folgen_vektor_p folgen_vektor_add(folgen_vektor_p f, folgen_vektor_p g) { folgen_vektor_p back; int k, d, size, dim, a, b, test_f, test_g; vec_p max, vec_1, n, n_f, n_g, r; ASSERT( f->grad->dim == g->grad->dim ); dim = f->grad->dim; max = vec_max( f->grad, g->grad ); vec_1 = vec_one( dim ); n = vec_add( vec_1, max ); n_f = vec_add( vec_1, f->grad ); n_g = vec_add( vec_1, g->grad ); size = vec_size( n ); back = folgen_vektor_new( max ); for(k=0;k<size;k++) { r = entry_one2d( k, n ); test_f = 0; test_g = 0; for(d=0;d<dim;d++) { if( r->array[d] > f->grad->array[d] ) { test_f = test_f + 1; } if( r->array[d] > g->grad->array[d] ) { test_g = test_g + 1; } } if( (test_f == 0) && (test_g == 0) ) { a = entry_d2one( r, n_f ); b = entry_d2one( r, n_g ); folge_del( back->vektor[k] ); back->vektor[k] = folge_add( f->vektor[a], g->vektor[b] ); } if( (test_f != 0) && (test_g == 0) ) { b = entry_d2one( r, n_g ); folge_del( back->vektor[k] ); back->vektor[k] = folge_copy( g->vektor[b] ); } if( (test_f == 0) && (test_g != 0) ) { a = entry_d2one( r, n_f ); folge_del( back->vektor[k] ); back->vektor[k] = folge_copy( f->vektor[a] ); } vec_del( r ); } vec_del( n ); vec_del( n_f ); vec_del( n_g ); vec_del( vec_1 ); return back; }
folgen_vektor_p folgen_vektor_faltung(folgen_vektor_p f, folgen_matrix_p Gamma) { folgen_vektor_p back; vec_p vec_1, n_1, n_2, grad_1, grad_2, r, s; int k, j, a, b; int size_1, size_2, dim; folge_p temp, temp1, sum; ASSERT( f->grad->dim == Gamma->grad1->dim ); dim = f->grad->dim; vec_1 = vec_one(dim); grad_2 = vec_min( f->grad, Gamma->grad2 ); n_2 = vec_add( grad_2, vec_1 ); size_2 = vec_size( n_2 ); grad_1 = vec_copy( Gamma->grad1 ); n_1 = vec_add( grad_1, vec_1 ); size_1 = vec_size( n_1 ); back = folgen_vektor_new( grad_1 ); for(k=0;k<size_1;k++) { sum = folge_new( vec_new(dim), vec_new(dim) ); for(j=0;j<size_2;j++) { r = entry_one2d( j, n_2 ); s = vec_add( f->grad, vec_1 ); a = entry_d2one( r, s ); vec_del( s ); s = vec_add( Gamma->grad2, vec_1 ); b = entry_d2one( r, s ); vec_del( s ); vec_del( r ); temp = folge_faltung( f->vektor[a], Gamma->matrix[k][b] ); temp1 = folge_add( sum, temp ); folge_del( temp ); folge_del( sum ); sum = temp1; } folge_del( back->vektor[k] ); back->vektor[k] = sum; } vec_del( n_1 ); vec_del( n_2 ); vec_del( grad_2 ); vec_del( vec_1 ); return back; }
folge_p folge_add(folge_p f, folge_p g) { folge_p back; int size, k, size_g, size_f; fepc_real_t x, y; vec_p temp1, temp2, max, lang, min, r; size_f = vec_size( f->lang ); size_g = vec_size( g->lang ); if(size_f == 0) { back = folge_copy( g ); return back; } if(size_g == 0) { back = folge_copy( f ); return back; } if( (size_g!=0) && (size_f!=0) ) { min = vec_min( f->start, g->start ); temp1 = vec_add( f->start, f->lang ); temp2 = vec_add( g->start, g->lang ); max = vec_max( temp1, temp2 ); vec_del( temp1 ); vec_del( temp2 ); lang = vec_op( 1, max, -1, min); vec_del( max ); back = folge_new( min, lang ); size = vec_size( lang ); for(k=0;k<size;k++) { temp1 = entry_one2d( k, lang ); r = vec_add( min, temp1 ); vec_del( temp1 ); x = folge_glied( r, f ); y = folge_glied( r, g ); vec_del( r ); back->glied[k] = x + y; } return back; } }
folgen_vektor_p folgen_vektor_projekt(folgen_vektor_p f,folgen_vektor_p g) { folgen_vektor_p back; int k, size_g, test, dim, d, i; vec_p grad, r, n_f, n_g, start, lang, vec_1; ASSERT( f->grad->dim == g->grad->dim ); dim = f->grad->dim; vec_1 = vec_one( dim ); n_g = vec_add( g->grad, vec_1 ); n_f = vec_add( f->grad, vec_1 ); size_g = vec_size( n_g ); grad = vec_copy( g->grad ); back = folgen_vektor_new( grad ); for(k=0;k<size_g;k++) { r = entry_one2d( k, n_g ); test = 0; for(d=0;d<dim;d++) { if( r->array[d] > f->grad->array[d] ) { test = test + 1; } } if(test == 0) { i = entry_d2one( r, n_f ); folge_del( back->vektor[k] ); back->vektor[k] = folge_projekt( f->vektor[i], g->vektor[k] ); } else { folge_del( back->vektor[k] ); start = vec_copy( g->vektor[k]->start ); lang = vec_copy( g->vektor[k]->lang ); back->vektor[k] = folge_new( start, lang ); } vec_del( r ); } vec_del( vec_1 ); vec_del( n_g ); vec_del( n_f ); return back; }
folge_p folge_projekt(folge_p f, folge_p g) { folge_p back; int k, size; vec_p r, start, lang, temp; ASSERT( f->start->dim == g->start->dim ); start = vec_copy( g->start ); lang = vec_copy( g->lang ); back = folge_new( start, lang ); size = vec_size( lang ); for(k=0;k<size;k++) { temp = entry_one2d( k, lang ); r = vec_add( temp, start ); vec_del( temp ); back->glied[k] = folge_glied( r, f ); vec_del( r ); } return back; }
fepc_real_t folge_norm(folge_p f, folge_p g) { vec_p temp, temp1, temp2, min, max, lang, vec_1; int k, dim, size; fepc_real_t norm, diff; ASSERT(f->start->dim == g->start->dim); dim = f->start->dim; vec_1 = vec_one( dim ); min = vec_min( f->start, g->start ); temp1 = vec_add( f->start, f->lang ); temp2 = vec_add( g->start, g->lang ); temp = vec_max( temp1, temp2 ); vec_del( temp1 ); vec_del( temp2 ); lang = vec_op( 1, temp, -1, min ); vec_del( temp ); size = vec_size( lang ); norm = 0.0; for(k=0;k<size;k++) { temp = entry_one2d( k, lang ); temp1 = vec_add( temp, min ); diff = folge_glied( temp1, f ) - folge_glied( temp1, g ); norm = norm + ( diff * diff ); vec_del( temp ); vec_del( temp1 ); } vec_del( vec_1 ); vec_del( min ); vec_del( lang ); norm = sqrt(norm); return norm; }
folge_p folge_slow_faltung(folge_p f,folge_p g) { folge_p back; int k, l, i, test, wert; int size_f, size_g, size_w, dim; vec_p n_f, n_g, n_w, w_start; vec_p r, s, temp; fepc_real_t *f_glied, *g_glied, *w_glied; fepc_real_t sum; /*Testen auf Konsistenz*/ ASSERT(f->start->dim == f->lang->dim); ASSERT(g->start->dim == g->lang->dim); ASSERT(g->start->dim == f->start->dim); dim = g->start->dim; n_f = f->lang; size_f = vec_size( n_f ); n_g = g->lang; size_g = vec_size( n_g ); for(k=0;k<dim;k++) { ASSERT( f->lang->array[k] >= 0 ); ASSERT( g->lang->array[k] >= 0 ); } /*Rueckgabe einer leeren Folge, falls f oder g leere Folgen sind*/ if ( (size_f == 0) || (size_g == 0) ) { r = vec_new(dim); s = vec_new(dim); back = folge_new( r, s ); return back; } /*Berechnungen*/ n_w = vec_new(dim); for(k=0;k<dim;k++) { n_w->array[k] = n_f->array[k]+n_g->array[k]-1; } f_glied = f->glied; g_glied = g->glied; /*Initialisierung der Faltung*/ w_start = vec_add( f->start, g->start ); back = folge_new(w_start , n_w); w_glied = back->glied; size_w = vec_size( n_w ); /*Berechnung der Faltung*/ for(k=0;k<size_w;k++) { sum = 0; r = entry_one2d(k, n_w); for(l=0;l<size_f;l++) { s = entry_one2d(l,n_f); temp = vec_op( 1, r, -1, s); test = 0; for(i = 0;i<dim;i++) { if ( (temp->array[i]<0) || (temp->array[i]>=n_g->array[i]) ) { test = test + 1; } } if (test == 0) { wert = entry_d2one( temp, n_g ); sum = sum + f_glied[l] * g_glied[wert]; } vec_del(s); vec_del(temp); } w_glied[k] = sum; vec_del(r); } return back; }
folgen_matrix_p folgen_matrix_add(folgen_matrix_p f, folgen_matrix_p g) { folgen_matrix_p back; int k, j, d, size1, size2, dim; int a1, a2, b1, b2; int test_f, test_g, test_f1, test_g1, test_f2, test_g2; vec_p grad1, grad2, vec_1, n1, n2; vec_p n_f1, n_g1, n_f2, n_g2, r1, r2; ASSERT( f->grad1->dim == g->grad1->dim ); dim = f->grad1->dim; grad1 = vec_max( f->grad1, g->grad1 ); grad2 = vec_max( f->grad2, g->grad2 ); vec_1 = vec_one( dim ); n1 = vec_add( vec_1, grad1 ); n2 = vec_add( vec_1, grad2 ); n_f1 = vec_add( vec_1, f->grad1 ); n_g1 = vec_add( vec_1, g->grad1 ); n_f2 = vec_add( vec_1, f->grad2 ); n_g2 = vec_add( vec_1, g->grad2 ); size1 = vec_size( n1 ); size2 = vec_size( n2 ); back = folgen_matrix_new( grad1, grad2 ); for(k=0;k<size1;k++) { r1 = entry_one2d( k, n1 ); test_f1 = 0; test_g1 = 0; for(d=0;d<dim;d++) { if( r1->array[d] > f->grad1->array[d] ) { test_f1 = test_f1 + 1; } if( r1->array[d] > g->grad1->array[d] ) { test_g1 = test_g1 + 1; } } for(j=0;j<size2;j++) { r2 = entry_one2d( j, n2 ); test_f2 = 0; test_g2 = 0; for(d=0;d<dim;d++) { if( r2->array[d] > f->grad2->array[d] ) { test_f2 = test_f2 + 1; } if( r2->array[d] > g->grad2->array[d] ) { test_g2 = test_g2 + 1; } } test_g = test_g1 + test_g2; test_f = test_f1 + test_f2; if( (test_f == 0) && (test_g == 0) ) { a1 = entry_d2one( r1, n_f1 ); a2 = entry_d2one( r2, n_f2 ); b1 = entry_d2one( r1, n_g1 ); b2 = entry_d2one( r2, n_g2 ); folge_del( back->matrix[k][j] ); back->matrix[k][j] = folge_add( f->matrix[a1][a2], g->matrix[b1][b2] ); } if( (test_f != 0) && (test_g == 0) ) { b1 = entry_d2one( r1, n_g1 ); b2 = entry_d2one( r2, n_g2 ); folge_del( back->matrix[k][j] ); back->matrix[k][j] = folge_copy( g->matrix[b1][b2] ); } if( (test_f == 0) && (test_g != 0) ) { a1 = entry_d2one( r1, n_f1 ); a2 = entry_d2one( r2, n_f2 ); folge_del( back->matrix[k][j] ); back->matrix[k][j] = folge_copy( g->matrix[a1][a2] ); } vec_del( r2 ); } vec_del( r1 ); } vec_del( n1 ); vec_del( n2 ); vec_del( n_f1 ); vec_del( n_g1 ); vec_del( n_f2 ); vec_del( n_g2 ); vec_del( vec_1 ); return back; }
fepc_real_t folgen_vektor_norm(folgen_vektor_p f, folgen_vektor_p g) { vec_p max, temp, temp1, temp2, r, vec_1; int k, size, test_f, test_g; int i, j, d, dim; folge_p temp_folge; fepc_real_t wert, norm; ASSERT( f->grad->dim == g->grad->dim ); dim = f->grad->dim; vec_1 = vec_one(dim); temp = vec_max( f->grad, g->grad ); max = vec_add( temp, vec_1 ); vec_del(temp); size = vec_size( max ); norm = 0.0; for(k=0;k<size;k++) { r = entry_one2d( k, max ); /*Test ob Folge von f den Grad r besitzt*/ test_f = 0; for(d=0;d<dim;d++) { if (( r->array[d] ) > ( f->grad->array[d] )) { test_f = test_f + 1; } } /*Test ob Folge von g den Grad r besitzt*/ test_g = 0; for(d=0;d<dim;d++) { if (( r->array[d] ) > ( g->grad->array[d] )) { test_g = test_g + 1; } } /*Berechnung der Norm*/ if( (test_f==0) && (test_g==0) ) { temp = vec_add(f->grad, vec_1); i = entry_d2one( r, temp); vec_del(temp); temp = vec_add(g->grad, vec_1); j = entry_d2one( r, temp); vec_del(temp); wert = folge_norm(f->vektor[i],g->vektor[j]); norm = norm + wert; } if( (test_f==0) && (test_g>0) ) { temp = vec_add(f->grad, vec_1); i = entry_d2one( r, temp); vec_del(temp); temp1 = vec_new(dim); temp2 = vec_new(dim); temp_folge = folge_new( temp1, temp2 ); wert = folge_norm(f->vektor[i],temp_folge); norm = norm + wert; folge_del(temp_folge); } if( (test_f>0) && (test_g==0) ) { temp = vec_add(g->grad, vec_1); j = entry_d2one( r, temp); vec_del(temp); temp1 = vec_new(dim); temp2 = vec_new(dim); temp_folge = folge_new( temp1, temp2 ); wert = folge_norm(g->vektor[j],temp_folge); norm = norm + wert; folge_del(temp_folge); } vec_del( r ); } vec_del(vec_1); vec_del(max); return norm; }
/******************************************************* * * globale Funktionen * *******************************************************/ fepc_real_t* fft_faltung(fepc_real_t* a, vec_p n_a, fepc_real_t* b, vec_p n_b) { int size_a, size_b, size_c, dim; int k, i, wert, test; int *n; vec_p temp, n_c; fepc_real_t *c; fftw_complex *in, *out_a, *out_b; double *out, *in_a, *in_b; fftw_plan p; /*Auf Testen von Konsistenz wird verzichtet, da Input bereits auf Konsistenz getestet*/ /*Faltung ueber Fouriertrafo (Theorie ist in Dokumentation zu finden)*/ dim = n_a->dim; n_c = vec_new(dim); for(k=0;k<dim;k++) { n_c->array[k] = n_a->array[k]+n_b->array[k]-1; } n = n_c->array; size_a = vec_size( n_a ); size_b = vec_size( n_b ); size_c = vec_size( n_c ); /*Initialisieren des Ergebnis Array*/ c = (fepc_real_t*) malloc(sizeof(fepc_real_t) * size_c); /*Berechnen der Fouriertrafo von in_a*/ in_a = (double*) fftw_malloc(sizeof(double) * size_c); out_a = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); for (k=0;k<size_c;k++) { temp = entry_one2d(k,n_c); test = 0; for(i=0;i<dim;i++) { if ((temp->array[i] <0)||(temp->array[i]>=n_a->array[i])) { test = test + 1; } } if (test == 0) { wert = entry_d2one(temp,n_a); in_a[k] = a[wert]; } else { in_a[k] = 0; } vec_del(temp); } p = fftw_plan_dft_r2c(dim,n,in_a,out_a,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); /*Berechnen der Fouriertrafo von in_b*/ in_b = (double*) fftw_malloc(sizeof(double) * size_c); out_b = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); for (k=0;k<size_c;k++) { temp = entry_one2d(k,n_c); test = 0; for(i=0;i<dim;i++) { if ((temp->array[i] <0)||(temp->array[i]>=n_b->array[i])) { test = test + 1; } } if (test == 0) { wert = entry_d2one(temp,n_b); in_b[k] = b[wert]; } else { in_b[k] = 0; } vec_del(temp); } p = fftw_plan_dft_r2c(dim,n,in_b,out_b,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); out = (double*) fftw_malloc(sizeof(double) * size_c); for (k=0;k<size_c;k++) { in[k][0] = out_a[k][0]*out_b[k][0] - out_a[k][1]*out_b[k][1]; in[k][1] = out_a[k][1]*out_b[k][0] + out_a[k][0]*out_b[k][1]; } /*Berechnung der Inversen Fouriertrafo von in*/ p = fftw_plan_dft_c2r(dim,n,in,out,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); for (k=0;k<size_c;k++) { c[k] = (fepc_real_t) out[k]/size_c; } vec_del(n_c); fftw_free(in); free(in_a); free(in_b); free(out); fftw_free(out_a); fftw_free(out_b); return c; }