9 #include <vapor/EasyThreads.h>
10 #include <vapor/MyBase.h>
12 #pragma warning(disable : 4996)
68 static const double Flt_Epsilon;
69 static const double TINY;
73 unsigned int ntilde_c;
74 unsigned int max_width_c;
78 double *fwd_lifting_c;
79 double *inv_lifting_c;
82 int zero(
const double x );
84 double neville (
const double *x,
const double *f,
const int n,
const double xx);
87 double** moment,
const double *filter,
const int step2,
88 const int noGammas,
const int len,
const int n,
const int ntilde
91 double** matrix(
long nrl,
long nrh,
long ncl,
long nch);
94 double **m,
long nrl,
long nrh,
long ncl,
long nch
97 void LUdcmp(
double **a,
int n,
int *indx,
double *d);
98 void LUbksb (
double **a,
int n,
int *indx,
double *b);
101 double *lifting,
const double** moment,
const int len,
102 const int step2,
const int noGammas,
const int ntilde
105 double *create_fwd_filter (
unsigned int);
106 double *create_inv_filter (
unsigned int,
const double *);
107 double **create_moment(
108 const unsigned int,
const unsigned int,
const int
111 double *create_inv_lifting(
double *,
unsigned int,
unsigned int);
113 double *create_fwd_lifting(
114 const double *filter,
const unsigned int n,
115 const unsigned int ntilde,
const unsigned int width
118 void FLWT1D_Predict(Data_T*,
const long,
const long,
double *,
int stride);
119 void FLWT1D_Update(Data_T *,
const long,
const long,
const double*,
int stride);
121 void forward_transform1d_haar(Data_T *data,
int width,
int stride);
123 void inverse_transform1d_haar(Data_T *data,
int width,
int stride);
159 using namespace VAPoR;
163 #define MAX(A,B) ((A)>(B)?(A):(B))
181 fwd_lifting_c = NULL;
183 inv_lifting_c = NULL;
186 SetClassName(
"Lifting1D");
197 _nfactor = sqrt(pow(2.0, (
double) j));
202 if (n_c == 1 && ntilde_c == 1) {
210 "Invalid # lifting coeffs., n=%d, is odd",
216 if (n_c > MAX_FILTER_COEFF) {
218 "Invalid # of lifting coeffs., n=%d, exceeds max=%d",
219 n_c, MAX_FILTER_COEFF
223 if (ntilde_c > MAX_FILTER_COEFF) {
225 "Invalid # of lifting coeffs., ntilde=%d, exceeds max=%d",
226 ntilde_c, MAX_FILTER_COEFF
231 int maxN =
MAX(n_c, ntilde_c) - 1;
232 int maxl = (width_c == 1) ? 0 : (
int)
LogBaseN ((
double)(width_c-1)/maxN, (
double) 2.0);
236 "Invalid # of samples, width=%d, less than # moments",
244 if (! (fwd_filter_c = create_fwd_filter(n_c))) {
245 SetErrMsg(
"malloc() : %s", strerror(errno));
248 if (! (inv_filter_c = create_inv_filter(n_c, fwd_filter_c))) {
249 SetErrMsg(
"malloc() : %s", strerror(errno));
256 int Nrows = (n_c>>1) + 1;
257 filterPtr = filter_c;
258 fprintf (stdout,
"\nFilter Coefficients (N=%d)\n", n_c);
259 for (row = 0 ; row < Nrows ; row++) {
260 fprintf (stdout,
"For %d in the left and %d in the right\n[ ",
262 for (col = 0 ; col < n_c ; col++)
263 fprintf (stdout,
"%.18g ", *(filterPtr++));
264 fprintf (stdout,
"]\n");
270 fwd_lifting_c = create_fwd_lifting(fwd_filter_c,n_c,ntilde_c,width_c);
271 if (! fwd_lifting_c) {
272 SetErrMsg(
"malloc() : %s", strerror(errno));
276 inv_lifting_c = create_inv_lifting(fwd_lifting_c, ntilde_c, width_c);
277 if (! inv_lifting_c) {
278 SetErrMsg(
"malloc() : %s", strerror(errno));
288 if (! _objInitialized)
return;
290 if (fwd_filter_c)
delete [] fwd_filter_c;
293 if (inv_filter_c)
delete [] inv_filter_c;
296 if (fwd_lifting_c)
delete [] fwd_lifting_c;
297 fwd_lifting_c = NULL;
299 if (inv_lifting_c)
delete [] inv_lifting_c;
300 inv_lifting_c = NULL;
316 Data_T *data,
int stride
318 if (n_c == 1 && ntilde_c == 1) {
319 forward_transform1d_haar(data, width_c, stride);
322 FLWT1D_Predict (data, width_c, n_c, fwd_filter_c, stride);
323 FLWT1D_Update (data, width_c, ntilde_c, fwd_lifting_c, stride);
326 if (_nfactor != 1.0) {
328 for(
unsigned int i=1; i<width_c; i+=2) {
329 data[i*stride] /= _nfactor;
343 Data_T *data,
int stride
345 if (_nfactor != 1.0) {
347 for(
unsigned int i=1; i<width_c; i+=2) {
348 data[i*stride] *= _nfactor;
352 if (n_c == 1 && ntilde_c == 1) {
353 inverse_transform1d_haar(data, width_c, stride);
356 FLWT1D_Update (data, width_c, ntilde_c, inv_lifting_c, stride);
357 FLWT1D_Predict (data, width_c, n_c, inv_filter_c, stride);
364 const double __negeps_f = -100 * Flt_Epsilon;
365 const double __poseps_f = 100 * Flt_Epsilon;
367 return ( __negeps_f < x ) && ( x < __poseps_f );
384 const double *x,
const double *f,
const int n,
const double xx
387 double vy[MAX_FILTER_COEFF];
390 for ( i=0; i<n; i++ ) {
392 for ( j=i-1; j>=0; j--) {
393 double den = x[i] - x[j];
395 vy[j] = vy[j+1] + (vy[j+1] - vy[j]) * (xx - x[i]) / den;
409 const double *filter,
420 const double *filterPtr;
428 top3 = (n>>1) -
IsOdd(len);
429 top2 = noGammas - (top1 + top3);
434 for ( row = 1 ; row <= top1 ; row++ ) {
437 for ( col = 0 ; col < n ; col++ ) {
439 for ( j = 0 ; j < ntilde ; j++ ) {
440 moment[idxL][j] += filterPtr[col]*moment[idxG][j];
450 for ( i = 0 ; i < top2 ; i++ ) {
452 for ( col = 0 ; col < n ; col++ ) {
454 for ( j = 0 ; j < ntilde ; j++ ) {
455 moment[idxL][j] += filterPtr[col]*moment[idxG][j];
465 for ( row = top3 ; row >= 1 ; row-- ) {
466 idxL = (top2-1)*step2;
468 for ( col = n-1 ; col >= 0 ; col-- ) {
470 for ( j = 0 ; j < ntilde ; j++ ) {
471 moment[idxL][j] += filterPtr[col]*moment[idxG][j];
485 long nrl,
long nrh,
long ncl,
long nch
491 m =
new double* [nrh-nrl+1];
496 for ( i=nrl ; i<=nrh ; i++ ) {
497 m[i] =
new double[nch-ncl+1];
498 if (!m[i])
return NULL;
507 double **m,
long nrl,
long nrh,
long ncl,
long nch
511 for ( i=nrh ; i>=nrl ; i-- ) {
549 double **a,
int n,
int *indx,
double *d
552 double big, dum, sum, temp;
560 if ((temp=(
double)fabs((
double)a[i][j])) > big)
562 assert(big != (
double)0.0);
569 for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
577 sum -= a[i][k]*a[k][j];
579 if ( (dum=vv[i]*(
double)fabs((
double)sum)) >= big) {
595 if (a[j][j] == (
double)0.0)
596 a[j][j]=(double)TINY;
601 dum=(double)1/(a[j][j]);
602 for ( i=j+1 ; i<n ; i++ )
626 double **a,
int n,
int *indx,
double *b
636 for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
641 for (i=n-1;i>=0;i--) {
643 for (j=i+1;j<n;j++) sum -= a[i][j]*b[j];
645 if (zero(b[i])) b[i] = (double)0;
656 const double** moment,
679 indx =
new int[ntilde];
683 lift = matrix(0, (
long)ntilde-1, 0, (
long)ntilde-1);
684 b =
new double[ntilde];
687 top1 = (ntilde>>1) - 1;
688 top3 = (ntilde>>1) -
IsOdd(len);
689 top2 = noGammas - (top1 + top3);
693 for ( i=0 ; i<top1 ; i++ ) {
695 for (col=0 ; col<ntilde ; col++ ) {
697 for ( row=0 ; row<ntilde ; row++ ) {
698 lift[row][col] = moment[idxL][row];
704 LUdcmp (lift, ntilde, indx, &d);
706 for ( j=0 ; j<ntilde ; j++) {
707 b[j] = moment[idxG][j];
710 LUbksb (lift, ntilde, indx, b);
711 for (col=0; col<ntilde; col++) {
712 lifting[lcIdx++] = b[col];
719 for ( i=0 ; i<top2 ; i++ ) {
721 for ( col=0 ; col<ntilde ; col++ ) {
723 for ( row=0 ; row<ntilde ; row++ )
724 lift[row][col] = moment[idxL][row];
729 LUdcmp (lift, ntilde, indx, &d);
731 for ( j=0 ; j<ntilde ; j++)
732 b[j] = moment[idxG][j];
734 LUbksb (lift, ntilde, indx, b);
735 for ( col=0 ; col<ntilde ; col++ )
736 lifting[lcIdx++] = b[col];
742 for ( i=0 ; i<top3 ; i++ ) {
743 idxL = (top2-1)*step2;
744 for ( col=0 ; col<ntilde ; col++ ) {
746 for ( row=0 ; row<ntilde ; row++ )
747 lift[row][col] = moment[idxL][row];
752 LUdcmp (lift, ntilde, indx, &d);
754 for ( j=0 ; j<ntilde ; j++)
755 b[j] = moment[idxG][j];
757 LUbksb (lift, ntilde, indx, b);
758 for (col=0;col<ntilde;col++) {
759 lifting[lcIdx++] = b[col];
766 free_matrix(lift, 0, (
long)ntilde-1, 0, (
long)ntilde-1);
797 double xa[MAX_FILTER_COEFF], ya[MAX_FILTER_COEFF], x;
798 int row, col, cc, Nrows;
799 double *filter, *ptr;
806 filter =
new double[Nrows*n];
807 if (! filter)
return NULL;
811 xa[0] = (double)0.5*(
double)(1 - (int) n);
812 for (col = 1 ; col < (int)n ; col++) {
813 xa[col] = xa[col-1] + (double)1;
817 filter += ( (Nrows*n) - 1 );
818 for (row = 0 ; row < Nrows ; row++) {
820 for (col = 0 ; col < (int)n ; col++) {
821 for (cc = 0 ; cc < (int)n ; cc++)
824 *(filter--) = neville (xa, ya, n, x);
832 unsigned int n,
const double *filter
842 inv_filter =
new double[Nrows*n];
843 if (! inv_filter)
return NULL;
845 for ( i=0 ; i<(int)(n*(1+(n>>1))) ; i++ ) inv_filter[i] = -filter[i];
857 const unsigned int ntilde,
858 const unsigned int width,
866 moment = matrix( 0, (
long)(width-1), 0, (
long)(ntilde-1) );
872 for ( row=0 ; row<(int)width ; row++ )
873 for ( col=0 ; col<(int)ntilde ; col++ ) {
874 if ( row==0 && col==0 )
875 moment[row][col] = (double)1.0;
877 moment[row][col] = (double)pow( (
double)row, (double)col );
882 fprintf (stdout,
"Integral-Moments Coefficients for X (ntilde=%2d)\n", ntilde);
883 for ( row=0 ; row<(int)width ; row++ ) {
884 fprintf (stdout,
"Coeff[%d] (%.20g", row, moment[row][0]);
885 for ( col=1 ; col<(int)ntilde ; col++ )
886 fprintf (stdout,
",%.20g", moment[row][col]);
887 fprintf (stdout,
")\n");
894 #define CEIL(num,den) ( ((num)+(den)-1)/(den) )
902 double *inv_lifting = NULL;
906 noGammas = width >> 1;
908 inv_lifting =
new double[noGammas*ntilde];
909 for ( col=0 ; col<(int)(noGammas*ntilde) ; col++ ) {
910 inv_lifting[col] = -fwd_lifting[col];
924 const double *filter,
925 const unsigned int n,
926 const unsigned int ntilde,
927 const unsigned int width
933 double *lifting = NULL;
937 moment = create_moment(ntilde, width, 0);
938 if (! moment)
return NULL;
946 len =
CEIL (width, 1);
950 noGammas = width >> 1;
952 lifting =
new double[noGammas*ntilde];
953 for ( col=0 ; col<(int)(noGammas*ntilde) ; col++ ) {
954 lifting[col] = (double)0;
958 update_moment(moment, filter, step2, noGammas, len, n, ntilde );
960 lifting, (
const double **) moment, len, step2,
965 fprintf (stdout,
"\nLifting Coefficients:\n");
967 for ( x=0 ; x<(width>>1) ; x++ ) {
968 sprintf (buf,
"%.20g", *(liftPtr++));
969 for ( k=1 ; k<nTilde ; k++ )
970 sprintf (buf,
"%s,%.20g", buf, *(liftPtr++));
971 fprintf (stdout,
"Gamma[%d] (%s)\n", x, buf);
976 free_matrix(moment, 0, (
long)(width-1), 0, (
long)(ntilde-1) );
1002 register Data_T *lambdaPtr,
1004 register double *fP, *filterPtr;
1017 len =
CEIL(width, 1);
1018 stepIncr = stride << 1;
1026 stop2 = (len >> 1) - N + 1 + j;
1033 filterPtr = filter + N;
1036 gammaPtr = vect + (stepIncr >> 1);
1041 *(gammaPtr) -= (*(lambdaPtr)*(*(filterPtr++)));
1042 lambdaPtr += stepIncr;
1045 gammaPtr += stepIncr;
1051 lambdaPtr = vect + soi;
1055 *(gammaPtr) -= (*(lambdaPtr)*(*(fP++)));
1056 lambdaPtr += stepIncr;
1061 gammaPtr += stepIncr;
1066 vect += (soi-stepIncr);
1071 *(gammaPtr) -= (*(lambdaPtr)*(*(--fP)));
1072 lambdaPtr += stepIncr;
1075 gammaPtr += stepIncr;
1094 const register double * lcPtr;
1095 register Data_T *vL,
1111 len =
CEIL(width, 1);
1112 stepIncr = stride << 1;
1113 noGammas = len >> 1 ;
1119 stop1 = nTilde >> 1;
1121 stop2 = noGammas - nTilde + 1 + j;
1131 vG = vect + (stepIncr >> 1);
1136 *(vL) += (*(vG)*(*(lcPtr++)));
1149 *(vL) += (*(vG)*(*(lcPtr++)));
1159 vect += (soi - stepIncr);
1164 *(vL) += (*(vG)*(*(lcPtr++)));
1183 int stepIncr = stride << 1;
1195 for(i=0;i<width;i++) {
1196 t += data[i*stride];
1198 lave = t / (double) width;
1201 for (i=0; i<nG; i++) {
1202 data[stride] = data[stride] - data[0];
1203 data[0] = (Data_T)(data[0] + (data[stride] /2.0));
1214 data[0] = (Data_T)((lave * (
double) nL) - lsum);
1231 int stepIncr = stride << 1;
1239 if (
IsOdd(width) ) {
1242 for(i=0,j=0;i<nL;i++,j+=stepIncr) {
1245 lave = t/(double)nL;
1248 for (i=0; i<nG; i++) {
1249 data[0] = (Data_T)(data[0] - (data[stride] * 0.5));
1250 data[stride] = data[stride] + data[0];
1251 lsum += data[0] + data[stride];
1261 *data = (Data_T)((lave * (
double) width) - lsum);
1265 #endif // _Lifting1D_h_
COMMON_API double LogBaseN(double x, double n)
void InverseTransform(Data_T *data, int stride=1)
COMMON_API int IsOdd(int x)
void ForwardTransform(Data_T *data, int stride=1)
static const int MAX_FILTER_COEFF
maximum number of filter coefficients
Wrapper for Wim Swelden's Liftpack wavelet transform interface.
Lifting1D(unsigned int n, unsigned int ntilde, unsigned int width, int normalize=0)