/*************************************************************************** * Copyright (C) 2008 by Douglas Castro * * douglas@localhost.localdomain * * * ***************************************************************************/ #include "amr.h" double trunca_detalhe(double detalhe); double trunca_detalhe(double detalhe) { if(fabs(detalhe) < 0.01) { detalhe = 0.0; } return detalhe; } void amr_analise_haar(Reg *pac, int profund, double eps, bool_t sim) { assert((pac->esq == NULL) == (pac->dir == NULL)); if (pac->esq == NULL) { /* Não há o que fazer: */ return; } int qual; for (qual = 0; qual <= 1; qual++) { if(qual==0) { amr_analise_haar(pac->esq, profund+1, eps, sim); } else { amr_analise_haar(pac->dir, profund+1, eps, sim); } } // lembrando: |C^k| = |C^{k-1}|/2 // |f^k| = (|f^{k+1}_e| + |f^{k+1}_d|)/2 double restricao = ( pac->esq->fval + pac->dir->fval )/2.0; double detalhe = ( pac->esq->fval - pac->dir->fval )/2.0; // detalhe = trunca_detalhe(detalhe); pac->esq->fval = detalhe; pac->fval = restricao; /* Elimina os filhos, se sao nao-nulos mas ambos superfluos e tem netos nulos: */ /* truncamento dos detalhes, se necessario */ if(sim) {// se sim == TRUE, entra aqui if (fabs(detalhe) < eps && pac->esq->esq==NULL) { /* Elimina os dois filhos: */ free(pac->esq); pac->esq = NULL; free(pac->dir); pac->dir = NULL; } } return; } void amr_sintese_haar(Reg *pac, int profund) { assert((pac->esq == NULL) == (pac->dir == NULL)); if (pac->esq == NULL) { /* Não há o que fazer: */ return; } double detalhe = pac->esq->fval; pac->esq->fval = pac->fval + detalhe; pac->dir->fval = pac->fval - detalhe; int qual; for (qual = 0; qual <= 1; qual++) { if(qual==0) { amr_sintese_haar(pac->esq, profund+1); } else { amr_sintese_haar(pac->dir, profund+1); } } } void amr_analise_harten(VReg pac[], double xmin[], double xmax[], int profund, Preditor pred, double eps, bool_t sim) { int k=5; int ctr = (k*k)/2; assert((pac[ctr].p->esq == NULL) == (pac[ctr].p->dir == NULL)); if (pac[ctr].p->esq == NULL) { /* Não há o que fazer: */ return; } /* Decide o eixo {ex} perpendicular ao corte: */ int ex = profund % 2; int qual; for (qual = 0; qual <= 1; qual++) { VReg pac_fil[k*k]; double xmin_fil[2], xmax_fil[2]; /* Constrói o pacote do filho {qual}: */ esc_pac_ana(pac, xmin, xmax, ex, pred, qual, pac_fil, xmin_fil, xmax_fil); amr_analise_harten(pac_fil, xmin_fil, xmax_fil, profund+1, pred, eps, sim); } // lembrando: |C^k| = |C^{k-1}|/2 // |f^k| = (|f^{k+1}_e| + |f^{k+1}_d|)/2 // printf("prof = %d, ex = %d\n",profund, ex); double restricao = ( pac[ctr].p->esq->fval + pac[ctr].p->dir->fval )/2.0; double fa, fb, fc; if (ex == 0) { fa = pac[ctr-1].fv; fb = pac[ctr].fv; fc = pac[ctr+1].fv; } else { fa = pac[ctr-k].fv; fb = pac[ctr].fv; fc = pac[ctr+k].fv; } double fprev_fil = pred(fa, fb, fc);/// por enquanto usamos a interplacao pra prever o filho esquerdo; double detalhe = pac[ctr].p->esq->fval - fprev_fil; pac[ctr].p->esq->fval = detalhe; pac[ctr].p->fval = restricao; pac[ctr].p->dir->fval = restricao; /* truncamento dos detalhes, se necessario */ assert((pac[ctr].p->esq->esq==NULL) == (pac[ctr].p->esq->dir==NULL)); assert((pac[ctr].p->dir->esq==NULL) == (pac[ctr].p->dir->dir==NULL)); // printf("det = %f\n",fabs(detalhe)); if(sim) {// se sim == TRUE, entra aqui if ((fabs(detalhe) < eps) && (pac[ctr].p->esq->esq==NULL) && (pac[ctr].p->dir->esq==NULL)) { /* Elimina os dois filhos: */ free(pac[ctr].p->esq); pac[ctr].p->esq = NULL; free(pac[ctr].p->dir); pac[ctr].p->dir = NULL; } } return; } void amr_sintese_harten(VReg pac[], double xmin[], double xmax[], int profund, Preditor pred) { int k=5; // posteriormente k pode se tornar argumento da funcao int ctr = (k*k)/2; assert((pac[ctr].p->esq == NULL) == (pac[ctr].p->dir == NULL)); if (pac[ctr].p->esq == NULL) { /* Não há o que fazer: */ return; } /* Decide o eixo {ex} perpendicular ao corte: */ int ex = profund % 2; double fa, fb, fc; if (ex == 0) { fa = pac[ctr-1].fv; fb = pac[ctr].fv; fc = pac[ctr+1].fv; } else { fa = pac[ctr-k].fv; fb = pac[ctr].fv; fc = pac[ctr+k].fv; } double detalhe = pac[ctr].p->esq->fval; double fprev = pred(fa, fb, fc);; double esq = fprev + detalhe; pac[ctr].p->esq->fval = esq; double dir = 2.0*pac[ctr].p->dir->fval - esq; pac[ctr].p->dir->fval = dir; int qual; //double fprev_fil; for (qual = 0; qual <= 1; qual++) { VReg pac_fil[k*k]; double xmin_fil[2], xmax_fil[2]; /* Constrói o pacote do filho {qual}: */ esc_pac_ana(pac, xmin, xmax, ex, pred, qual, pac_fil, xmin_fil, xmax_fil); amr_sintese_harten(pac_fil, xmin_fil, xmax_fil, profund+1, pred); } } void esc_pac_sin(VReg pac[],double xmin[], double xmax[], int ex, Preditor pred, int qual, VReg fil[], double xmin_fil[], double xmax_fil[]) { int k=5; double xmed = (xmin[ex] + xmax[ex])/2.0; xmin_fil[ex] = (qual == 0 ? xmin[ex] : xmed); xmax_fil[ex] = (qual == 0 ? xmed : xmax[ex]); xmin_fil[1-ex] = xmin[1-ex]; xmax_fil[1-ex] = xmax[1-ex]; int i,j; if(ex == 0) { // montando gabarito for(i=0; iesq); fv_fil = /*((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval);*/ fint; } else { p_fil = (pl == NULL ? NULL : pl->dir); fv_fil = /*((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval);*/ 2.0*fb - fint; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } else { /* filho direito: */ for(j=0; jdir); fv_fil = /*((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval);*/ 2.0*fb - fint; } else { p_fil = (pl == NULL ? NULL : pl->esq); fv_fil = /*((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval);*/ fint; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } } } else { // montando gabarito int i,j; for(i=0;idir); fv_fil = /*((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval);*/ 2.0*fb - fint; } else { p_fil = (pl == NULL ? NULL : pl->esq); fv_fil = /*((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval);*/ fint; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } else {//filho esquerdo for(j=0;jesq); fv_fil = /*((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval);*/ fint; } else { p_fil = (pl == NULL ? NULL : pl->dir); fv_fil = /*((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval);*/ 2.0*fb - fint; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } } } } /// COMO CRIAR UM PACOTE PARA ALGORITMO DA ANALISE?? void esc_pac_ana(VReg pac[],double xmin[], double xmax[], int ex, Preditor pred, int qual, VReg fil[], double xmin_fil[], double xmax_fil[]) { int k=5; double xmed = (xmin[ex] + xmax[ex])/2.0; xmin_fil[ex] = (qual == 0 ? xmin[ex] : xmed); xmax_fil[ex] = (qual == 0 ? xmed : xmax[ex]); xmin_fil[1-ex] = xmin[1-ex]; xmax_fil[1-ex] = xmax[1-ex]; int i,j; if(ex == 0) { // montando gabarito for(i=0; iesq); fv_fil = /*((pl == NULL || pl->esq == NULL) ?*/ fint /*: pl->esq->fval)*/; } else { // 2*fb-fint = 2*fb - (fb + (fc -fa)/8.0) = fb - (fc -fa)/8.0 p_fil = (pl == NULL ? NULL : pl->dir); fv_fil = /*((pl == NULL || pl->dir == NULL) ?*/ 2.0*fb - fint /*: pl->dir->fval)*/; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } else { /* filho direito: */ for(j=0; jdir); fv_fil = /*((pl == NULL || pl->dir == NULL) ?*/ 2.0*fb - fint /*: pl->dir->fval)*/; } else { p_fil = (pl == NULL ? NULL : pl->esq); fv_fil = /*((pl == NULL || pl->esq == NULL) ?*/ fint /*: pl->esq->fval)*/; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } } } else { // montando gabarito int i,j; for(i=0;idir); fv_fil = /*((pl == NULL || pl->dir == NULL) ?*/ 2.0*fb - fint /*: pl->dir->fval)*/; } else { p_fil = (pl == NULL ? NULL : pl->esq); fv_fil = /*((pl == NULL || pl->esq == NULL) ?*/ fint /*: pl->esq->fval)*/; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } else {//filho esquerdo for(j=0;jesq); fv_fil = /*((pl == NULL || pl->esq == NULL) ?*/ fint /*: pl->esq->fval)*/; } else { p_fil = (pl == NULL ? NULL : pl->dir); fv_fil = /*((pl == NULL || pl->dir == NULL) ?*/ 2.0*fb - fint /*: pl->dir->fval)*/; } fil[i*k+j].p = p_fil; fil[i*k+j].fv = fv_fil; } } } } } // void amr_analise(VReg pac[], double xmin[], double xmax[], int profund, Preditor pred) // { // int k=5; // posteriormente k pode se tornar argumento da funcao // int ctr = (k*k)/2; // // assert((pac[ctr].p->esq == NULL) == (pac[ctr].p->dir == NULL)); // // if (pac[ctr].p->esq == NULL) // { /* Não há o que fazer: */ // return; // } // // /* fprintf(stderr, "%*sf(int) = %9.6f f(arv)= %9.6f\n", 2*profund, "", pac[ctr].fv, pac[ctr].p->fval); */ // // /* Decide o eixo {ex} perpendicular ao corte: */ // int ex = profund % 2; // // int qual; // double fprev_fil; // // for (qual = 0; qual <= 1; qual++) // { // VReg pac_fil[k*k]; // double xmin_fil[2], xmax_fil[2]; // // /* Constrói o pacote do filho {qual}: */ // esc_pac(pac, xmin, xmax, ex, pred, qual, pac_fil, xmin_fil, xmax_fil); // // amr_analise(pac_fil, xmin_fil, xmax_fil, profund+1, pred); // } // // // lembrando: |C^k| = |C^{k-1}|/2 // // |f^k| = (|f^{k+1}_e| + |f^{k+1}_d|)/2 // printf("paiant= %f ,", pac[ctr].p->fval); // pac[ctr].fv = ( pac[ctr].p->esq->fval + pac[ctr].p->dir->fval )/2.0; // // double fa, fb, fc; // if (ex == 0) // { // fa = pac[ctr-1].fv; // fb = pac[ctr].fv; // fc = pac[ctr+1].fv; // } // else // { // fa = pac[ctr-k].fv; // fb = pac[ctr].fv; // fc = pac[ctr+k].fv; // } // double fint = pred(fa, fb, fc); // // if (qual == 0) // // { fprev_fil = 2.0*fb - fint; }//ou essa?? // // else // { fprev_fil = fint; } // eh essa a previsao correta?? // // double detalhe = pac[ctr].p->esq->fval - fprev_fil; // pac[ctr].p->esq->fval = detalhe; // pac[ctr].p->dir->fval = pac[ctr].fv; // printf("prof= %d, pai= %f, det= %f \n", profund, pac[ctr].fv, pac[ctr].p->esq->fval); // return; // // } // // void amr_sintese(VReg pac[], double xmin[], double xmax[], int profund, Preditor pred) // { // int k=5; // posteriormente k pode se tornar argumento da funcao // int ctr = (k*k)/2; // assert((pac[ctr].p->esq == NULL) == (pac[ctr].p->dir == NULL)); // if (pac[ctr].p->esq == NULL) // { /* Não há o que analisar: */ // return; // } // // /* Decide o eixo {ex} perpendicular ao corte: */ // int ex = profund % 2; // // int qual; // double fprev_fil; // // for (qual = 0; qual <= 1; qual++) // { // VReg pac_fil[k*k]; // double xmin_fil[2], xmax_fil[2]; // // /* Constrói o pacote do filho {qual}: */ // esc_pac(pac, xmin, xmax, ex, pred, qual, pac_fil, xmin_fil, xmax_fil); // //amr_previsao // double fa, fb, fc; // if (ex == 0) // { // fa = pac[ctr-1].fv; // fb = pac[ctr].fv; // fc = pac[ctr+1].fv; // } // else // { // fa = pac[ctr-k].fv; // fb = pac[ctr].fv; // fc = pac[ctr+k].fv; // } // double fint = pred(fa, fb, fc); // // if (qual == 0) // // { fprev_fil = 2.0*fb - fint; } // // else // // { fprev_fil = fint; } // double fprev = /*2.0*fb -*/ fint + pac[ctr].p->esq->fval; // pac[ctr].p->esq->fval = fprev; // pac[ctr].p->dir->fval = 2.0*(pac[ctr].p->fval) - fprev; // // if ( qual == 0 ) // { // pac_fil[ctr].fv = fprev; // } // else // { // pac_fil[ctr].fv = pac[ctr].p->dir->fval; // } // // amr_sintese(pac_fil, xmin_fil, xmax_fil, profund+1, pred); // } // // } // // void esc_pac(VReg pac[],double xmin[], double xmax[], int ex, Preditor pred, int qual, VReg fil[], double xmin_fil[], double xmax_fil[]) // { // int k=5; // // double xmed = (xmin[ex] + xmax[ex])/2.0; // xmin_fil[ex] = (qual == 0 ? xmin[ex] : xmed); // xmax_fil[ex] = (qual == 0 ? xmed : xmax[ex]); // // xmin_fil[1-ex] = xmin[1-ex]; // xmax_fil[1-ex] = xmax[1-ex]; // // int i,j,ind=1; // if(ex == 0) // { // montando gabarito // for(i=0; iesq); // fv_fil = ((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval); // } // else // { // p_fil = (pl == NULL ? NULL : pl->dir); // fv_fil = ((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval); // } // fil[i*k+j].p = p_fil; // fil[i*k+j].fv = fv_fil; // } // } // else // { /* filho direito: */ // for(j=0; jdir); // fv_fil = ((pl == NULL || pl->dir == NULL) ? 2.0*fb -fint : pl->dir->fval); // } // else // { // p_fil = (pl == NULL ? NULL : pl->esq); // fv_fil = ((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval); // } // fil[i*k+j].p = p_fil; // fil[i*k+j].fv = fv_fil; // } // } // } // } // else // { // // montando gabarito // int i,j; // for(i=0;idir); // fv_fil = ((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval); // } // else // { // p_fil = (pl == NULL ? NULL : pl->esq); // fv_fil = ((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval); // } // fil[i*k+j].p = p_fil; // fil[i*k+j].fv = fv_fil; // } // } // else // {//filho esquerdo // for(j=0;jesq); // fv_fil = ((pl == NULL || pl->esq == NULL) ? fint : pl->esq->fval); // } // else // { // p_fil = (pl == NULL ? NULL : pl->dir); // fv_fil = ((pl == NULL || pl->dir == NULL) ? 2.0*fb - fint : pl->dir->fval); // } // fil[i*k+j].p = p_fil; // fil[i*k+j].fv = fv_fil; // } // } // } // } // } // // //