/*************************************************************************** * Copyright (C) 2008 by Douglas Castro,,, * * douglas@douglas-laptop * ***************************************************************************/ /* Last edited on 2008-08-15 14:01:15 by stolfi */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "definicoes.h" #include "imprime.h" #include "arvore.h" #include "interp_integ.h" #include "bases.h" #include "amr.h" #include // #include void DoEPSTests(char *prefixo); void DrawThings(PSStream *ps); void DrawTexts(PSStream *ps, double xc, double yc); void DrawLines(PSStream *ps, double xc, double yc, bool_t arrowheads); void DrawFigures(PSStream *ps, double xc, double yc, bool_t fill, bool_t draw, bool_t eo); void testa_divide_pacote(void); void plota_elemento_da_base(void); void desenha_folhas(PSStream *ps,Reg *r, int ind, int prof, double xmin, double xmax, double ymin, double ymax); void DoMesh(char *prefixo, Reg *u); void DrawCells(PSStream *ps, double xmin, double xmax, double ymin, double ymax, bool_t fill, bool_t draw, bool_t eo); void MakeTree(char *prefixo, Reg *u); void DrawNodes(PSStream *ps,Reg *u, int prof, double x,double y); void MakeLines(PSStream *ps, int qual, int prof, double xc, double yc, bool_t arrowheads); double funcao0(double x, double y); /* Fun��o que � 1 no miolo e zer ona fronteira. */ double funcao1(double x, double y); double funcao2(double x, double y); double funcao0(double x, double y) { double u = (x - 0.25)/0.5; // mapeia x:[0.25--0.75] --> u:[0--1] double v = (y/M_SQRT1_2 - 0.25)/0.5; // mapeia y:[0.25--0.75]*sqrt(1/2) --> v[0--1] if ((u < 0) || (u > 1)) { return 0.0; } if ((v < 0) || (v > 1)) { return 0.0; } double wx = u*(1.0 - u); double wy = v*(1.0 - v); double w = wx*wy; return (1.0 - cos(16*M_PI*w)); } double funcao1(double x, double y) { double pi = 3.1415926535897932; if(x<0.0) { return 1.0 - 5.0*((3.0 - x)*(-2.0 - x) - (3.0 - y)*(-2.0 - y))*sin(pi*x)*sin(pi*x); } else if(x>1.0) { return 1.0 + 5.0*((3.0 - x)*(-2.0 - x) - (3.0 - y)*(-2.0 - y))*sin(pi*x)*sin(pi*x); } else { return 1.0 - 5.0*((3.0 - x)*(-2.0 - x) - (3.0 - y)*(-2.0 - y))*sin(pi*x)*sin(pi*x) + 100.0*sin(pi*x)*sin(pi*y); } } double funcao2(double x, double y) { double xc = 0.500, yc = 0.500*M_SQRT1_2; double r = 0.100; /* Gaussiana centrada em {xc,yc} com raio medio {r}: */ double dx = x - xc, dy = y - yc; return funcao0(x,y) * exp(-(dx*dx + dy*dy)/(2*r*r)); } #define OUT_PREFIX "out" int main(int argc, char *argv[]) { // testa_divide_pacote(); plota_elemento_da_base(); /** Cria uma arvore completa */ double xmin[]={0.0,0.0},xmax[]={1.0,M_SQRT1_2}; int niv = 12, profund = 0, indice =1; double eps_poda = 0.001; Funcao *f = &funcao2; Reg *u = completa(niv, profund, indice,xmin,xmax,funcao2,integra); printf("Cheque arquivo completa.txt para obter dados de saida\n"); FILE *disco = fopen("completa.txt", "w"); mostra_folhas(disco, u, 1, 0, xmin[0], xmax[0], xmin[1], xmax[1]); fclose(disco); /** aqui termina a criacao da arvore completa */ /** Podando a arvore */ // pra isso criamos um pacote com medias conheciadas fora do dominio double fval[25]; int kx, ky; for (kx = 0; kx < 5; kx++) { for (ky = 0; ky < 5; ky++) { double xlo = xmin[0] + (-2.0 + kx)*(xmax[0] - xmin[0]); double xhi = xmin[0] + (-1.0 + kx)*(xmax[0] - xmin[0]); double ylo = xmin[1] + (-2.0 + ky)*(xmax[1] - xmin[1]); double yhi = xmin[1] + (-1.0 + ky)*(xmax[1] - xmin[1]); double fint = integra(xlo, xhi, ylo, yhi, f); // fprintf(stderr, "x = [%8.6f %8.6f] y = [%8.6f %8.6f] int = %24.16e\n", xlo, xhi, ylo, yhi, fint); fval[5*ky + kx] = fint/((xhi-xlo)*(yhi-ylo)); } } Reg *pc[] = {NULL, NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, u, NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL}; VReg pac[25]; int i; for(i=0;i<25;i++) { pac[i].p = pc[i]; pac[i].fv = fval[i]; } // imprime o que esta fora do dominio para saber o que a funcao de interpolacao faz la FILE *beira = fopen("beirada.txt", "w"); imprime_arvore(beira, pac, xmin, xmax, 0, interpola_quad); fclose(beira); double podaf=integra(xmin[0], xmax[0], xmin[1], xmax[1], f)/(fabs(xmin[0]- xmax[0])*fabs(xmin[1]- xmax[1])); // aqui e feita a poda da arvore (void) poda_arvore(pac, xmin, xmax, 0, interpola_quad, podaf, eps_poda); printf("Cheque arquivo podada.txt para obter dados de saida\n"); FILE *podada = fopen("podada.txt", "w"); mostra_folhas(podada, u, 1, 0, xmin[0], xmax[0], xmin[1], xmax[1]); fclose(podada); /// aqui termina a parte da jardinagem (poda) /// em desenvolvimento! tentar recuparar o falor pontual, conhecendo as medias // double x[] = {0.7,0.3}; // double fx = f(x[0],x[1]); // double fv = avalia_arvore(pac, xmin, xmax, niv, profund, interpola_quad, x); // DoEPSTests(); /// Algumas impressoes relevantes // desennha as celulas folha da arvore DoMesh(OUT_PREFIX, u); // desenha a arvore binaria MakeTree(OUT_PREFIX, u); /// Aqui comecam os testes da analise multiresolucao (AMR) // primeiro a analise // comecamos com criacao de uma arvore completa Reg *v = completa(niv, profund, indice,xmin,xmax,funcao2,integra); // depois um pacote um pacote com medias conheciadas fora do dominio Reg *pct[] = {NULL, NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, v, NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL}; for(i=0;i<25;i++) { pac[i].p = pct[i]; pac[i].fv = fval[i]; } //analise! printf("raiz real = %f, raizint = %f, filesq = %f, fildir = %f\n", pac[12].p->fval,pac[12].fv,pac[12].p->esq->fval,pac[12].p->dir->fval); amr_analise( pac, xmin, xmax, profund, interpola_quad); printf("raiz real = %f, raizint = %f, filesq = %f, fildir = %f\n", pac[12].p->fval,pac[12].fv,pac[12].p->esq->fval,pac[12].p->dir->fval); //e comeca a sintese! amr_sintese( pac, xmin, xmax, profund, interpola_quad); printf("raiz real = %f, raizint = %f, filesq = %f, fildir = %f\n", pac[12].p->fval,pac[12].fv,pac[12].p->esq->fval,pac[12].p->dir->fval); //imprimir pra ver se prestou FILE *amr1 = fopen("amr.txt", "w"); mostra_folhas(amr1, v, 1, 0, xmin[0], xmax[0], xmin[1], xmax[1]); fclose(amr1); /// Em desenvolvimento! Criacao da base. // criar um pacote para testar a base // Reg *phi = NULL; // VReg phi_ij[25]; // int ii,jj; // for(ii=0;ii<5;ii++) // { // for(jj=0;jj<5;jj++) // { // phi_ij[ii*5+jj].p = phi; // phi_ij[ii*5+jj].fv = 0.0; // } // } printf("aquichegou\n"); // for(ii=0;ii<25;ii++) // { // phi_ij[ii].fv = 1.0; // cria_base(phi_ij, xmin, xmax, 0, interpola_quad, eps_poda); // printf("%10.6f \n",phi_ij[12].fv); // phi_ij[ii].fv = 0.0; // } // printf("\n"); return EXIT_SUCCESS; } void plota_elemento_da_base(void) { double xmin[2], xmax[2]; xmin[0] = 0; xmax[0] = 1.0; xmin[1] = 0; xmax[1] = sqrt(0.5); int niv_t = 7; /* Constrói um pacote com árvores de nível {niv_t} e valores nulos: */ int k=5; // Todo pacote tem {k*k} elementos. // int ctr = (k*k)/2; VReg pac[k*k]; int i; for(i=0;ifval = v; p = (prof < 2 ? p->esq : p->dir); v *= 2; } } int i0, i1; for (i1 = 0; i1 < k; i1++) { for (i0 = 0; i0 < k; i0++) { /* Bota um emelento 1.0, o resto 0.0: */ bota(i0, i1, 1.0); fprintf(stderr, "=== testando divisao de pacote ===\n"); mostra_pacote(stderr, pac, k, xmin, xmax); int qual, ex; for (ex = 0; ex < 2; ex++) { for (qual = 0; qual < 2; qual++) { fprintf(stderr, "direcao = %d filho = %d\n", ex, qual); double xmin_fil[2], xmax_fil[2]; VReg fil[k*k]; divide_pacote(pac, xmin, xmax, ex, interpola_quad, qual, fil, xmin_fil, xmax_fil); mostra_pacote(stderr, fil, k, xmin_fil, xmax_fil); } } /* Limpa pacote: */ bota(i0, i1, 0.0); } } } /** * Funcao que sai a procura de celulas folhas na arvore e desenha tais celulas */ void desenha_folhas(PSStream *ps,Reg *r, int ind, int prof, double xmin, double xmax, double ymin, double ymax) { assert((r->esq == NULL) == (r->dir == NULL)); if(r->esq==NULL) { DrawCells(ps, xmin, xmax, ymin, ymax, TRUE, TRUE, FALSE); return; } if(prof%2==0) { desenha_folhas(ps, r->esq, 2*ind + 0, prof + 1, xmin, (xmax+xmin)/2.0, ymin, ymax); desenha_folhas(ps, r->dir, 2*ind + 1, prof + 1, (xmax+xmin)/2.0, xmax, ymin, ymax); } else { desenha_folhas(ps, r->esq, 2*ind + 0, prof + 1, xmin, xmax, ymin, (ymax+ymin)/2.0); desenha_folhas(ps, r->dir, 2*ind + 1, prof + 1, xmin, xmax, (ymin+ymax)/2.0, ymax); } } /** * A chamada dessa funcao retorna a grade formada por todas as celulas folha da arvore */ void DoMesh(char *prefixo, Reg *u) { PSStream *ps = pswr_new_stream(TRUE, prefixo, NULL, NULL, FALSE, 328.0, 246.0); pswr_new_page(ps, "mesh"); pswr_set_window ( ps, -22.00, +22.00, -16.50, +16.50, 4.00, 324.00, 3.00, 243.00, 44, 33 ); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.20, 0.0, 0.0); pswr_set_fill_color(ps, 1.000, 1.000, 1.000); // chamar uma funcao que sai a procura de folhas desenha_folhas(ps, u, 1, 0, 0.0, 1.0, 0.0, 1.0); pswr_close_stream(ps); } void DrawCells(PSStream *ps, double xmin, double xmax, double ymin, double ymax, bool_t fill, bool_t draw, bool_t eo) { /* Usable area [0 _ 12]�[0 _ 15] */ // Aqui e feita uma mudanca de escala para que o retangulo se ajuste ao // dominio onde e feito o desenho [-22,22]X[-16.5,16,5] double xe = 44.0*xmin-22.0; double xd = 44.0*xmax-22.0; double ye = 33.0*ymin-16.5; double yd = 33.0*ymax-16.5; pswr_rectangle(ps, xe, xd, ye, yd, fill, draw); } void MakeTree(char *prefixo, Reg *u) { PSStream *ps = pswr_new_stream(TRUE, prefixo, NULL, NULL, FALSE, 328.0, 246.0); pswr_new_page(ps, "tree"); pswr_set_window ( ps, -22.00, +22.00, -16.50, +16.50, 4.00, 324.00, 3.00, 243.00, 44, 33 ); double x=0.0,y=12.0; int prof = 0; DrawNodes(ps,u,prof,x,y); pswr_close_stream(ps); } void DrawNodes(PSStream *ps,Reg *u, int prof, double x,double y) { if(u->esq==NULL){ return;} pswr_comment(ps, "Medium solid black segments:"); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.20, 0.0, 0.0); int qual; for(qual = 0;qual<=1;qual++) { if(qual==0) { DrawNodes(ps, u->esq, prof+1, x-20.0/(pow(2.0,prof+1)), y-2.0); } else { DrawNodes(ps, u->dir, prof+1, x+20.0/(pow(2.0,prof+1)), y-2.0); } MakeLines(ps, qual, prof, x, y, FALSE); } } void MakeLines(PSStream *ps, int qual, int prof, double xc, double yc, bool_t arrowheads) { auto void do_seg(double xa, double ya, double xb, double yb); void do_seg(double xa, double ya, double xb, double yb) { pswr_segment(ps, xa+xc, ya+yc, xb+xc, yb+yc); pswr_dot(ps, xa+xc, ya+yc, 1.0, FALSE, TRUE); pswr_dot(ps, xb+xc, yb+yc, 1.0, FALSE, TRUE); if (arrowheads) { pswr_arrowhead(ps, xa+xc, ya+yc, xb+xc, yb+yc, 2.0, 3.0, 0.85, TRUE, TRUE); } } // pswr_dot(ps, 0.0,12.0, 1.0,TRUE, TRUE); // pswr_dot(ps, -20.0,12.0, 1.0,TRUE, TRUE); // pswr_dot(ps, 20.0,12.0, 1.0,TRUE, TRUE); if(qual==0) { do_seg(-20.0/(pow(2.0,prof+1)), -2.0, 0.0, /*3*/0.0); //esq } else { do_seg(0.0, /*3*/0.0, 20.0/(pow(2.0,prof+1)), -2.0); //dir } } void DoEPSTests(char *prefixo) { PSStream *ps = pswr_new_stream(TRUE, prefixo, NULL, NULL, FALSE, 328.0, 246.0); pswr_new_page(ps, NULL); pswr_set_window ( ps, -22.00, +22.00, -16.50, +16.50, 4.00, 324.00, 3.00, 243.00, 44, 33 ); DrawThings(ps); pswr_close_stream(ps); } void DrawThings(PSStream *ps) { pswr_comment(ps, "Thick solid red frame:"); pswr_set_pen(ps, 1.000, 0.000, 0.000, 0.40, 0.0, 0.0); pswr_frame(ps); pswr_comment(ps, "Thin dashed light yellow gridlines:"); pswr_set_pen(ps, 1.000, 1.000, 0.500, 0.10, 2.0, 1.0); pswr_grid_lines(ps); pswr_comment(ps, "Medium solid black coordinate lines:"); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.20, 0.0, 0.0); pswr_coord_line(ps, HOR, 0.17); pswr_coord_line(ps, VER, 3.14); pswr_comment(ps, "Text in various positions:"); DrawTexts(ps, -20.0, -15.5); pswr_comment(ps, "Medium solid black segments:"); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.20, 0.0, 0.0); DrawLines(ps, -6.0, -15.5, FALSE); pswr_comment(ps, "Thicker blue segments with arrowheads:"); pswr_set_pen(ps, 0.000, 0.000, 1.000, 0.40, 0.0, 0.0); DrawLines(ps, +8.0, -15.5, TRUE); pswr_comment(ps, "Thin solid black figures, yellow filled:"); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.10, 0.0, 0.0); pswr_set_fill_color(ps, 1.000, 1.000, 0.000); pswr_grid_cell(ps, 3, 2, TRUE, TRUE); DrawFigures(ps, -20.0, +0.5, TRUE, TRUE, FALSE); pswr_comment(ps, "Medium solid red figures, unfilled:"); pswr_set_pen(ps, 1.000, 0.000, 0.000, 0.20, 0.0, 0.0); pswr_set_fill_color(ps, -1.00, -1.00, -1.00); pswr_grid_cell(ps, 5, 2, TRUE, TRUE); DrawFigures(ps, -6.0, +0.5, TRUE, TRUE, FALSE); pswr_comment(ps, "Unstroked figures, pink e-o-filled:"); pswr_set_pen(ps, 0.000, 0.000, 0.000, 0.50, 0.0, 0.0); pswr_set_fill_color(ps, 1.000, 0.800, 0.700); pswr_grid_cell(ps, 7, 2, TRUE, FALSE); DrawFigures(ps, +8.0, +0.5, TRUE, FALSE, TRUE); } void DrawTexts(PSStream *ps, double xc, double yc) { /* Usable area [0 _ 12]�[0 _ 15] */ pswr_rectangle(ps, 0.25+xc, 11.75+xc, 0.25+yc, 14.75+yc, FALSE, TRUE); auto void do_lab(char *text, double xd, double yd, double xalign, double yalign); void do_lab(char *text, double xd, double yd, double xalign, double yalign) { pswr_set_fill_color(ps, 0.000, 0.700, 1.000); pswr_dot(ps, xd+xc, yd+yc, 0.3, TRUE, FALSE); pswr_label(ps, text, xd+xc, yd+yc, xalign, yalign); } pswr_set_pen(ps, 1.000, 0.000, 0.000, 0.50, 0.0, 0.0); pswr_set_label_font(ps, "Courier", 10.0); do_lab("red C10", +1.00, +3.00, 0.0, 0.0); pswr_set_label_font(ps, "Times-Roman", 12.0); do_lab("red TR12", +6.00, +6.00, 0.5, 0.0); pswr_set_pen(ps, 0.000, 0.000, 1.000, 0.50, 0.0, 0.0); pswr_set_label_font(ps, "Helvetica", 8.0); do_lab("blu H8", +11.00, +9.00, 1.0, 0.5); pswr_set_label_font(ps, "Courier", 12.0); do_lab("blu C12", +1.00, +12.00, 0.0, 0.5); } void DrawLines(PSStream *ps, double xc, double yc, bool_t arrowheads) { /* Usable area [0 _ 12]�[0 _ 15] */ pswr_rectangle(ps, 0.25+xc, 11.75+xc, 0.25+yc, 14.75+yc, FALSE, TRUE); auto void do_seg(double xa, double ya, double b, double yb); void do_seg(double xa, double ya, double xb, double yb) { pswr_segment(ps, xa+xc, ya+yc, xb+xc, yb+yc); pswr_dot(ps, xa+xc, ya+yc, 1.0, FALSE, TRUE); pswr_dot(ps, xb+xc, yb+yc, 1.0, FALSE, TRUE); if (arrowheads) { pswr_arrowhead(ps, xa+xc, ya+yc, xb+xc, yb+yc, 2.0, 3.0, 0.85, TRUE, TRUE); } } do_seg(1.0, 1.0, 11.0, 3.0); do_seg(1.0, 3.0, 11.0, 1.0); pswr_segment(ps, 1.0+xc, 5.0+yc, 1.0+xc, 13.0+yc); pswr_segment(ps, 11.0+xc, 5.0+yc, 11.0+xc, 13.0+yc); pswr_segment(ps, 2.0+xc, 14.0+yc, 10.0+xc, 14.0+yc); int i; for (i = -7; i <= +7; i++) { double align = ((i % 2) == 0)*0.5 - ((i % 4) == 0)*0.25; double ticksz = 0.5 + ((i % 2) == 0)*0.5 + ((i % 4) == 0)*1.0; pswr_tick(ps, VER, 1.0+xc, 9.0+0.5*i+yc, ticksz, align); pswr_tick(ps, VER, 11.0+xc, 9.0+0.5*i+yc, ticksz, 1-align); pswr_tick(ps, HOR, 6.0 + 0.5*i+xc, 14.0+yc, ticksz, 1-align); } pswr_curve(ps, 4.0+xc, 4.0+yc, 11.0+xc, 14.0+yc, 1.0+xc, 14.0+yc, 8.0+xc, 4.0+yc ); pswr_dot(ps, 4.0+xc, 4.0+yc, 1.0, FALSE, TRUE); pswr_dot(ps, 11.0+xc, 14.0+yc, 0.5, FALSE, TRUE); pswr_dot(ps, 1.0+xc, 14.0+yc, 0.5, FALSE, TRUE); pswr_dot(ps, 8.0+xc, 4.0+yc, 1.0, FALSE, TRUE); } void DrawFigures(PSStream *ps, double xc, double yc, bool_t fill, bool_t draw, bool_t eo) { /* Usable area [0 _ 12]�[0 _ 15] */ pswr_rectangle(ps, 0.25+xc, 11.75+xc, 0.25+yc, 14.75+yc, FALSE, TRUE); int n = 17; double x[n], y[n]; int i; for (i = 0; i < n; i++) { double t = 2.0*3.1415926*((double)i)/((double)n); double r = (0.75 +0.25*cos(t)); x[i] = xc + 3.0 + 2.0*r*cos(2*t); y[i] = yc + 2.0 + 1.5*r*sin(2*t); } pswr_rectangle(ps, 7.0+xc, 9.0+xc, 1.5+yc, 3.5+yc, fill, draw); pswr_circle(ps, 3.0+xc, 7.0+yc, 2.0, fill, draw); pswr_dot(ps, 3.0+xc, 7.0+yc, 2.0, fill, draw); pswr_lune(ps, 9.0+xc, 7.0+yc, 1.5, 45.0, fill, draw); pswr_slice(ps, 3.0+xc, 12.0+yc, 2.0, 30.0, 135.0, fill, draw); pswr_polygon(ps, x, y, n, fill, draw, eo); pswr_triangle(ps, 7.0+xc, 10.0+yc, 11.0+xc, 12.0+yc, 9.0+xc, 14.0+yc, fill, draw); }