//----------------------------------------------------------------------------- // name: bool setup( void ) // desc: set up original wavelet trees, calculate threshold, initialize root // of new tree //----------------------------------------------------------------------------- bool Treesynth::setup( void ) { // Get value arrays of trees float * tnew_values = tnew->values(); float * tree_values = tree->values(); // Wavelet decompositions pwtset( 10 ); wt1( tree_values, tree->getSize(), 1, *pwt ); if( lefttree ) { float * lefttree_values = lefttree->values(); wt1( lefttree_values, ( 1 << tree->getSize() ), 1, *pwt ); // pow( 2, tree->getSize() ) } // Calculate nearness threshold (epsilon) and print related values std::cout << "p: " << percentage << std::endl; std::cout << "epsilon: " << (epsilon = FindEpsilon( tree, tree->getSize(), percentage )) << std::endl; std::cout << "kfactor: " << kfactor << std::endl; // Copy root of tnew, since that's always the same tnew_values[0] = tree_values[0]; // approximation tnew_values[1] = tree_values[1]; // root // Return return true; }
int main(void) { unsigned long i,nused; int itest,k; float *u,*v,*w,frac,thresh,tmp; u=vector(1,NMAX); v=vector(1,NMAX); w=vector(1,NMAX); for (;;) { printf("Enter k (4, -4, 12, or 20) and frac (0.0 to 1.0):\n"); if (scanf("%d %f",&k,&frac) == EOF) break; frac=FMIN(1.0,FMAX(0.0,frac)); itest=(k == -4 ? 1 : 0); if (k < 0) k = -k; if (k != 4 && k != 12 && k != 20) continue; for (i=1;i<=NMAX;i++) w[i]=v[i]=(i > NCEN-NWID && i < NCEN+NWID ? ((float)(i-NCEN+NWID)*(float)(NCEN+NWID-i))/(NWID*NWID) : 0.0); if (!itest) pwtset(k); wt1(v,NMAX,1,itest ? daub4 : pwt); for (i=1;i<=NMAX;i++) u[i]=fabs(v[i]); thresh=select((int)((1.0-frac)*NMAX),NMAX,u); nused=0; for (i=1;i<=NMAX;i++) { if (fabs(v[i]) <= thresh) v[i]=0.0; else nused++; } wt1(v,NMAX,-1,itest ? daub4 : pwt); for (thresh=0.0,i=1;i<=NMAX;i++) if ((tmp=fabs(v[i]-w[i])) > thresh) thresh=tmp; printf("k,NMAX,nused= %d %d %d\n",k,NMAX,nused); printf("discrepancy= %12.6f\n",thresh); } free_vector(w,1,NMAX); free_vector(v,1,NMAX); free_vector(u,1,NMAX); return 0; }
//----------------------------------------------------------------------------- // name: void synth( void ) // desc: does wavelet tree learning to build the new tree, then does the // inverse discrete wavelet transform on the new tree to get synthesized // signal //----------------------------------------------------------------------------- void Treesynth::synth( void ) { // Set up candidate set for root (also always the same, but gets deleted) tnew_data->getNode( 0, 0 )->cs = new TS_UINT[1]; tnew_data->getNode( 0, 0 )->cs[0] = 0; tnew_data->getNode( 0, 0 )->cslength = 1; // Synthesize new tree if( startlevel <= 1 ) { for(int n = 0; n < 2; n++) { // level 1 (the level next to the root) // try copying randomly instead of in order // (so instead of LR it could be LL or RR or RL) if( randflip ) { int random = (int)( 2 * rand()/( RAND_MAX + 1.0 ) ); *(tnew->getNode( 1, n )->value) = tree->getValue( 1, random ); } else *(tnew->getNode( 1, n )->value) = tree->getValue( 1, n ); } } else { int l, n; for( l = 1; l <= startlevel; l++ ) { int length = ( 1 << l ); // (int)pow( 2, l ) for( n = 0; n < length; n++ ) { *(tnew->getNode( 1, n )->value) = tree->getValue( 1, n ); if( l == startlevel - 1 ) { tnew_data->getNode( 1, n )->cs = new TS_UINT[length]; tnew_data->getNode( 1, n )->cslength = length; for( int q = 0; q < length; q++ ) tnew_data->getNode( 1, n )->cs[q] = q; } } } } // Breadth-first part int lev; for( lev = startlevel; lev <= stoplevel; lev++ ) { if( lev >= tree->getLevels() - 1 ) break; std::cout << "Processing level " << lev << " "; std::cout << "k is " << (npredecessors = ( 1 << lev ) * kfactor) << std::endl; // (int)(pow( 2, lev ) for( int offset = 0; offset < ( 1 << lev ); offset++ ) { // (int)(pow( 2, lev ) CandidateSet( lev, offset ); if( tnew_data->getNode( lev, offset )->cslength == 0 ) std::cerr << "Double Uh-oh " << lev << "-" << offset << std::endl; // Randomly choose a node from candidate set and steal its children int randPick = (int)( rand()/(RAND_MAX + 1.0) * tnew_data->getNode( lev, offset )->cslength ); randPick = tnew_data->getNode( lev, offset )->cs[randPick]; // left child *(tnew->getNode( lev, offset )->left->value) = tree->getValue( lev+1, 2*randPick ); // right child: changed to make sure nodes referred to are within limits if( 2*offset + 1 < ( 1 << (lev + 1) ) ) { // pow( 2, lev+1 ) if( 2*randPick + 1 < ( 1 << (lev + 1) ) ) // pow( 2, lev+1 ) *(tnew->getNode( lev, offset )->right->value) = tree->getValue( lev+1, 2*randPick + 1 ); else { *(tnew->getNode( lev, offset )->right->value) = tree->getValue( lev+1, 2*randPick ); if( randPick > 0 ) *(tnew->getNode( lev, offset )->left->value) = tree->getValue( lev+1, 2*randPick - 1 ); } } // if it's stoplevel, copy all descendants if( lev == stoplevel ) { int l, m = 2, p; for( l = lev + 2; l < tree->getLevels(); l++ ) { m = 2*m; for( p = 0; p < m; p++ ) *(tnew->getNode( l, m*offset + p )->value) = tree->getValue( l, m*randPick + p ); } } // yeah... } } // Reconstruct signal from new wavelet tree TS_UINT size = tnew->getSize(); memcpy( synsig, tnew->values(), size * sizeof(TS_FLOAT) ); wt1( synsig, size, -1, *pwt ); memset( tnew->values(), 0, size * sizeof(TS_FLOAT) ); }