FILTLAN  1.0a
polyfilt.h
Go to the documentation of this file.
1 #ifndef POLYFILT_H
2 #define POLYFILT_H
3 
7 #include "matkitdef.h"
8 
9 #ifdef USE_NAMESPACE
10 using namespace MATKIT;
11 namespace MATKIT {
12 #endif
13 
14 class Vector;
15 class Matrix;
16 class SymmetricMatrix;
17 class SparseMatrix;
18 
19 #ifdef USE_NAMESPACE
20 } // end of namespace MATKIT
21 #endif
22 
23 
25 // Newton - Hermite Polynomial Interpolation
27 
32 
49 // build P(z) by Newton's divided differences in the form
50 // P(z) = a(1) + a(2)*(z-x(1)) + a(3)*(z-x(1))*(z-x(2)) + ... + a(n)*(z-x(1))*...*(z-x(n-1)),
51 // such that P(x(i)) = y(i) for i=1,...,n, where
52 // x,y are input vectors of length n, and a is the output vector of length n
53 // if x(i)==x(j) for some i!=j, then it is assumed that the derivative of P(z) is to be zero at x(i),
54 // and the Hermite polynomial interpolation is applied
55 // in general, if there are k x(i)'s with the same value x0, then
56 // the j-th order derivative of P(z) is zero at z=x0 for j=1,...,k-1
57 Vector NewtonPolynomial(const Vector &x, const Vector &y);
58 
60 
69 // return the evaluated P(z0), i.e. the value of P(z) at z=z0, where P(z) is a Newton polynomial defined by
70 // P(z) = a(1) + a(2)*(z-x(1)) + a(3)*(z-x(1))*(z-x(2)) + ... + a(n)*(z-x(1))*...*(z-x(n-1))
71 // this routine also works for evluating the function value of a Hermite interpolating polynomial,
72 // which is in the same form as a Newton polynomial
73 Real NewtonPolynomialEvaluation(const Vector &a, const Vector &x, const Real z0);
74  // end of group_poly_intp
76 
77 
78 
80 // Base Filter
82 
86 // begin of group_base_filter
88 
120 // compute a base filter P(z) which is a continuous, piecewise polynomial P(z) expanded
121 // in a basis of `translated' (i.e. scale-and-shift) Chebyshev polynomials in each interval
122 //
123 // The base filter P(z) equals P_j(z) for z in the j-th interval [intv(j), intv(j+1)), where
124 // P_j(z) a Hermite interpolating polynomial
125 //
126 // input:
127 // intv is a vector which defines the intervals; the j-th interval is [intv(j), intv(j+1))
128 // HiLowFlags determines the shape of the base filter P(z)
129 // Consider the j-th interval [intv(j), intv(j+1)]
130 // HighLowFlag[j-1]==1, P(z)==1 for z in [intv(j), intv(j+1)]
131 // ==0, P(z)==0 for z in [intv(j), intv(j+1)]
132 // ==-1, [intv(j), intv(j+1)] is a transition interval;
133 // P(intv(j)) and P(intv(j+1)) are defined such that P(z) is continuous
134 // baseDeg is the degree of smoothness of the Hermite (piecewise polynomial) interpolation
135 // to be precise, the i-th derivative of P(z) is zero, i.e. d^{i}P(z)/dz^i==0, at all interval end points z=intv(j) for i=1,...,baseDeg
136 //
137 // output:
138 // P(z) expanded in a basis of `translated' (scale-and-shift) Chebyshev polynomials
139 // to be preicse, for z in the j-th interval [intv(j),intv(j+1)), P(z) equals
140 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(n,j)*S_{n-1}(z),
141 // where S_i(z) is the `translated' Chebyshev polynomial in that interval,
142 // S_i((z-c)/h) = T_i(z), c = (intv(j)+intv(j+1))) / 2, h = (intv(j+1)-intv(j)) / 2,
143 // with T_i(z) the Chebyshev polynomial of the first kind,
144 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
145 // the return matrix is the matrix of Chebyshev coefficients pp just described
146 //
147 // note that the degree of P(z) in each interval is (at most) 2*baseDeg+1, with 2*baseDeg+2 coefficients
148 // let n be the length of intv; then there are n-1 intervals
149 // therefore the return matrix pp is of size (2*baseDeg+2)-by-(n-1)
150 Matrix HermiteBaseFilterInChebyshevBasis(const Vector &intv, const int *HiLowFlags, mkIndex baseDeg);
151 
153 // an instance of this class, taken by GetIntervals() and PolynomialFilterInterface::setFilter(), is a collection of options to determine the intervals which decides the base filter
154 // it is used as an input argument of GetIntervals(), and also
157 
162  // interval weights, default 100,1,1,1,100
164 
165  // the following parameter is for high-pass filters (and low-pass filters with conversion) only
167  // the (relative) length of transition interval (default 0.6)
169 
170  // the following parameters are for mid-pass filters only
172  // this parameter tells whether to reverse the interval or not; it is effective only for mid-pass filters (default false)
175  // initial length of `plateau' relative to the length of the interval of desired eigenvalues (default 0.1)
178  // the rate at which the plateau shrinks at each iteration (default 1.5)
181  // initial shift step, relative to the length of the interval of desired eigenvalues (default 0.01)
184  // the rate at which the shift step expands (default 1.5)
187  // maximum number of inner iterations (default 30)
188  mkIndex maxInnerIter;
190  // a mid-pass filter P(x) should have P(a1)=P(b1), where [a1,b1] is the interval of desired eigenvalues
191  // yLimitTol (default 0.0001) is the tolerance allowed for |P(a1)-P(b1)|
192  Real yLimitTol;
193 
194  // the following parameters are for all filters
196  // maximum number of outer iterations, default 50
197  mkIndex maxOuterIter;
199 
201  // number of grid points, used to measure the maximum function value of the polynomial P(z) for z not in the interval which the eigenvalues are sought (default 200)
202  // the value of numGridPoints will automatically be increased if it is too small
203  mkIndex numGridPoints;
205  // this is the bottom line (default 0.001) which the function value of the polynomial must be greater than for z is in the interval of desired eigenvalues
208  // the limit of height of ripples (not in the interval of desired eigenvalues) relative to the bottom of polynomial values for z in the interval of desired eigenvalues (default 0.8)
210 
212  // a default constructor to set default parameters
214  // set default interval weights
215  intervalWeights.resize(5);
216  intervalWeights(1) = 100.0;
217  intervalWeights(2) = 1.0;
218  intervalWeights(3) = 1.0;
219  intervalWeights(4) = 1.0;
220  intervalWeights(5) = 100.0;
221 
222  // for high-pass filters (and low-pass filters with conversion)
223  transitionIntervalRatio = 0.6;
224 
225  // for mid-pass filters
226  reverseInterval = false;
227  initialPlateau = 0.1;
228  plateauShrinkRate = 1.5;
229  initialShiftStep = 0.01;
230  shiftStepExpansionRate = 1.5;
231  maxOuterIter = 50;
232  yLimitTol = 0.0001;
233 
234  // for all filters
235  maxInnerIter = 30;
236  numGridPoints = 200;
237  yBottomLine = 0.001;
238  yRippleLimit = 0.8;
239  }
240 };
241 
243 // the routine GetIntervals() returns an instance of this class, which gives the information of a polynomial filter
245  // the following returned values are for all filters
247  // The partition of the range of spectrum which decides the base filter and the polynomial filter.
248  Vector intervals;
250  // 1 means a high-pass filter (or low-pass filter with conversion); 2 means a mid-pass filter
253  // 0 means no acceptable is found; 1 means an OK filter is found; 2 means an optimal filter is found
254  int filterOK;
256  // between 0.0 and 1.0; the higher the better quality of the filter
259  // number of iterations to get the (transition) intervals
260  mkIndex numIter;
262 
264  // total number of iterations performed; this may include a few extra iterations without improving the (transition) intervals, compared to numIter
265  mkIndex totalNumIter;
267  // the lowest polynomial value P(z) for z in the interval [a1,b1] of desired eigenvalues
268  Real yLimit;
270  // the height of (highest, if more than one) summit in the interval [a1,b1] of desired eigenvalues
271  Real ySummit;
273  // number of steps moving leftward
274  mkIndex numLeftSteps;
276  // the height of highest summit in the left-hand side of the interval of desired eigenvalues
279  // the height of lowest bottom in the left-hand side of the interval of desired eigenvalues
281 
282  // the following returned values are for high-pass filters (or low-pass filters after conversion)
284  // in general it is |p(a1)-p(b1)|, where [a1,b1] is the interval of desired eigenvalues
285  Real yLimitGap;
287  // number of steps moving rightward
288  mkIndex numRightSteps;
290  // the height of highest summit in the right-hand side of the interval of desired eigenvalues
293  // the height of lowest bottom in the right-hand side of the interval of desired eigenvalues
295 
297  // a default constructor to initialize all zero
299  // zero initialization
300  filterOK = 0;
301  filterQualityIndex = 0.0;
302 
303  numIter = 0;
304  totalNumIter = 0;
305  yLimit = 0.0;
306  yLimitGap = 0.0;
307  ySummit = 0.0;
308 
309  numLeftSteps = 0;
310  yLeftSummit = 0.0;
311  yLeftBottom = 0.0;
312 
313  numRightSteps = 0;
314  yRightSummit = 0.0;
315  yRightBottom = 0.0;
316  }
317 };
318 
320 
344 // this routine determines the intervals (including the transition one(s)) by an interative process
345 //
346 // frame is a vector consisting of 4 ordered elements:
347 // [frame(1),frame(4)] is the interval which (tightly) contains all eigenvalues, and
348 // [frame(2),frame(3)] is the interval in which the eigenvalues are sought
349 // baseDeg is the left-and-right degree of the base filter for each interval
350 // polyDeg is the (maximum possible) degree of s(z), with z*s(z) the polynomial filter
351 // intv is the output; the j-th interval is [intv(j),intv(j+1))
352 // opts is a collection of interval options
353 //
354 // the base filter P(z) is a piecewise polynomial from Hermite interpolation with degree baseDeg at each end point of intervals
355 //
356 // the polynomial filter Q(z) is in the form z*s(z), i.e. Q(0)==0, such that ||(1-P(z))-z*s(z)||_w is minimized with
357 // s(z) a polynomial of degree up to polyDeg
358 //
359 // the resulting polynomial filter Q(z) satisfies Q(x)>=Q(y) for x in [frame(2),frame(3)], and
360 // y in [frame(1),frame(4)] but not in [frame(2),frame(3)]
361 //
362 // the routine returns an instance of PolynomialFilterInfo which gives some information of the polynomial filter
363 PolynomialFilterInfo GetIntervals(Vector &intv, const Vector &frame, mkIndex polyDeg, mkIndex baseDeg, IntervalOptions &opts);
364 
366 // same as GetIntervals() above, with default IntervalOptions
367 PolynomialFilterInfo GetIntervals(Vector &intervals, const Vector &frame, mkIndex polyDeg, mkIndex baseDeg); // default interval options will be used
368 
370 // end of group_base_filter
371 
372 
373 
375 // Chebyshev Polynomials
377 
383 
394 // translate the coefficients of a Newton polynomial to the coefficients
395 // in a basis of the `translated' Chebyshev polynomials
396 //
397 // input:
398 // a Newton polynomial defined by vectors a and x:
399 // P(z) = a(1) + a(2)*(z-x(1)) + a(3)*(z-x(1))*(z-x(2)) + ... + a(n)*(z-x(1))*...*(z-x(n-1))
400 // the interval [aa,bb] defines the `translated' Chebyshev polynomials S_i(z) = T_i((z-c)/h),
401 // where c=(aa+bb)/2 and h=(bb-aa)/2, and T_i is the Chebyshev polynomial of the first kind
402 // note that T_i is defined by T_0(z)=1, T_1(z)=z, and T_i(z)=2*z*T_{i-1}(z)+T_{i-2}(z) for i>=2
403 //
404 // output:
405 // a vector q containing the Chebyshev coefficients, such that
406 // P(z) = q(1)*S_0(z) + q(2)*S_1(z) + ... + q(n)*S_{n-1}(z)
407 Vector ExpandNewtonPolynomialInChebyshevBasis(Real aa, Real bb, const Vector &a, const Vector &x);
408 
410 
424 // evaluate P(z) at z=z0, where P(z) is a polynomial expanded in a basis of
425 // the `translated' (i.e. scale-and-shift) Chebyshev polynomials
426 //
427 // input:
428 // c is a vector of Chebyshev coefficients which defines the polynomial
429 // P(z) = c(1)*S_0(z) + c(2)*S_1(z) + ... + c(n)*S_{n-1}(z),
430 // where S_i is the `translated' Chebyshev polynomial S_i((z-c)/h) = T_i(z), with
431 // c = (intv(j)+intv(j+1)) / 2, h = (intv(j+1)-intv(j)) / 2
432 // note that T_i(z) is the Chebyshev polynomial of the first kind,
433 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
434 //
435 // output:
436 // the evaluated value of P(z) at z=z0
437 Real PolynomialEvaluationInChebyshevBasis(const Vector &c, Real z0, Real aa=-1.0, Real bb=1.0);
438 
440 
462 // evaluate P(z) at z=z0, where P(z) is a piecewise polynomial expanded
463 // in a basis of the (optionally translated, i.e. scale-and-shift) Chebyshev polynomials for each interval
464 //
465 // input:
466 // intv is a vector which defines the intervals; the j-th interval is [intv(j), intv(j+1))
467 // pp is a matrix of Chebyshev coefficients which defines a piecewise polynomial P(z)
468 // in a basis of the `translated' Chebyshev polynomials in each interval
469 // the polynomial P_j(z) in the j-th interval, i.e. when z is in [intv(j), intv(j+1)), is defined by the j-th column of pp:
470 // if basisTranslated == false, then
471 // P_j(z) = pp(1,j)*T_0(z) + pp(2,j)*T_1(z) + ... + pp(n,j)*T_{n-1}(z),
472 // where T_i(z) is the Chebyshev polynomial of the first kind,
473 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
474 // if basisTranslated == true, then
475 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(n,j)*S_{n-1}(z),
476 // where S_i is the `translated' Chebyshev polynomial S_i((z-c)/h) = T_i(z), with
477 // c = (intv(j)+intv(j+1)) / 2, h = (intv(j+1)-intv(j)) / 2
478 //
479 // output:
480 // the evaluated value of P(z) at z=z0
481 //
482 // note that if z0 falls below the first interval, then the polynomial in the first interval will be used for evaluting P(z0)
483 // if z0 flies over the last interval, then the polynomial in the last interval will be used for evaluting P(z0)
484 Real PiecewisePolynomialEvaluationInChebyshevBasis(const Matrix &pp, const Vector &intv, Real z0, bool basisTranslated=true);
485 
487 
510 // compute the weighted inner product of two piecewise polynomials expanded
511 // in a basis of `translated' (i.e. scale-and-shift) Chebyshev polynomials for each interval
512 //
513 // pp and qq are two matrices of Chebyshev coefficients which define the piecewise polynomials P(z) and Q(z), respectively
514 // For z in the j-th interval, P(z) equals
515 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(n,j)*S_{n-1}(z),
516 // and Q(z) equals
517 // Q_j(z) = qq(1,j)*S_0(z) + qq(2,j)*S_1(z) + ... + qq(n,j)*S_{n-1}(z),
518 // where S_i(z) is the `translated' Chebyshev polynomial in that interval,
519 // S_i((z-c)/h) = T_i(z), c = (aa+bb)) / 2, h = (bb-aa) / 2,
520 // with T_i(z) the Chebyshev polynomial of the first kind,
521 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
522 //
523 // the (scaled) j-th interval inner product is defined by
524 // <P_j,Q_j> = (Pi/2)*( pp(1,j)*qq(1,j) + sum_{k} pp(k,j)*qq(k,j) ),
525 // which comes from the property
526 // <T_0,T_0>=pi, <T_i,T_i>=pi/2 for i>=1, and <T_i,T_j>=0 for i!=j
527 //
528 // the weighted inner product is <P,Q> = sum_{j} intervalWeights(j)*<P_j,Q_j>,
529 // which is the return value
530 //
531 // note that for unit weights, pass an empty vector of intervalWeights (i.e. of length 0)
532 Real PiecewisePolynomialInnerProductInChebyshevBasis(const Matrix &pp, const Matrix &qq, const Vector &intervalWeights);
533 
535 
552 // compute Q(z) = z*P(z), where P(z) and Q(z) are piecewise polynomials expanded
553 // in a basis of `translated' (i.e. scale-and-shift) Chebyshev polynomials for each interval
554 //
555 // P(z) and Q(z) are stored as matrices of Chebyshev coefficients pp and qq, respectively
556 //
557 // for z in the j-th interval, P(z) equals
558 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(n,j)*S_{n-1}(z),
559 // and Q(z) equals
560 // Q_j(z) = qq(1,j)*S_0(z) + qq(2,j)*S_1(z) + ... + qq(n,j)*S_{n-1}(z),
561 // where S_i(z) is the `translated' Chebyshev polynomial in that interval,
562 // S_i((z-c)/h) = T_i(z), c = (intv(j)+intv(j+1))) / 2, h = (intv(j+1)-intv(j)) / 2,
563 // with T_i(z) the Chebyshev polynomial of the first kind,
564 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
565 //
566 // the returned matrix is qq which represents Q(z) = z*P(z)
567 Matrix PiecewisePolynomialInChebyshevBasisMultiplyX(const Matrix &pp, const Vector &intv);
568  // end of group_chebyshev
570 
571 
572 
574 // Conjugate Residual Method in the Polynomial Space
576 
581 
614 // this routine employs a conjugate-residual-type algorithm in polynomial space to minimize ||P(z)-Q(z)||_w,
615 // where P(z), the base filter, is the input piecewise polynomial, and
616 // Q(z) is the output polynomial satisfying Q(0)==1, i.e. the constant term of Q(z) is 1
617 // niter is the number of conjugate-residual iterations; therefore, the degree of Q(z) is up to niter+1
618 // both P(z) and Q(z) are expanded in the `translated' (scale-and-shift) Chebyshev basis for each interval,
619 // and presented as matrices of Chebyshev coefficients, denoted by pp and qq, respectively
620 //
621 // input:
622 // intv is a vector which defines the intervals; the j-th interval is [intv(j),intv(j+1))
623 // w is a vector of Chebyshev weights; the weight of j-th interval is w(j)
624 // the interval weights define the inner product of two continuous functions and then
625 // the derived w-norm ||P(z)-Q(z)||_w
626 // pp is a matrix of Chebyshev coefficients which defines the piecewise polynomial P(z)
627 // to be specific, for z in [intv(j), intv(j+1)), P(z) equals
628 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(niter+2,j)*S_{niter+1}(z),
629 // where S_i(z) is the `translated' Chebyshev polynomial in that interval,
630 // S_i((z-c)/h) = T_i(z), c = (intv(j)+intv(j+1))) / 2, h = (intv(j+1)-intv(j)) / 2,
631 // with T_i(z) the Chebyshev polynomial of the first kind,
632 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
633 //
634 // output:
635 // the return matrix, denoted by qq, represents a polynomial Q(z) with degree up to 1+niter
636 // and satisfying Q(0)==1, such that ||P(z))-Q(z)||_w is minimized
637 // this polynomial Q(z) is expanded in the `translated' Chebyshev basis for each interval
638 // to be precise, considering z in [intv(j), intv(j+1)), Q(z) equals
639 // Q_j(z) = qq(1,j)*S_0(z) + qq(2,j)*S_1(z) + ... + qq(niter+2,j)*S_{niter+1}(z)
640 //
641 // note:
642 // 1. since Q(0)==1, P(0)==1 is expected; if P(0)!=1, one can translate P(z)
643 // for example, if P(0)==0, one can use 1-P(z) as input instead of P(z)
644 // 2. typically, the base filter, defined by pp and intv, is from Hermite interpolation
645 // in intervals [intv(j),intv(j+1)) for j=1,...,nintv, with nintv the number of intervals
646 Matrix FilteredConjugateResidualPolynomial(const Matrix &pp, const Vector &intv,
647  const Vector &w, mkIndex niter);
648 
650 
696 // this routine employs a conjugate-residual-type algorithm in polynomial space to compute
697 // x = x0 + s(A)*r0 with r0 = b - A*x0, such that ||(1-P(z))-z*s(z)||_w is minimized, where
698 // P(z) is a given piecewise polynomial, called the base filter,
699 // s(z) is a polynomial of degree up to niter, the number of conjugate-residual iterations,
700 // and b and x0 are given vectors
701 //
702 // note that P(z) is expanded in the `translated' (scale-and-shift) Chebyshev basis for each interval,
703 // and presented as a matrix of Chebyshev coefficients pp
704 //
705 // input:
706 // A is a sparse matrix
707 // x0, b are vectors
708 // niter is the number of conjugate-residual iterations
709 // intv is a vector which defines the intervals; the j-th interval is [intv(j),intv(j+1))
710 // w is a vector of Chebyshev weights; the weight of j-th interval is w(j)
711 // the interval weights define the inner product of two continuous functions and then
712 // the derived w-norm ||P(z)-Q(z)||_w
713 // pp is a matrix of Chebyshev coefficients which defines the piecewise polynomial P(z)
714 // to be specific, for z in [intv(j), intv(j+1)), P(z) equals
715 // P_j(z) = pp(1,j)*S_0(z) + pp(2,j)*S_1(z) + ... + pp(niter+2,j)*S_{niter+1}(z),
716 // where S_i(z) is the `translated' Chebyshev polynomial in that interval,
717 // S_i((z-c)/h) = T_i(z), c = (intv(j)+intv(j+1))) / 2, h = (intv(j+1)-intv(j)) / 2,
718 // with T_i(z) the Chebyshev polynomial of the first kind,
719 // T_0(z) = 1, T_1(z) = z, and T_i(z) = 2*z*T_{i-1}(z) - T_{i-2}(z) for i>=2
720 // tol is the tolerance; if the residual polynomial in z-norm is dropped by a factor lower
721 // than tol, then stop the conjugate-residual iteration
722 //
723 // output:
724 // the return vector is x = x0 + s(A)*r0 with r0 = b - A*x0, such that ||(1-P(z))-z*s(z)||_w is minimized,
725 // subject to that s(z) is a polynomial of degree up to niter, where P(z) is the base filter
726 // in short, z*s(z) approximates 1-P(z)
727 //
728 // note:
729 // 1. since z*s(z) approximates 1-P(z), P(0)==1 is expected; if P(0)!=1, one can translate P(z)
730 // for example, if P(0)==0, one can use 1-P(z) as input instead of P(z)
731 // 2. typically, the base filter, defined by pp and intv, is from Hermite interpolation
732 // in intervals [intv(j),intv(j+1)) for j=1,...,nintv, with nintv the number of intervals
733 // 3. a common application is to compute R(A)*b, where R(z) approximates 1-P(z)
734 // in this case, one can set x0 = 0 and then the return vector is x = s(A)*b, where
735 // z*s(z) approximates 1-P(z); therefore, A*x is the wanted R(A)*b
736 // see also PolynomialFilterInterface::filteredSparseMatrixPolynomialVectorProduct()
737 Vector FilteredConjugateResidualMatrixPolynomialVectorProduct(const SparseMatrix &A, const Vector &x0, const Vector &b,
738  const Matrix &pp, const Vector &intv, const Vector &w,
739  mkIndex niter, Real tol=0.0);
740 
742 
751 // an interface to define R(S), i.e. set R and S, and compute R(S)*v, where
752 // S is a sparse symmetric matrix,
753 // R(z) is a polynomial which approximates a piecewise polynomial 1-P(z), with P(z) the base filter, and
754 // v is the input vector
755 //
756 // in short, use setFilter() to define R(S) once, and
757 // use filteredSparseMatrixPolynomialVectorProduct() to compute R(S)*v for every v
759 private:
760  // works for SparseMatrix only
762  // a pointer to the input sparse symmetric matrix via setFilter()
763  static const SparseMatrix *Sptr;
765  // the sparse symmetric matrix S in computing R(S)*v; S is translated from the input sparse symmetric matrix S0 in setFilter()
766  static SparseMatrix S;
767 
768  // parameters for polynomial filtering
770 
779  // the j-th interval is [intervals(j),intervals(j+1))
780  // the intervals are decided by GetIntervals() invoked by setFilter() which takes parameters frame, baseDeg, and polyDeg:
781  // 1. frame is a vector consisting of 4 ordered elements:
782  // [frame(1),frame(4)] is the interval which (tightly) contains all eigenvalues of S, and
783  // [frame(2),frame(3)] is the interval in which the eigenvalues are sought
784  // 2. baseDeg is the left-and-right degree of the base filter for each interval
785  // 3. polyDeg is the (maximum possible) degree of z*s(z), with s(z) the polynomial filter
786  static Vector intervals;
788  // intervalWeights(j) is the weight of j-th interval [intervals(j), intervals(j+1))
789  static Vector intervalWeights;
791  // maximum possible degree of s(z), with z*s(z) the polynomial filter
792  static mkIndex polyDegree;
794  // left-and-right degree of the base filter in each interval
795  static mkIndex baseDegree;
797 
800  // a base filter, which is a piecewise polynomial typically from Hermite interpolation
801  // for j-th interval, the polynomial is expanded in the `translated' (scale-and-shift) Chebyshev basis,
802  // with the Chebyshev coefficients stored in baseFilter(:,j)
803  static Matrix baseFilter;
805  // a zero vector of length the number of rows/columns of S
806  static Vector zn;
807 
808 public:
810  // the information of computing the polynomial filter; see class PolynomialFilterInfo in polyfilt.h for more information
812 
813  // routines for the polynomial filtered Lanczos eigensolver
815 
825  // this member function sets the sparse matrix S translated from S0, and also the base filter P(z)
826  // S0 is the sparse symmetric matrix of concern
827  // frame is a vector of 4 ordered elements
828  // [frame(1),frame(4)] is the interval which (tightly) contains all eigenvalues of S0, and
829  // [frame(2),frame(3)] is the interval in which the eigenvalues of S0 are sought
830  // polyDeg is the (maximum possible) degree of s(z), with z*s(z) the polynomial filter
831  // baseDeg is the left-and-right degree of the base filter for each interval
832  // opts is a collection of options to determine the intervals
833  static Vector setFilter(const SparseMatrix &S0, const Vector &frame, mkIndex polyDeg, mkIndex baseDeg, IntervalOptions &opts);
835 
843  // this routine computes R(S)*v, where it is assumed that S and R(z) have been defined by setFilter()
844  // R(z) is in the form z*s(z) which minimizes ||(1-P(z))-z*s(z)||_w by a conjugate-residual-type algorithm,
845  // where P(z) is a piecewise polynomial as the base filter, and s(z) is a polynomial of degree up to polyDegree,
846  // and w-norm is defined by data members intervals and intervalWeights
847  //
848  // note that P(z) is defined by the data members baseFilter and intervals
849  // it is expanded in the `translated' (scale-and-shift) Chebyshev basis for each interval,
850  // and presented as a matrix of Chebyshev coefficients baseFilter
851  //
852  // see also FilteredConjugateResidualMatrixPolynomialVectorProduct()
853  static Vector filteredSparseMatrixPolynomialVectorProduct(const Vector &v) {
854  return (*Sptr)*FilteredConjugateResidualMatrixPolynomialVectorProduct(*Sptr, zn, v, baseFilter, intervals, intervalWeights, polyDegree);
855  }
856 };
857  // end of group_cr_poly
859 
860 
861 #endif
Real filterQualityIndex
Between 0.0 and 1.0; the higher the better quality of the filter.
Definition: polyfilt.h:257
mkIndex numIter
Number of iterations to get the (transition) intervals.
Definition: polyfilt.h:260
Vector NewtonPolynomial(const Vector &x, const Vector &y)
Build a polynomial P(z) by Newton&#39;s divided differences and return the coefficient vector a...
static Vector intervals
The jth interval is [intervals(j),intervals(j+1)).
Definition: polyfilt.h:786
int filterOK
0 means no acceptable is found; 1 means an OK filter is found; 2 means an optimal filter is found...
Definition: polyfilt.h:254
mkIndex numGridPoints
Number of grid points, used to measure the maximum function value of the polynomial P(z) for z not in...
Definition: polyfilt.h:203
Real yLimit
The lowest polynomial value P(z) for z in the interval [a1,b1] of desired eigenvalues.
Definition: polyfilt.h:268
Matrix FilteredConjugateResidualPolynomial(const Matrix &pp, const Vector &intv, const Vector &w, mkIndex niter)
This routine employs a conjugate-residual-type algorithm in polynomial space to minimize ||P(z)-Q(z)|...
PolynomialFilterInfo()
A default constructor to initialze all zero.
Definition: polyfilt.h:298
static SparseMatrix S
The sparse symmetric matrix S in computing R(S)*v; S is translated from the input sparse symmetric ma...
Definition: polyfilt.h:766
mkIndex maxInnerIter
Maximum number of inner iterations (default 30), effective only for mid-pass filters.
Definition: polyfilt.h:188
Real PolynomialEvaluationInChebyshevBasis(const Vector &c, Real z0, Real aa=-1.0, Real bb=1.0)
Evaluate P(z) at z=z0, where P(z) is a polynomial expanded in a basis of the ‘translated’ (i...
Real yLeftSummit
The height of highest summit in the left-hand side of the interval of desired eigenvalues.
Definition: polyfilt.h:277
Real yRightBottom
The height of lowest bottom in the right-hand side of the interval of desired eigenvalues.
Definition: polyfilt.h:294
Real yBottomLine
This is the bottom line (default 0.001) which the function value of the polynomial must be greater th...
Definition: polyfilt.h:206
Real ySummit
The height of (highest, if more than one) summit in the interval [a1,b1] of desired eigenvalues...
Definition: polyfilt.h:271
Real yRightSummit
The height of highest summit in the right-hand side of the interval of desired eigenvalues.
Definition: polyfilt.h:291
mkIndex maxOuterIter
Maximum number of outer iterations (default 50).
Definition: polyfilt.h:197
int filterType
1 means a high-pass filter (or low-pass filter with conversion); 2 means a mid-pass filter...
Definition: polyfilt.h:251
static Vector filteredSparseMatrixPolynomialVectorProduct(const Vector &v)
This routine computes R(S)*v, where it is assumed that S and R(S) have been defined by setFilter()...
Definition: polyfilt.h:853
static Vector zn
A zero vector of length the number of rows/columns of S.
Definition: polyfilt.h:806
Real yLimitTol
A mid-pass filter P(x) should have P(a1)=P(b1), where [a1,b1] is the interval of desired eigenvalues;...
Definition: polyfilt.h:192
static PolynomialFilterInfo filterInfo
The information of computing the polynomial filter. See class PolynomialFilterInfo in polyfilt...
Definition: polyfilt.h:811
Vector intervals
The partition of the range of spectrum which decides the base filter and the polynomial filter...
Definition: polyfilt.h:248
Matrix PiecewisePolynomialInChebyshevBasisMultiplyX(const Matrix &pp, const Vector &intv)
compute Q(z) = z*P(z), where P(z) and Q(z) are piecewise polynomials expanded in a basis of ‘transla...
IntervalOptions()
A default constructor to set default parameters.
Definition: polyfilt.h:213
Real yRippleLimit
The limit of height of ripples (not in the interval of desired eigenvalues) relative to the bottom of...
Definition: polyfilt.h:209
PolynomialFilterInfo GetIntervals(Vector &intv, const Vector &frame, mkIndex polyDeg, mkIndex baseDeg, IntervalOptions &opts)
This routine determines the intervals (including the transition one(s)) by an interative process...
Vector ExpandNewtonPolynomialInChebyshevBasis(Real aa, Real bb, const Vector &a, const Vector &x)
Translate the coefficients of a Newton polynomial to the coefficients in a basis of the ‘translatedâ€...
Real initialShiftStep
Initial shift step, relative to the length of the interval of desired eigenvalues (default 0...
Definition: polyfilt.h:182
static Vector intervalWeights
intervalWeights(j) is the weight of jth interval [intervals(j),intervals(j+1)).
Definition: polyfilt.h:789
Real yLimitGap
In general, it is |p(a1)-p(b1)|, where [a1,b1] is the interval of desired eigenvalues.
Definition: polyfilt.h:285
Real yLeftBottom
The height of lowest bottom in the left-hand side of the interval of desired eigenvalues.
Definition: polyfilt.h:280
mkIndex numLeftSteps
Number of steps moving leftward.
Definition: polyfilt.h:274
Real plateauShrinkRate
The rate at which the plateau shrinks at each iteration (default 1.5), effective only for mid-pass fi...
Definition: polyfilt.h:179
static mkIndex polyDegree
Maximum possible degree of s(z), with z*s(z) the polynomial filter.
Definition: polyfilt.h:792
static Matrix baseFilter
A base filter, which is a piecewise polynomial typically from Hermite interpolation.
Definition: polyfilt.h:803
An interface to define R(S), i.e. set R and S, and compute R(S)*v, where R is the residual polynomial...
Definition: polyfilt.h:758
bool reverseInterval
This parameter tells whether to reverse the interval or not. It is effective only for mid-pass filter...
Definition: polyfilt.h:173
The routine GetIntervals() returns an instance of this class, which gives the information of a polyno...
Definition: polyfilt.h:244
Real PiecewisePolynomialInnerProductInChebyshevBasis(const Matrix &pp, const Matrix &qq, const Vector &intervalWeights)
Compute the weighted inner product of two piecewise polynomials expanded in a basis of ‘translated’...
Real initialPlateau
Initial length of ‘plateau’, relative to the length of the interval of desired eigenvalues (default...
Definition: polyfilt.h:176
Real transitionIntervalRatio
The (relative) length of transition interval (default 0.6), effective only for high-pass filters...
Definition: polyfilt.h:168
mkIndex totalNumIter
Total number of iterations performed.
Definition: polyfilt.h:265
Vector intervalWeights
Interval weights (default 100,1,1,1,100).
Definition: polyfilt.h:163
static const SparseMatrix * Sptr
A pointer to the input sparse symmetric matrix via setFilter().
Definition: polyfilt.h:763
An instance of this class, taken by GetIntervals() and PolynomialFilterInterface::setFilter(), is a collection of options to determine the intervals which decides the base filter.
Definition: polyfilt.h:155
Real PiecewisePolynomialEvaluationInChebyshevBasis(const Matrix &pp, const Vector &intv, Real z0, bool basisTranslated=true)
Evaluate P(z) at z=z0, where P(z) is a piecewise polynomial expanded in a basis of the (optionally tr...
Real NewtonPolynomialEvaluation(const Vector &a, const Vector &x, const Real z0)
Evaluate P(z0), i.e. the value of P(z) at z=z0, where P(z) is a Newton polynomial defined by a and x...
static mkIndex baseDegree
Left-and-right degree of the base filter in each interval.
Definition: polyfilt.h:795
Real shiftStepExpansionRate
The rate at which the shift step expands (default 1.5), effective only for mid-pass filters...
Definition: polyfilt.h:185
Matrix HermiteBaseFilterInChebyshevBasis(const Vector &intv, const int *HiLowFlags, mkIndex baseDeg)
Compute a base filter P(z) which is a continuous, piecewise polynomial P(z) expanded in a basis of ‘...
Vector FilteredConjugateResidualMatrixPolynomialVectorProduct(const SparseMatrix &A, const Vector &x0, const Vector &b, const Matrix &pp, const Vector &intv, const Vector &w, mkIndex niter, Real tol=0.0)
This routine employs a conjugate-residual-type algorithm in polynomial space to compute x=x0+s(A)*r0 ...
mkIndex numRightSteps
Number of steps moving rightward.
Definition: polyfilt.h:288