/***************************************************************************** File: fast_v2.c November 9 Authors: Ioan Tabus (tabus@cs.tut.fi) Doina Petrescu Alin Alecu Bogdan Dumitrescu Purpose: Fast stack filter design Copyright 1998 Ioan Tabus, Doina Petrescu, Alin Alecu, Bogdan Dumitrescu. All Rights Reserved. Reference: @ARTICLE{TFI, author = { I. T\u{a}bu\c{s} and D. Petrescu and M. Gabbouj }, title = {A Training Framework for Stack and {Boolean} Filtering-{F}ast optimal design procedures and robustness case study}, journal = TRIP # " Special Issue on Nonlinear Image Processing", volume = "IP-5", year = "1996", month = "June", pages = "809--826", } These programs are supplied free of charge for research purposes only, and may not be sold or incorporated into any commercial product. There is ABSOLUTELY NO WARRANTY of any sort, nor any undertaking that they are fit for ANY PURPOSE WHATSOEVER. Use them at your own risk. If you do happen to find a bug, or have modifications to suggest, please report it to tabus@cs.tut.fi. The copyright notice above and this statement of conditions must remain an integral part of each and every copy made of this file. /****************************************************************************/ /* */ /* Implementation of recursive procedure */ /* */ /* Inputs: */ /* - name of coefficients file (e.g. as written by coeff_final.c) */ /* - name of output filter file */ /* Output: */ /* - filter file (it will be written in boolean tabular form) */ /* */ /* Allows insertion of: - desired window size */ /* */ /* */ /****************************************************************************/ #include #include #include #include #define REC_COMP_COST /* gains are computed recursively in Hasse */ #define N0 9 /* Min. window size */ #define N 17 /* Max. size of window. Eg: 5 9 10 17 */ #define LG 131072 /* Max. no. of coefficients. Eg: 32 512 1024 131072 */ #define LN 300 /* dimension of cost matrix */ #define LNN 1000 #define NUM 258064 typedef unsigned char byte; byte fpos[LG][N+1],f[LG],fp[LG],fpocket[LG], ft[LG],fpinit[LG],fnon[LG]; int costs[LG]; /* Cost coefficients read from disk */ int cost[LG][N+1]; int C0; double J0,J2,Jmin,J,Jbool[N+1],Jstack[N+1]; double Rcost[LN]; /* Costs matrix, used in LP */ int NR, /* Current window size */ LG1; clock_t cl1; double evalJc(); /* Evaluates Jstack */ void comp_boool_stack(); /* Computes the Boolean and stack filter */ byte comp_LP(); /* Procedure which implements LP */ void calculate(); /* Computes lg, ln and lnn */ int winsize, /* Actual window size */ lg, /* 2^winsize */ ln, /* lg+2 */ lnn; /* winsize*lg/2 + 1 */ byte visited[LG]; /***************************************************************************/ void calculate(int size) { lg=pow(2,size); ln=lg+2; lnn=(size*lg/2) + 1; } /***************************************************************************/ void main( argc, argv) int argc; char * argv[]; { FILE *fpt; char namec[40], namef[40],str[10]; int nn,i,j,j1,j2,jocker,depl,p,it,imin,sw,t,st,best,v[N],cn,tmp; int jmax,k; double s,pivot; /* Input window size */ printf("\n Input window size: "); scanf("%d",&winsize); calculate(winsize); /* Reading cost coefficients from disk file */ if(argc==3) strcpy(namec, argv[1]); else { printf("\n Name of coefficients file: "); scanf("%s",namec); } fpt=fopen(namec,"r"); if(fpt==NULL) {printf("\n Can't open %s\n", namec); return;} if(argc==3) strcpy(namef,argv[2]); else { printf("\n Name of filter file: "); scanf("%s", namef); } for(nn=0;nn=N0;NR--) {LG1=LG1/2; for(j=0;j nod) && ! fpocket[fiu] && ! visited[fiu] && !fp[fiu] ) c += comp_cost_down(fiu); v <<= 1; } return c; } int comp_cost_up( int nod ) { int c, v, l, tata; c = - costs[nod]; visited[nod] = 1; v = 1; for ( l=0 ; l < NR ; l++ ) { tata = nod & (~v); if ( (tata < nod) && ! fpocket[tata] && ! visited[tata] && fp[tata] ) c += comp_cost_up(tata); v <<= 1; } return c; } /* ----------------------------------------------------------------------*/ void reset_visited_down( int nod ) { int v, l, fiu; visited[nod] = 0; v = 1; for ( l=0 ; l < NR ; l++ ) { fiu = nod | v; if ( (fiu > nod) && ! fpocket[fiu] ) reset_visited_down(fiu); v <<= 1; } } void reset_visited_up( int nod ) { int v, l, tata; visited[nod] = 0; v = 1; for ( l=0 ; l < NR ; l++ ) { tata = nod & (~v); if ( (tata < nod) && ! fpocket[tata] ) reset_visited_up(tata); v <<= 1; } } /* ----------------------------------------------------------------------*/ void set_sons_on_one(int nod) { int v, l, fiu; fp[nod] = 1; v = 1; for ( l=0 ; l < NR ; l++ ) { fiu = nod | v; if ( (fiu > nod) && ! fpocket[fiu] ) set_sons_on_one(fiu); v <<= 1; } } void set_fathers_on_zero(int nod) { int v, l, tata; fp[nod] = 0; v = 1; for ( l=0 ; l < NR ; l++ ) { tata = nod & (~v); if ( (tata < nod) && ! fpocket[tata] ) set_fathers_on_zero(tata); v <<= 1; } } /****************************************************************************/ /* Compute the boolean and stack filter */ void comp_boool_stack() { int i,j,j1,j2,depl,it,imin,sw,t,st,best,ifrez,Improv; double Jdelta,J1; /************ * Stage II * *************/ /* f will store decided nodes, namely f[i]=1 for cost[i]<0 and f[i]=0 for */ /* cost[i]>0 */ /* fnon will store undecided nodes */ for(i=0;i0.) {f[i]=0;} else {f[i]=1; if (costs[i]==0.) fnon[i]=1; } } /************/ /* Evaluate J */ Jbool[NR]=evalJc(f); printf(" Jbool %.5lf \n ",Jbool[NR]); /* Test if the Boolean filter is stack */ /*********************** * Stage III-1 + III-2 * ***********************/ best=1; for(i=LG1-1;i>=0;i--) { fpocket[i]=0;fp[i]=0; /* if f[node]=1 (decided on 1), verify all nodes that stack under. If we */ /* find one that has f[node']=0, then stack condition not respected */ if(f[i]) { fp[i]=1;fpocket[i]=1; depl=1; for(j=0;ji) {if(!fp[j2]){fp[i]=0;fpocket[i]=0;best=0;break;} } /*j2 lays under i*/ } } } /* exit with fp=set I1 */ /*******************/ /* Evaluate J */ J0=evalJc(fp); printf(" J(f^+_max) %.5lf \n ",J0); if(best==0) { printf(" Boolean isn't stack!\n"); /* If Boolean isn't stack, then back to work */ if (NR!=N0) { for(i=0;i<(LG1/2);i++) fpinit[i+(LG1/2)]=fpinit[i]; for(i=0;i=LN) {cannot=1;return(cannot);} } /* Construct R */ /* for every ni belonging to coresp, search for every node nj that stacks */ /* under. If fpocket[nj]=1 (decided node) then R[k,i]=1 and R[k,LGG1]=1 , */ /* after which we select another ni */ /* If fpocket[nj]=0 (undecided node) then R[k,i]=1, R[k,j]=-1, */ /* R[k,LGG1]=0 after which go to next nj */ LNN1=0; for(i=0;i=LNN) {cannot=1;return(cannot);} jocker=0; } } else { for(p=0;p<=LGG1;p++) R[LNN1][p]=0; R[LNN1][cor[j2]]=-1; R[LNN1][i]=1; if(LNN1>=LNN) {cannot=1;return(cannot);} LNN1++; } } } } LN1=LGG1+2; /* Construct zerov */ for(it=0;it=0;k--) { if(fp[k]==1) { jmax=-1; for(j=0;js) {k=i;s=Rcost[i];} if(Rcost[k]<=0) break; /* All done! */ /* identical algorithm as that of initialization */ else { jmax=-1; for(j=0;j=0;i--) { fpocket[i]=0; if(fp[i]) { fpocket[i]=1; depl=1; for(j=0;ji) {if(!fp[j2]){ fpocket[i]=0;best=0;break;} } /*j2 lays under i*/ } } } if(best==0) printf(" Stack is not a stack!\n"); else printf(" Stack is stack!\n"); printf("\n LNN1=%d LGG1=%d J=%.5lf \n",LNN1,LGG1,evalJc(fp)); printf(" %.5lf",evalJc(fp)); printf(" %.3lf",((double)clock()-cl1)/CLOCKS_PER_SEC); return(0); }