numo-gsl-integration 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -6
- data/README.md +19 -24
- data/docs/error-handling.md +8 -14
- data/docs/routines.md +318 -214
- data/ext/numo/gsl/integration/callback.c +3 -4
- data/ext/numo/gsl/integration/cquad.c +1 -0
- data/ext/numo/gsl/integration/fixed.c +163 -0
- data/ext/numo/gsl/integration/glfixed.c +14 -3
- data/ext/numo/gsl/integration/integration.c +12 -0
- data/ext/numo/gsl/integration/integration_internal.h +3 -1
- data/ext/numo/gsl/integration/qagi.c +1 -0
- data/ext/numo/gsl/integration/qagil.c +8 -0
- data/ext/numo/gsl/integration/qagiu.c +8 -0
- data/ext/numo/gsl/integration/qagp.c +21 -9
- data/ext/numo/gsl/integration/qags.c +1 -0
- data/ext/numo/gsl/integration/qawc.c +8 -0
- data/ext/numo/gsl/integration/qawf.c +3 -0
- data/ext/numo/gsl/integration/qawo.c +3 -0
- data/ext/numo/gsl/integration/qaws.c +6 -0
- data/ext/numo/gsl/integration/romberg.c +1 -0
- data/lib/numo/gsl/integration/version.rb +1 -1
- data/lib/numo/gsl/integration.rb +0 -12
- data/sig/numo/gsl/integration.rbs +8 -18
- data/sig/numo/gsl.rbs +1 -1
- metadata +3 -22
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#include "integration_internal.h"
|
|
2
|
+
typedef struct {
|
|
3
|
+
gsl_function *function;
|
|
4
|
+
const gsl_integration_fixed_type *type;
|
|
5
|
+
size_t order;
|
|
6
|
+
double a;
|
|
7
|
+
double b;
|
|
8
|
+
double alpha;
|
|
9
|
+
double beta;
|
|
10
|
+
gsl_integration_fixed_workspace *workspace;
|
|
11
|
+
double *result;
|
|
12
|
+
} integration_fixed_params;
|
|
13
|
+
static const gsl_integration_fixed_type *integration_fixed_type(VALUE type) {
|
|
14
|
+
ID type_id;
|
|
15
|
+
if (!RB_TYPE_P(type, T_SYMBOL)) {
|
|
16
|
+
rb_raise(rb_eTypeError, "type must be a Symbol");
|
|
17
|
+
}
|
|
18
|
+
type_id = SYM2ID(type);
|
|
19
|
+
if (type_id == rb_intern("legendre")) {
|
|
20
|
+
return gsl_integration_fixed_legendre;
|
|
21
|
+
}
|
|
22
|
+
if (type_id == rb_intern("chebyshev")) {
|
|
23
|
+
return gsl_integration_fixed_chebyshev;
|
|
24
|
+
}
|
|
25
|
+
if (type_id == rb_intern("chebyshev2")) {
|
|
26
|
+
return gsl_integration_fixed_chebyshev2;
|
|
27
|
+
}
|
|
28
|
+
if (type_id == rb_intern("gegenbauer")) {
|
|
29
|
+
return gsl_integration_fixed_gegenbauer;
|
|
30
|
+
}
|
|
31
|
+
if (type_id == rb_intern("jacobi")) {
|
|
32
|
+
return gsl_integration_fixed_jacobi;
|
|
33
|
+
}
|
|
34
|
+
if (type_id == rb_intern("laguerre")) {
|
|
35
|
+
return gsl_integration_fixed_laguerre;
|
|
36
|
+
}
|
|
37
|
+
if (type_id == rb_intern("hermite")) {
|
|
38
|
+
return gsl_integration_fixed_hermite;
|
|
39
|
+
}
|
|
40
|
+
if (type_id == rb_intern("exponential")) {
|
|
41
|
+
return gsl_integration_fixed_exponential;
|
|
42
|
+
}
|
|
43
|
+
if (type_id == rb_intern("rational")) {
|
|
44
|
+
return gsl_integration_fixed_rational;
|
|
45
|
+
}
|
|
46
|
+
rb_raise(rb_eArgError, "unsupported fixed quadrature type: %s",
|
|
47
|
+
rb_id2name(type_id));
|
|
48
|
+
}
|
|
49
|
+
static VALUE integration_free_fixed_workspace(VALUE data) {
|
|
50
|
+
integration_fixed_params *params = (integration_fixed_params *)data;
|
|
51
|
+
if (params->workspace != NULL) {
|
|
52
|
+
gsl_integration_fixed_free(params->workspace);
|
|
53
|
+
}
|
|
54
|
+
return Qnil;
|
|
55
|
+
}
|
|
56
|
+
static VALUE integration_run_fixed(VALUE data) {
|
|
57
|
+
integration_fixed_params *params = (integration_fixed_params *)data;
|
|
58
|
+
params->workspace =
|
|
59
|
+
gsl_integration_fixed_alloc(params->type, params->order, params->a,
|
|
60
|
+
params->b, params->alpha, params->beta);
|
|
61
|
+
if (params->workspace == NULL) {
|
|
62
|
+
rb_memerror();
|
|
63
|
+
}
|
|
64
|
+
(void)gsl_integration_fixed(params->function, params->result,
|
|
65
|
+
params->workspace);
|
|
66
|
+
return Qnil;
|
|
67
|
+
}
|
|
68
|
+
static VALUE integration_run_fixed_with_workspace(VALUE data) {
|
|
69
|
+
return rb_ensure(integration_run_fixed, data,
|
|
70
|
+
integration_free_fixed_workspace, data);
|
|
71
|
+
}
|
|
72
|
+
VALUE integration_fixed(int argc, VALUE *argv, VALUE self) {
|
|
73
|
+
VALUE type;
|
|
74
|
+
VALUE options;
|
|
75
|
+
ID keywords[] = {rb_intern("order"), rb_intern("a"), rb_intern("b"),
|
|
76
|
+
rb_intern("alpha"), rb_intern("beta")};
|
|
77
|
+
VALUE keyword_values[5];
|
|
78
|
+
VALUE order_value;
|
|
79
|
+
VALUE alpha_value;
|
|
80
|
+
VALUE beta_value;
|
|
81
|
+
size_t order;
|
|
82
|
+
gsl_function function;
|
|
83
|
+
integration_callback_params params;
|
|
84
|
+
integration_fixed_params fixed_params;
|
|
85
|
+
double result;
|
|
86
|
+
int state = 0;
|
|
87
|
+
(void)self;
|
|
88
|
+
rb_scan_args(argc, argv, "1:", &type, &options);
|
|
89
|
+
fixed_params.type = integration_fixed_type(type);
|
|
90
|
+
if (NIL_P(options)) {
|
|
91
|
+
options = rb_hash_new();
|
|
92
|
+
}
|
|
93
|
+
rb_get_kwargs(options, keywords, 3, 2, keyword_values);
|
|
94
|
+
order_value = keyword_values[0];
|
|
95
|
+
alpha_value = keyword_values[3];
|
|
96
|
+
beta_value = keyword_values[4];
|
|
97
|
+
if (!RB_INTEGER_TYPE_P(order_value)) {
|
|
98
|
+
rb_raise(rb_eTypeError, "order must be an Integer");
|
|
99
|
+
}
|
|
100
|
+
if (RTEST(rb_funcall(order_value, rb_intern("<="), 1, INT2FIX(0)))) {
|
|
101
|
+
rb_raise(rb_eArgError, "order must be positive");
|
|
102
|
+
}
|
|
103
|
+
order = NUM2SIZET(order_value);
|
|
104
|
+
integration_function_init(&function, ¶ms);
|
|
105
|
+
fixed_params.function = &function;
|
|
106
|
+
fixed_params.order = order;
|
|
107
|
+
fixed_params.a = NUM2DBL(keyword_values[1]);
|
|
108
|
+
fixed_params.b = NUM2DBL(keyword_values[2]);
|
|
109
|
+
if (fixed_params.type == gsl_integration_fixed_gegenbauer) {
|
|
110
|
+
if (alpha_value == Qundef) {
|
|
111
|
+
rb_raise(rb_eArgError, "alpha is required for gegenbauer");
|
|
112
|
+
}
|
|
113
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
114
|
+
fixed_params.beta = 0.0;
|
|
115
|
+
} else if (fixed_params.type == gsl_integration_fixed_jacobi) {
|
|
116
|
+
if (alpha_value == Qundef) {
|
|
117
|
+
rb_raise(rb_eArgError, "alpha is required for jacobi");
|
|
118
|
+
}
|
|
119
|
+
if (beta_value == Qundef) {
|
|
120
|
+
rb_raise(rb_eArgError, "beta is required for jacobi");
|
|
121
|
+
}
|
|
122
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
123
|
+
fixed_params.beta = NUM2DBL(beta_value);
|
|
124
|
+
} else if (fixed_params.type == gsl_integration_fixed_laguerre) {
|
|
125
|
+
if (alpha_value == Qundef) {
|
|
126
|
+
rb_raise(rb_eArgError, "alpha is required for laguerre");
|
|
127
|
+
}
|
|
128
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
129
|
+
fixed_params.beta = 0.0;
|
|
130
|
+
} else if (fixed_params.type == gsl_integration_fixed_hermite) {
|
|
131
|
+
if (alpha_value == Qundef) {
|
|
132
|
+
rb_raise(rb_eArgError, "alpha is required for hermite");
|
|
133
|
+
}
|
|
134
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
135
|
+
fixed_params.beta = 0.0;
|
|
136
|
+
} else if (fixed_params.type == gsl_integration_fixed_exponential) {
|
|
137
|
+
if (alpha_value == Qundef) {
|
|
138
|
+
rb_raise(rb_eArgError, "alpha is required for exponential");
|
|
139
|
+
}
|
|
140
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
141
|
+
fixed_params.beta = 0.0;
|
|
142
|
+
} else if (fixed_params.type == gsl_integration_fixed_rational) {
|
|
143
|
+
if (alpha_value == Qundef) {
|
|
144
|
+
rb_raise(rb_eArgError, "alpha is required for rational");
|
|
145
|
+
}
|
|
146
|
+
if (beta_value == Qundef) {
|
|
147
|
+
rb_raise(rb_eArgError, "beta is required for rational");
|
|
148
|
+
}
|
|
149
|
+
fixed_params.alpha = NUM2DBL(alpha_value);
|
|
150
|
+
fixed_params.beta = NUM2DBL(beta_value);
|
|
151
|
+
} else {
|
|
152
|
+
fixed_params.alpha = 0.0;
|
|
153
|
+
fixed_params.beta = 0.0;
|
|
154
|
+
}
|
|
155
|
+
fixed_params.workspace = NULL;
|
|
156
|
+
fixed_params.result = &result;
|
|
157
|
+
rb_protect(integration_run_fixed_with_workspace, (VALUE)&fixed_params,
|
|
158
|
+
&state);
|
|
159
|
+
RB_GC_GUARD(params.block);
|
|
160
|
+
RB_GC_GUARD(params.exception);
|
|
161
|
+
integration_finish_callback(¶ms, state);
|
|
162
|
+
return DBL2NUM(result);
|
|
163
|
+
}
|
|
@@ -48,9 +48,18 @@ VALUE integration_glfixed(int argc, VALUE *argv, VALUE self) {
|
|
|
48
48
|
order_value = keyword_values[0];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
if (order_value == Qundef) {
|
|
52
|
+
order = 10;
|
|
53
|
+
} else {
|
|
54
|
+
if (!RB_INTEGER_TYPE_P(order_value)) {
|
|
55
|
+
rb_raise(rb_eTypeError, "order must be an Integer");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (RTEST(rb_funcall(order_value, rb_intern("<="), 1, INT2FIX(0)))) {
|
|
59
|
+
rb_raise(rb_eArgError, "order must be positive");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
order = NUM2SIZET(order_value);
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
integration_function_init(&function, ¶ms);
|
|
@@ -59,7 +68,9 @@ VALUE integration_glfixed(int argc, VALUE *argv, VALUE self) {
|
|
|
59
68
|
glfixed_params.a = NUM2DBL(a);
|
|
60
69
|
glfixed_params.b = NUM2DBL(b);
|
|
61
70
|
glfixed_params.order = order;
|
|
71
|
+
|
|
62
72
|
glfixed_params.table = gsl_integration_glfixed_table_alloc(order);
|
|
73
|
+
|
|
63
74
|
glfixed_params.result = &result;
|
|
64
75
|
|
|
65
76
|
rb_protect(integration_run_glfixed_with_table, (VALUE)&glfixed_params,
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#include "integration_internal.h"
|
|
2
2
|
|
|
3
|
+
static VALUE numo_eGslError;
|
|
4
|
+
|
|
5
|
+
static _Noreturn void integration_gsl_error_handler(const char *reason,
|
|
6
|
+
const char *file, int line,
|
|
7
|
+
int gsl_errno) {
|
|
8
|
+
rb_raise(numo_eGslError, "%s:%d: %s (GSL error %d)", file, line, reason,
|
|
9
|
+
gsl_errno);
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
void Init_integration(void) {
|
|
4
13
|
VALUE mNumo;
|
|
5
14
|
VALUE mGSL;
|
|
@@ -8,6 +17,8 @@ void Init_integration(void) {
|
|
|
8
17
|
mNumo = rb_define_module("Numo");
|
|
9
18
|
mGSL = rb_define_module_under(mNumo, "GSL");
|
|
10
19
|
mIntegration = rb_define_module_under(mGSL, "Integration");
|
|
20
|
+
numo_eGslError = rb_define_class_under(mGSL, "GslError", rb_eStandardError);
|
|
21
|
+
gsl_set_error_handler(&integration_gsl_error_handler);
|
|
11
22
|
|
|
12
23
|
rb_define_const(mIntegration, "GAUSS15", INT2NUM(GSL_INTEG_GAUSS15));
|
|
13
24
|
rb_define_const(mIntegration, "GAUSS21", INT2NUM(GSL_INTEG_GAUSS21));
|
|
@@ -32,4 +43,5 @@ void Init_integration(void) {
|
|
|
32
43
|
rb_define_singleton_method(mIntegration, "cquad", integration_cquad, -1);
|
|
33
44
|
rb_define_singleton_method(mIntegration, "romberg", integration_romberg, -1);
|
|
34
45
|
rb_define_singleton_method(mIntegration, "glfixed", integration_glfixed, -1);
|
|
46
|
+
rb_define_singleton_method(mIntegration, "fixed", integration_fixed, -1);
|
|
35
47
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#ifndef NUMO_GSL_INTEGRATION_INTERNAL_H
|
|
2
2
|
#define NUMO_GSL_INTEGRATION_INTERNAL_H
|
|
3
3
|
|
|
4
|
+
#include <gsl/gsl_errno.h>
|
|
4
5
|
#include <gsl/gsl_integration.h>
|
|
5
6
|
#include <ruby.h>
|
|
6
7
|
|
|
@@ -28,7 +29,7 @@ double integration_callback(double x, void *data);
|
|
|
28
29
|
void integration_raise_callback_exception(integration_callback_params *params);
|
|
29
30
|
void integration_finish_callback(integration_callback_params *params,
|
|
30
31
|
int state);
|
|
31
|
-
|
|
32
|
+
|
|
32
33
|
VALUE integration_free_workspace(VALUE data);
|
|
33
34
|
VALUE integration_free_cquad_workspace(VALUE data);
|
|
34
35
|
VALUE integration_free_romberg_workspace(VALUE data);
|
|
@@ -48,5 +49,6 @@ VALUE integration_qawf(int argc, VALUE *argv, VALUE self);
|
|
|
48
49
|
VALUE integration_cquad(int argc, VALUE *argv, VALUE self);
|
|
49
50
|
VALUE integration_romberg(int argc, VALUE *argv, VALUE self);
|
|
50
51
|
VALUE integration_glfixed(int argc, VALUE *argv, VALUE self);
|
|
52
|
+
VALUE integration_fixed(int argc, VALUE *argv, VALUE self);
|
|
51
53
|
|
|
52
54
|
#endif
|
|
@@ -46,6 +46,7 @@ VALUE integration_qagi(int argc, VALUE *argv, VALUE self) {
|
|
|
46
46
|
rb_scan_args(argc, argv, "0:", &options);
|
|
47
47
|
|
|
48
48
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
49
|
+
|
|
49
50
|
epsabs = parsed_options.epsabs;
|
|
50
51
|
epsrel = parsed_options.epsrel;
|
|
51
52
|
limit = parsed_options.limit;
|
|
@@ -13,14 +13,17 @@ typedef struct {
|
|
|
13
13
|
|
|
14
14
|
static VALUE integration_run_qagil(VALUE data) {
|
|
15
15
|
integration_qagil_params *params = (integration_qagil_params *)data;
|
|
16
|
+
|
|
16
17
|
(void)gsl_integration_qagil(params->function, params->b, params->epsabs,
|
|
17
18
|
params->epsrel, params->limit, params->workspace,
|
|
18
19
|
params->result, params->error);
|
|
20
|
+
|
|
19
21
|
return Qnil;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
static VALUE integration_run_qagil_with_workspace(VALUE data) {
|
|
23
25
|
integration_qagil_params *params = (integration_qagil_params *)data;
|
|
26
|
+
|
|
24
27
|
return rb_ensure(integration_run_qagil, data, integration_free_workspace,
|
|
25
28
|
(VALUE)params->workspace);
|
|
26
29
|
}
|
|
@@ -39,11 +42,13 @@ VALUE integration_qagil(int argc, VALUE *argv, VALUE self) {
|
|
|
39
42
|
double result;
|
|
40
43
|
double error;
|
|
41
44
|
int state = 0;
|
|
45
|
+
|
|
42
46
|
(void)self;
|
|
43
47
|
|
|
44
48
|
rb_scan_args(argc, argv, "1:", &b, &options);
|
|
45
49
|
|
|
46
50
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
51
|
+
|
|
47
52
|
epsabs = parsed_options.epsabs;
|
|
48
53
|
epsrel = parsed_options.epsrel;
|
|
49
54
|
limit = parsed_options.limit;
|
|
@@ -51,6 +56,7 @@ VALUE integration_qagil(int argc, VALUE *argv, VALUE self) {
|
|
|
51
56
|
integration_function_init(&function, ¶ms);
|
|
52
57
|
|
|
53
58
|
workspace = gsl_integration_workspace_alloc(limit);
|
|
59
|
+
|
|
54
60
|
qagil_params.function = &function;
|
|
55
61
|
qagil_params.b = NUM2DBL(b);
|
|
56
62
|
qagil_params.epsabs = epsabs;
|
|
@@ -62,8 +68,10 @@ VALUE integration_qagil(int argc, VALUE *argv, VALUE self) {
|
|
|
62
68
|
|
|
63
69
|
rb_protect(integration_run_qagil_with_workspace, (VALUE)&qagil_params,
|
|
64
70
|
&state);
|
|
71
|
+
|
|
65
72
|
RB_GC_GUARD(params.block);
|
|
66
73
|
RB_GC_GUARD(params.exception);
|
|
74
|
+
|
|
67
75
|
integration_finish_callback(¶ms, state);
|
|
68
76
|
|
|
69
77
|
return rb_ary_new_from_args(2, DBL2NUM(result), DBL2NUM(error));
|
|
@@ -13,14 +13,17 @@ typedef struct {
|
|
|
13
13
|
|
|
14
14
|
static VALUE integration_run_qagiu(VALUE data) {
|
|
15
15
|
integration_qagiu_params *params = (integration_qagiu_params *)data;
|
|
16
|
+
|
|
16
17
|
(void)gsl_integration_qagiu(params->function, params->a, params->epsabs,
|
|
17
18
|
params->epsrel, params->limit, params->workspace,
|
|
18
19
|
params->result, params->error);
|
|
20
|
+
|
|
19
21
|
return Qnil;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
static VALUE integration_run_qagiu_with_workspace(VALUE data) {
|
|
23
25
|
integration_qagiu_params *params = (integration_qagiu_params *)data;
|
|
26
|
+
|
|
24
27
|
return rb_ensure(integration_run_qagiu, data, integration_free_workspace,
|
|
25
28
|
(VALUE)params->workspace);
|
|
26
29
|
}
|
|
@@ -39,11 +42,13 @@ VALUE integration_qagiu(int argc, VALUE *argv, VALUE self) {
|
|
|
39
42
|
double result;
|
|
40
43
|
double error;
|
|
41
44
|
int state = 0;
|
|
45
|
+
|
|
42
46
|
(void)self;
|
|
43
47
|
|
|
44
48
|
rb_scan_args(argc, argv, "1:", &a, &options);
|
|
45
49
|
|
|
46
50
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
51
|
+
|
|
47
52
|
epsabs = parsed_options.epsabs;
|
|
48
53
|
epsrel = parsed_options.epsrel;
|
|
49
54
|
limit = parsed_options.limit;
|
|
@@ -51,6 +56,7 @@ VALUE integration_qagiu(int argc, VALUE *argv, VALUE self) {
|
|
|
51
56
|
integration_function_init(&function, ¶ms);
|
|
52
57
|
|
|
53
58
|
workspace = gsl_integration_workspace_alloc(limit);
|
|
59
|
+
|
|
54
60
|
qagiu_params.function = &function;
|
|
55
61
|
qagiu_params.a = NUM2DBL(a);
|
|
56
62
|
qagiu_params.epsabs = epsabs;
|
|
@@ -62,8 +68,10 @@ VALUE integration_qagiu(int argc, VALUE *argv, VALUE self) {
|
|
|
62
68
|
|
|
63
69
|
rb_protect(integration_run_qagiu_with_workspace, (VALUE)&qagiu_params,
|
|
64
70
|
&state);
|
|
71
|
+
|
|
65
72
|
RB_GC_GUARD(params.block);
|
|
66
73
|
RB_GC_GUARD(params.exception);
|
|
74
|
+
|
|
67
75
|
integration_finish_callback(¶ms, state);
|
|
68
76
|
|
|
69
77
|
return rb_ary_new_from_args(2, DBL2NUM(result), DBL2NUM(error));
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#include "integration_internal.h"
|
|
2
|
-
|
|
3
2
|
#include <math.h>
|
|
4
3
|
|
|
5
4
|
typedef struct {
|
|
@@ -21,13 +20,13 @@ static void integration_validate_qagp_points(VALUE points) {
|
|
|
21
20
|
double previous = 0.0;
|
|
22
21
|
|
|
23
22
|
if (!RB_TYPE_P(points, T_ARRAY)) {
|
|
24
|
-
rb_raise(
|
|
23
|
+
rb_raise(rb_eTypeError, "points must be an Array");
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
point_count = RARRAY_LEN(points);
|
|
27
|
+
|
|
28
28
|
if (point_count < 2) {
|
|
29
|
-
rb_raise(
|
|
30
|
-
"points must contain at least two values");
|
|
29
|
+
rb_raise(rb_eArgError, "points must contain at least two values");
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
for (index = 0; index < point_count; index++) {
|
|
@@ -35,18 +34,17 @@ static void integration_validate_qagp_points(VALUE points) {
|
|
|
35
34
|
double current;
|
|
36
35
|
|
|
37
36
|
if (!rb_obj_is_kind_of(point, rb_cNumeric)) {
|
|
38
|
-
rb_raise(
|
|
39
|
-
"points must contain only numeric values");
|
|
37
|
+
rb_raise(rb_eTypeError, "points must contain only numeric values");
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
current = NUM2DBL(point);
|
|
41
|
+
|
|
43
42
|
if (!isfinite(current)) {
|
|
44
|
-
rb_raise(
|
|
45
|
-
"points must contain only finite values");
|
|
43
|
+
rb_raise(rb_eArgError, "points must contain only finite values");
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
if (index > 0 && !(previous < current)) {
|
|
49
|
-
rb_raise(
|
|
47
|
+
rb_raise(rb_eArgError, "points must be strictly increasing");
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
previous = current;
|
|
@@ -58,15 +56,19 @@ static VALUE integration_run_qagp(VALUE data) {
|
|
|
58
56
|
size_t index;
|
|
59
57
|
|
|
60
58
|
params->points = ALLOC_N(double, params->point_count);
|
|
59
|
+
|
|
61
60
|
for (index = 0; index < params->point_count; index++) {
|
|
62
61
|
params->points[index] =
|
|
63
62
|
NUM2DBL(rb_ary_entry(params->points_array, (long)index));
|
|
64
63
|
}
|
|
64
|
+
|
|
65
65
|
params->workspace = gsl_integration_workspace_alloc(params->limit);
|
|
66
|
+
|
|
66
67
|
(void)gsl_integration_qagp(params->function, params->points,
|
|
67
68
|
params->point_count, params->epsabs,
|
|
68
69
|
params->epsrel, params->limit, params->workspace,
|
|
69
70
|
params->result, params->error);
|
|
71
|
+
|
|
70
72
|
return Qnil;
|
|
71
73
|
}
|
|
72
74
|
|
|
@@ -76,9 +78,11 @@ static VALUE integration_free_qagp_resources(VALUE data) {
|
|
|
76
78
|
if (params->workspace != NULL) {
|
|
77
79
|
gsl_integration_workspace_free(params->workspace);
|
|
78
80
|
}
|
|
81
|
+
|
|
79
82
|
if (params->points != NULL) {
|
|
80
83
|
xfree(params->points);
|
|
81
84
|
}
|
|
85
|
+
|
|
82
86
|
return Qnil;
|
|
83
87
|
}
|
|
84
88
|
|
|
@@ -102,14 +106,19 @@ VALUE integration_qagp(int argc, VALUE *argv, VALUE self) {
|
|
|
102
106
|
int state = 0;
|
|
103
107
|
|
|
104
108
|
(void)self;
|
|
109
|
+
|
|
105
110
|
rb_scan_args(argc, argv, "1:", &points, &options);
|
|
106
111
|
|
|
107
112
|
integration_validate_qagp_points(points);
|
|
113
|
+
|
|
108
114
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
115
|
+
|
|
109
116
|
epsabs = parsed_options.epsabs;
|
|
110
117
|
epsrel = parsed_options.epsrel;
|
|
111
118
|
limit = parsed_options.limit;
|
|
119
|
+
|
|
112
120
|
integration_function_init(&function, ¶ms);
|
|
121
|
+
|
|
113
122
|
qagp_params.points_array = points;
|
|
114
123
|
qagp_params.function = &function;
|
|
115
124
|
qagp_params.points = NULL;
|
|
@@ -120,10 +129,13 @@ VALUE integration_qagp(int argc, VALUE *argv, VALUE self) {
|
|
|
120
129
|
qagp_params.workspace = NULL;
|
|
121
130
|
qagp_params.result = &result;
|
|
122
131
|
qagp_params.error = &error;
|
|
132
|
+
|
|
123
133
|
rb_protect(integration_run_qagp_with_resources, (VALUE)&qagp_params, &state);
|
|
134
|
+
|
|
124
135
|
RB_GC_GUARD(points);
|
|
125
136
|
RB_GC_GUARD(params.block);
|
|
126
137
|
RB_GC_GUARD(params.exception);
|
|
138
|
+
|
|
127
139
|
integration_finish_callback(¶ms, state);
|
|
128
140
|
|
|
129
141
|
return rb_ary_new_from_args(2, DBL2NUM(result), DBL2NUM(error));
|
|
@@ -50,6 +50,7 @@ VALUE integration_qags(int argc, VALUE *argv, VALUE self) {
|
|
|
50
50
|
rb_scan_args(argc, argv, "2:", &a, &b, &options);
|
|
51
51
|
|
|
52
52
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
53
|
+
|
|
53
54
|
epsabs = parsed_options.epsabs;
|
|
54
55
|
epsrel = parsed_options.epsrel;
|
|
55
56
|
limit = parsed_options.limit;
|
|
@@ -15,14 +15,17 @@ typedef struct {
|
|
|
15
15
|
|
|
16
16
|
static VALUE integration_run_qawc(VALUE data) {
|
|
17
17
|
integration_qawc_params *params = (integration_qawc_params *)data;
|
|
18
|
+
|
|
18
19
|
(void)gsl_integration_qawc(params->function, params->a, params->b, params->c,
|
|
19
20
|
params->epsabs, params->epsrel, params->limit,
|
|
20
21
|
params->workspace, params->result, params->error);
|
|
22
|
+
|
|
21
23
|
return Qnil;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
static VALUE integration_run_qawc_with_workspace(VALUE data) {
|
|
25
27
|
integration_qawc_params *params = (integration_qawc_params *)data;
|
|
28
|
+
|
|
26
29
|
return rb_ensure(integration_run_qawc, data, integration_free_workspace,
|
|
27
30
|
(VALUE)params->workspace);
|
|
28
31
|
}
|
|
@@ -43,11 +46,13 @@ VALUE integration_qawc(int argc, VALUE *argv, VALUE self) {
|
|
|
43
46
|
double result;
|
|
44
47
|
double error;
|
|
45
48
|
int state = 0;
|
|
49
|
+
|
|
46
50
|
(void)self;
|
|
47
51
|
|
|
48
52
|
rb_scan_args(argc, argv, "3:", &a, &b, &c, &options);
|
|
49
53
|
|
|
50
54
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
55
|
+
|
|
51
56
|
epsabs = parsed_options.epsabs;
|
|
52
57
|
epsrel = parsed_options.epsrel;
|
|
53
58
|
limit = parsed_options.limit;
|
|
@@ -55,6 +60,7 @@ VALUE integration_qawc(int argc, VALUE *argv, VALUE self) {
|
|
|
55
60
|
integration_function_init(&function, ¶ms);
|
|
56
61
|
|
|
57
62
|
workspace = gsl_integration_workspace_alloc(limit);
|
|
63
|
+
|
|
58
64
|
qawc_params.function = &function;
|
|
59
65
|
qawc_params.a = NUM2DBL(a);
|
|
60
66
|
qawc_params.b = NUM2DBL(b);
|
|
@@ -67,8 +73,10 @@ VALUE integration_qawc(int argc, VALUE *argv, VALUE self) {
|
|
|
67
73
|
qawc_params.error = &error;
|
|
68
74
|
|
|
69
75
|
rb_protect(integration_run_qawc_with_workspace, (VALUE)&qawc_params, &state);
|
|
76
|
+
|
|
70
77
|
RB_GC_GUARD(params.block);
|
|
71
78
|
RB_GC_GUARD(params.exception);
|
|
79
|
+
|
|
72
80
|
integration_finish_callback(¶ms, state);
|
|
73
81
|
|
|
74
82
|
return rb_ary_new_from_args(2, DBL2NUM(result), DBL2NUM(error));
|
|
@@ -4,6 +4,7 @@ typedef struct {
|
|
|
4
4
|
gsl_function *function;
|
|
5
5
|
double a;
|
|
6
6
|
double omega;
|
|
7
|
+
|
|
7
8
|
enum gsl_integration_qawo_enum sine;
|
|
8
9
|
double epsabs;
|
|
9
10
|
size_t limit;
|
|
@@ -20,9 +21,11 @@ static VALUE integration_free_qawf_resources(VALUE data) {
|
|
|
20
21
|
if (params->table != NULL) {
|
|
21
22
|
gsl_integration_qawo_table_free(params->table);
|
|
22
23
|
}
|
|
24
|
+
|
|
23
25
|
if (params->cycle_workspace != NULL) {
|
|
24
26
|
gsl_integration_workspace_free(params->cycle_workspace);
|
|
25
27
|
}
|
|
28
|
+
|
|
26
29
|
if (params->workspace != NULL) {
|
|
27
30
|
gsl_integration_workspace_free(params->workspace);
|
|
28
31
|
}
|
|
@@ -5,6 +5,7 @@ typedef struct {
|
|
|
5
5
|
double a;
|
|
6
6
|
double b;
|
|
7
7
|
double omega;
|
|
8
|
+
|
|
8
9
|
enum gsl_integration_qawo_enum sine;
|
|
9
10
|
double epsabs;
|
|
10
11
|
double epsrel;
|
|
@@ -21,6 +22,7 @@ static VALUE integration_free_qawo_resources(VALUE data) {
|
|
|
21
22
|
if (params->table != NULL) {
|
|
22
23
|
gsl_integration_qawo_table_free(params->table);
|
|
23
24
|
}
|
|
25
|
+
|
|
24
26
|
if (params->workspace != NULL) {
|
|
25
27
|
gsl_integration_workspace_free(params->workspace);
|
|
26
28
|
}
|
|
@@ -69,6 +71,7 @@ VALUE integration_qawo(int argc, VALUE *argv, VALUE self) {
|
|
|
69
71
|
rb_scan_args(argc, argv, "4:", &a, &b, &omega, &sine, &options);
|
|
70
72
|
|
|
71
73
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
74
|
+
|
|
72
75
|
epsabs = parsed_options.epsabs;
|
|
73
76
|
epsrel = parsed_options.epsrel;
|
|
74
77
|
limit = parsed_options.limit;
|
|
@@ -23,6 +23,7 @@ static VALUE integration_free_qaws_resources(VALUE data) {
|
|
|
23
23
|
if (params->table != NULL) {
|
|
24
24
|
gsl_integration_qaws_table_free(params->table);
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
if (params->workspace != NULL) {
|
|
27
28
|
gsl_integration_workspace_free(params->workspace);
|
|
28
29
|
}
|
|
@@ -36,6 +37,7 @@ static VALUE integration_run_qaws(VALUE data) {
|
|
|
36
37
|
params->table = gsl_integration_qaws_table_alloc(params->alpha, params->beta,
|
|
37
38
|
params->mu, params->nu);
|
|
38
39
|
params->workspace = gsl_integration_workspace_alloc(params->limit);
|
|
40
|
+
|
|
39
41
|
(void)gsl_integration_qaws(params->function, params->a, params->b,
|
|
40
42
|
params->table, params->epsabs, params->epsrel,
|
|
41
43
|
params->limit, params->workspace, params->result,
|
|
@@ -69,9 +71,11 @@ VALUE integration_qaws(int argc, VALUE *argv, VALUE self) {
|
|
|
69
71
|
int state = 0;
|
|
70
72
|
|
|
71
73
|
(void)self;
|
|
74
|
+
|
|
72
75
|
rb_scan_args(argc, argv, "6:", &a, &b, &alpha, &beta, &mu, &nu, &options);
|
|
73
76
|
|
|
74
77
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 1000);
|
|
78
|
+
|
|
75
79
|
epsabs = parsed_options.epsabs;
|
|
76
80
|
epsrel = parsed_options.epsrel;
|
|
77
81
|
limit = parsed_options.limit;
|
|
@@ -94,8 +98,10 @@ VALUE integration_qaws(int argc, VALUE *argv, VALUE self) {
|
|
|
94
98
|
qaws_params.error = &error;
|
|
95
99
|
|
|
96
100
|
rb_protect(integration_run_qaws_with_resources, (VALUE)&qaws_params, &state);
|
|
101
|
+
|
|
97
102
|
RB_GC_GUARD(params.block);
|
|
98
103
|
RB_GC_GUARD(params.exception);
|
|
104
|
+
|
|
99
105
|
integration_finish_callback(¶ms, state);
|
|
100
106
|
|
|
101
107
|
return rb_ary_new_from_args(2, DBL2NUM(result), DBL2NUM(error));
|
|
@@ -50,6 +50,7 @@ VALUE integration_romberg(int argc, VALUE *argv, VALUE self) {
|
|
|
50
50
|
rb_scan_args(argc, argv, "2:", &a, &b, &options);
|
|
51
51
|
|
|
52
52
|
integration_options_parse(options, &parsed_options, 0.0, 1e-8, 20);
|
|
53
|
+
|
|
53
54
|
epsabs = parsed_options.epsabs;
|
|
54
55
|
epsrel = parsed_options.epsrel;
|
|
55
56
|
limit = parsed_options.limit;
|
data/lib/numo/gsl/integration.rb
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require_relative "integration/version"
|
|
4
|
-
require "numo/gsl"
|
|
5
|
-
|
|
6
|
-
module Numo
|
|
7
|
-
module GSL
|
|
8
|
-
module Integration
|
|
9
|
-
class Error < Numo::GSL::GslError
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
3
|
require "numo/gsl/integration/integration"
|