static VALUE rb_gsl_integration_qawo(int argc, VALUE *argv, VALUE obj) { double a, epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; gsl_integration_qawo_table *t = NULL; int status, intervals, itmp, flag = 0, flagt = 0; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc < 2) rb_raise(rb_eArgError, "too few arguments"); CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: if (argc < 1) rb_raise(rb_eArgError, "too few arguments"); Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } Need_Float(argv[itmp]); a = NUM2DBL(argv[itmp]); flagt = get_qawo_table(argv[argc-1], &t); flag = get_epsabs_epsrel_limit_workspace(argc-1, argv, itmp+1, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qawo(F, a, epsabs, epsrel, limit, w, t, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); if (flagt == 1) gsl_integration_qawo_table_free(t); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
ANACalculatorCoplanarTriple::~ANACalculatorCoplanarTriple() { delete[] m_z1; delete[] m_integrand_values; gsl_interp_free (m_interp); gsl_interp_accel_free(m_accel); if(m_qawo_table) gsl_integration_qawo_table_free(m_qawo_table); if(m_workspace) gsl_integration_workspace_free(m_workspace); if(m_cyclic_workspace) gsl_integration_workspace_free(m_cyclic_workspace); }
static VALUE rb_gsl_integration_qawf(int argc, VALUE *argv, VALUE obj) { double a, epsabs = EPSREL_DEFAULT; double result, abserr; size_t limit = LIMIT_DEFAULT; gsl_function *F = NULL; gsl_integration_workspace *w = NULL, *cw = NULL; gsl_integration_qawo_table *t = NULL; int status, intervals, flag = 0, flagt = 0, itmp; VALUE *vtmp; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc < 2) rb_raise(rb_eArgError, "too few arguments"); CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: if (argc < 1) rb_raise(rb_eArgError, "too few arguments"); Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } Need_Float(argv[itmp]); a = NUM2DBL(argv[itmp]); itmp += 1; if (TYPE(argv[itmp]) == T_FLOAT) { epsabs = NUM2DBL(argv[itmp]); itmp += 1; } vtmp = argv + itmp; flagt = get_qawo_table(argv[argc-1], &t); switch (argc - 1 - itmp) { case 0: w = gsl_integration_workspace_alloc(limit); cw = gsl_integration_workspace_alloc(limit); flag = 1; break; case 1: CHECK_FIXNUM(vtmp[0]); limit = FIX2INT(vtmp[0]); w = gsl_integration_workspace_alloc(limit); cw = gsl_integration_workspace_alloc(limit); flag = 1; break; case 2: CHECK_WORKSPACE(vtmp[0]); CHECK_WORKSPACE(vtmp[1]); Data_Get_Struct(vtmp[0], gsl_integration_workspace, w); Data_Get_Struct(vtmp[1], gsl_integration_workspace, cw); flag = 0; break; case 3: CHECK_FIXNUM(vtmp[0]); CHECK_WORKSPACE(vtmp[1]); CHECK_WORKSPACE(vtmp[2]); limit = FIX2INT(vtmp[0]); Data_Get_Struct(vtmp[1], gsl_integration_workspace, w); Data_Get_Struct(vtmp[2], gsl_integration_workspace, cw); flag = 0; break; default: rb_raise(rb_eArgError, "wrong number of arguments"); break; } status = gsl_integration_qawf(F, a, epsabs, limit, w, cw, t, &result, &abserr); intervals = w->size; if (flag == 1) { gsl_integration_workspace_free(w); gsl_integration_workspace_free(cw); } if (flagt == 1) gsl_integration_qawo_table_free(t); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
int main_gsl_quad() { // Na postawie N i K bede ustalal jak wiele moze byc przedzialów, // Ustalilem recznie, na wyczucie. // int DEEP = (int)( log(2.0E7 / N) ); // printf("%d\n", DEEP); int DLIMIT = Pow(2,DEEP); double result1, result2, diff1, diff2; double result3, result4, diff3, diff4; F = gsl_vector_alloc((int)N); // Macierz G jest trojdiagonalna symetryczna G1 = gsl_vector_alloc((int)N); // wiec mozna ja opisac jedynie poprzez 2 G2 = gsl_vector_alloc((int)N-1); // wektory- diagonali i poddiagonali. X = gsl_vector_alloc((int)N); // for (int i = 0; i < N; ++i) gsl_vector_set(G1, i, 2*(i-1.0)/h); for (int i = 0; i < N-1; ++i) gsl_vector_set(G2, i, -(2.0*i+1.0)/2.0/h); workspace = gsl_integration_workspace_alloc(LIMIT); if ( K > 20 ) { DLIMIT = (int) log10(sqrt(5*K))*DLIMIT; DEEP = (int) log2(DLIMIT); } DLIMIT *= 4; DEEP *= 4; table = gsl_integration_qawo_table_alloc(K*PI, h, GSL_INTEG_SINE, DEEP); fun.function = &f2q_sin; // printf("%d %d\n", DEEP, DLIMIT); // Mamy doczynienia z funkcja oscylujaca, uzyjmy wiec specjalnych // kwadratur GSLa, oddzielnie dla sinus oddzielnie dla cosinus, // for (f2qi = 1; f2qi <= N; ++f2qi) { // sinus fisign = 1; if ( f2qi < 2 ) // wartosci na siebie nachodza gsl_integration_qawo(&fun, (f2qi-1)*h, 0.0E0, EPSILON, DLIMIT, workspace, table, &result1, &diff1); else result1 = -result3; fisign = -1; gsl_integration_qawo(&fun, (f2qi )*h, 0.0E0, EPSILON, DLIMIT, workspace, table, &result3, &diff3); gsl_vector_set(F, f2qi-1, result1+result3); // if( f2qi % 1000 == 0 ) { printf("%d \r", f2qi); fflush(stdout); } } gsl_integration_qawo_table_free(table); table = gsl_integration_qawo_table_alloc(K*PI, h, GSL_INTEG_COSINE, DEEP); fun.function = &f2q_cos; for (f2qi = 1; f2qi <= N; ++f2qi) { // cosinus fisign = 1; if ( f2qi < 2 ) // wartosci na siebie nachodza gsl_integration_qawo(&fun, (f2qi-1)*h, 0.0E0, EPSILON, DLIMIT, workspace, table, &result2, &diff2); else result2 = -result4; fisign = -1; gsl_integration_qawo(&fun, (f2qi )*h, 0.0E0, EPSILON, DLIMIT, workspace, table, &result4, &diff4); gsl_vector_set(F, f2qi-1, result1+result3+gsl_vector_get(F, f2qi-1)); // if( f2qi % 1000 == 0 ) { printf("%d \r", f2qi); fflush(stdout); } } gsl_integration_qawo_table_free(table); // Mamy F wiec znajdujemy X (h*), rozwiazujac uklad Gh=F // gdzie G symetryczna trojdiagonalna, // // fprintf(stderr,"2 quad done.\n"); gsl_linalg_solve_symm_tridiag(G1,G2,F,X); // for (int i = 0; i < N; ++i) // fprintf(stderr,"h[%d] = %.15e\n",i,gsl_vector_get(X,i)); fprintf(stderr,"2 linalg done.\n"); return 0; }
gsl_complex integrate_line_segment(Params *params, gsl_complex p0, gsl_complex p1) { gsl_complex k = gsl_complex_sub(p1, p0); const double r = params->r; const double a = 0.0; // parameter interval start const double b = 1.0; // parameter interval end const double L = b - a; // length of parameter interval const size_t table_size = 1000; // calculate frequency of oscillatory part double omega = GSL_REAL(k) * r; gsl_integration_workspace *ws = gsl_integration_workspace_alloc(table_size); // prepare sine/cosine tables for integration gsl_integration_qawo_table *table_cos = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_COSINE, table_size); gsl_integration_qawo_table *table_sin = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_SINE, table_size); LineSegmentParams lsp; lsp.p0 = p0; lsp.k = k; lsp.damping = params->r * GSL_IMAG(k); lsp.params = params; //fprintf(stderr, "p0 = %g %g, p1 = %g %g, k = %g %g, r = %g, omega = %g, damping = %g\n", // GSL_REAL(p0), GSL_IMAG(p0), GSL_REAL(p1), GSL_IMAG(p1), // GSL_REAL(k), GSL_IMAG(k), r, omega, lsp.damping); gsl_function F; F.function = &line_segment_integrand_wrapper; F.params = &lsp; double result_real_cos, abserr_real_cos; double result_real_sin, abserr_real_sin; double result_imag_cos, abserr_imag_cos; double result_imag_sin, abserr_imag_sin; double epsabs = 1e-9; double epsrel = 1e-9; lsp.part = REAL; gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_real_cos, &abserr_real_cos); gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_real_sin, &abserr_real_sin); lsp.part = IMAG; gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_imag_cos, &abserr_imag_cos); gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_imag_sin, &abserr_imag_sin); //fprintf(stderr, " cos: %g (+- %g) %g (+- %g) sin: %g (+- %g) %g (+- %g)\n", // result_real_cos, abserr_real_cos, result_imag_cos, abserr_imag_cos, // result_real_sin, abserr_real_sin, result_imag_sin, abserr_imag_sin); gsl_complex cos_part = gsl_complex_rect(result_real_cos, result_imag_cos); gsl_complex sin_part = gsl_complex_rect(-result_imag_sin, result_real_sin); gsl_complex sum = gsl_complex_add(cos_part, sin_part); gsl_complex result = gsl_complex_mul( k, gsl_complex_mul(sum, gsl_complex_exp(gsl_complex_mul_imag(p0, params->r)))); gsl_integration_qawo_table_free(table_sin); gsl_integration_qawo_table_free(table_cos); gsl_integration_workspace_free(ws); return result; }