carray 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +56 -0
  3. data/GPL +340 -0
  4. data/Gemfile +9 -0
  5. data/Gemfile.lock +33 -0
  6. data/LEGAL +50 -0
  7. data/NOTE +73 -0
  8. data/Rakefile +20 -0
  9. data/TODO +5 -0
  10. data/ca_iter_block.c +242 -0
  11. data/ca_iter_dimension.c +287 -0
  12. data/ca_iter_window.c +202 -0
  13. data/ca_obj_array.c +1189 -0
  14. data/ca_obj_bitarray.c +523 -0
  15. data/ca_obj_bitfield.c +636 -0
  16. data/ca_obj_block.c +885 -0
  17. data/ca_obj_fake.c +405 -0
  18. data/ca_obj_farray.c +482 -0
  19. data/ca_obj_field.c +625 -0
  20. data/ca_obj_grid.c +738 -0
  21. data/ca_obj_mapping.c +614 -0
  22. data/ca_obj_object.c +777 -0
  23. data/ca_obj_reduce.c +299 -0
  24. data/ca_obj_refer.c +627 -0
  25. data/ca_obj_repeat.c +640 -0
  26. data/ca_obj_select.c +558 -0
  27. data/ca_obj_shift.c +952 -0
  28. data/ca_obj_transpose.c +582 -0
  29. data/ca_obj_unbound_repeat.c +557 -0
  30. data/ca_obj_window.c +1023 -0
  31. data/carray.h +1381 -0
  32. data/carray_access.c +1798 -0
  33. data/carray_attribute.c +903 -0
  34. data/carray_call_cfunc.c +1107 -0
  35. data/carray_cast.c +1155 -0
  36. data/carray_cast_func.rb +498 -0
  37. data/carray_class.c +132 -0
  38. data/carray_conversion.c +518 -0
  39. data/carray_copy.c +453 -0
  40. data/carray_core.c +1307 -0
  41. data/carray_element.c +572 -0
  42. data/carray_generate.c +681 -0
  43. data/carray_iterator.c +630 -0
  44. data/carray_loop.c +462 -0
  45. data/carray_mask.c +1174 -0
  46. data/carray_math.rb +834 -0
  47. data/carray_numeric.c +257 -0
  48. data/carray_operator.c +582 -0
  49. data/carray_order.c +1040 -0
  50. data/carray_random.c +529 -0
  51. data/carray_sort_addr.c +261 -0
  52. data/carray_stat.c +2102 -0
  53. data/carray_stat_proc.rb +1990 -0
  54. data/carray_test.c +602 -0
  55. data/carray_undef.c +69 -0
  56. data/carray_utils.c +740 -0
  57. data/ext/calculus/carray_calculus.c +792 -0
  58. data/ext/calculus/carray_interp.c +355 -0
  59. data/ext/calculus/extconf.rb +12 -0
  60. data/ext/calculus/lib/autoload/autoload_math_calculus.rb +2 -0
  61. data/ext/calculus/lib/math/calculus.rb +119 -0
  62. data/ext/calculus/lib/math/interp/adapter_interp1d.rb +31 -0
  63. data/ext/dataframe/API.txt +11 -0
  64. data/ext/dataframe/extconf.rb +3 -0
  65. data/ext/dataframe/lib/carray/autoload/autoload_dataframe_dataframe.rb +14 -0
  66. data/ext/dataframe/lib/carray/dataframe/dataframe.rb +1104 -0
  67. data/ext/dataframe/sample/test_uniq_sort.rb +5 -0
  68. data/ext/fortio/extconf.rb +3 -0
  69. data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +5 -0
  70. data/ext/fortio/lib/carray/io/fortran_format.rb +43 -0
  71. data/ext/fortio/lib/fortio.rb +3 -0
  72. data/ext/fortio/lib/fortio/fortran_format.rb +603 -0
  73. data/ext/fortio/lib/fortio/fortran_format.tab.rb +536 -0
  74. data/ext/fortio/lib/fortio/fortran_format.y +215 -0
  75. data/ext/fortio/lib/fortio/fortran_namelist.rb +151 -0
  76. data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +470 -0
  77. data/ext/fortio/lib/fortio/fortran_namelist.y +213 -0
  78. data/ext/fortio/lib/fortio/fortran_sequential.rb +345 -0
  79. data/ext/fortio/ruby_fortio.c +182 -0
  80. data/ext/fortio/test/test_H.rb +5 -0
  81. data/ext/fortio/test/test_T.rb +7 -0
  82. data/ext/fortio/test/test_fortran_format.rb +86 -0
  83. data/ext/fortio/test/test_namelist.rb +25 -0
  84. data/ext/fortio/test/test_sequential.rb +13 -0
  85. data/ext/fortio/test/test_sequential2.rb +13 -0
  86. data/ext/fortio/work/test.rb +10 -0
  87. data/ext/fortio/work/test_e.rb +19 -0
  88. data/ext/fortio/work/test_ep.rb +10 -0
  89. data/ext/fortio/work/test_parse.rb +12 -0
  90. data/ext/imagemap/carray_imagemap.c +495 -0
  91. data/ext/imagemap/doc/call_graph.dot +28 -0
  92. data/ext/imagemap/draw.c +567 -0
  93. data/ext/imagemap/extconf.rb +13 -0
  94. data/ext/imagemap/lib/autoload/autoload_graphics_imagemap.rb +1 -0
  95. data/ext/imagemap/lib/graphics/imagemap.rb +273 -0
  96. data/ext/imagemap/lib/image_map.rb +4 -0
  97. data/ext/imagemap/test/swath_index.rb +83 -0
  98. data/ext/imagemap/test/swath_warp.rb +99 -0
  99. data/ext/imagemap/test/test.rb +23 -0
  100. data/ext/imagemap/test/test_image.rb +42 -0
  101. data/ext/imagemap/test/test_line.rb +14 -0
  102. data/ext/imagemap/test/test_rotate.rb +17 -0
  103. data/ext/imagemap/test/test_triangle.rb +20 -0
  104. data/ext/imagemap/test/test_warp.rb +26 -0
  105. data/ext/mathfunc/carray_mathfunc.c +321 -0
  106. data/ext/mathfunc/extconf.rb +18 -0
  107. data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +1 -0
  108. data/ext/mathfunc/lib/math/mathfunc.rb +15 -0
  109. data/ext/mathfunc/test/test_hypot.rb +5 -0
  110. data/ext/mathfunc/test/test_j0.rb +22 -0
  111. data/ext/mathfunc/test/test_jn.rb +8 -0
  112. data/ext/mathfunc/test/test_sph.rb +9 -0
  113. data/ext/narray/README +22 -0
  114. data/ext/narray/ca_wrap_narray.c +491 -0
  115. data/ext/narray/carray_narray.c +21 -0
  116. data/ext/narray/extconf.rb +57 -0
  117. data/ext/narray/lib/autoload/autoload_math_narray.rb +1 -0
  118. data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +11 -0
  119. data/ext/narray/lib/math/narray.rb +17 -0
  120. data/ext/narray/lib/math/narray_miss.rb +45 -0
  121. data/extconf.rb +3 -25
  122. data/lib/carray.rb +28 -0
  123. data/lib/carray/autoload/autoload_base.rb +23 -0
  124. data/lib/carray/autoload/autoload_graphics_gnuplot.rb +2 -0
  125. data/lib/carray/autoload/autoload_io_csv.rb +14 -0
  126. data/lib/carray/autoload/autoload_io_excel.rb +5 -0
  127. data/lib/carray/autoload/autoload_io_imagemagick.rb +6 -0
  128. data/lib/carray/autoload/autoload_io_pg.rb +6 -0
  129. data/lib/carray/autoload/autoload_io_sqlite3.rb +12 -0
  130. data/lib/carray/autoload/autoload_io_table.rb +1 -0
  131. data/lib/carray/autoload/autoload_math_histogram.rb +5 -0
  132. data/lib/carray/autoload/autoload_math_interp.rb +4 -0
  133. data/lib/carray/autoload/autoload_math_recurrence.rb +6 -0
  134. data/lib/carray/autoload/autoload_object_iterator.rb +1 -0
  135. data/lib/carray/autoload/autoload_object_link.rb +1 -0
  136. data/lib/carray/autoload/autoload_object_pack.rb +2 -0
  137. data/lib/carray/base/autoload.rb +94 -0
  138. data/lib/carray/base/basic.rb +1051 -0
  139. data/lib/carray/base/inspect.rb +252 -0
  140. data/lib/carray/base/iterator.rb +367 -0
  141. data/lib/carray/base/math.rb +403 -0
  142. data/lib/carray/base/obsolete.rb +93 -0
  143. data/lib/carray/base/serialize.rb +260 -0
  144. data/lib/carray/base/struct.rb +634 -0
  145. data/lib/carray/graphics/gnuplot.rb +2116 -0
  146. data/lib/carray/info.rb +112 -0
  147. data/lib/carray/io/csv.rb +560 -0
  148. data/lib/carray/io/excel.rb +26 -0
  149. data/lib/carray/io/imagemagick.rb +231 -0
  150. data/lib/carray/io/pg.rb +101 -0
  151. data/lib/carray/io/sqlite3.rb +202 -0
  152. data/lib/carray/io/table.rb +77 -0
  153. data/lib/carray/math/histogram.rb +179 -0
  154. data/lib/carray/math/interp.rb +57 -0
  155. data/lib/carray/math/interp/adapter_gsl_spline.rb +47 -0
  156. data/lib/carray/math/recurrence.rb +95 -0
  157. data/lib/carray/mkmf.rb +145 -0
  158. data/lib/carray/object/ca_obj_iterator.rb +52 -0
  159. data/lib/carray/object/ca_obj_link.rb +52 -0
  160. data/lib/carray/object/ca_obj_pack.rb +101 -0
  161. data/mkmath.rb +731 -0
  162. data/mt19937ar.c +182 -0
  163. data/mt19937ar.h +86 -0
  164. data/rdoc_main.rb +27 -0
  165. data/rdoc_math.rb +5 -0
  166. data/rdoc_stat.rb +31 -0
  167. data/ruby_carray.c +242 -0
  168. data/ruby_ccomplex.c +497 -0
  169. data/ruby_float_func.c +83 -0
  170. data/spec/CABlockIterator/CABlockIterator_spec.rb +113 -0
  171. data/spec/CArray/bug/store_spec.rb +27 -0
  172. data/spec/CArray/index/repeat_spec.rb +10 -0
  173. data/spec/CArray/method/eq_spec.rb +80 -0
  174. data/spec/CArray/method/is_nan_spec.rb +12 -0
  175. data/spec/CArray/method/ne_spec.rb +18 -0
  176. data/spec/CArray/method/round_spec.rb +11 -0
  177. data/spec/CArray/object/_attribute_spec.rb +32 -0
  178. data/spec/CArray/object/s_new_spec.rb +31 -0
  179. data/spec/CArray/serialize/Serialization_spec.rb +89 -0
  180. data/spec/spec_all.rb +11 -0
  181. data/test/test_ALL.rb +50 -0
  182. data/test/test_CABitfield.rb +59 -0
  183. data/test/test_CABlock.rb +208 -0
  184. data/test/test_CAField.rb +40 -0
  185. data/test/test_CAGrid.rb +76 -0
  186. data/test/test_CAMapping.rb +106 -0
  187. data/test/test_CAMmap.rb +11 -0
  188. data/test/test_CARefer.rb +94 -0
  189. data/test/test_CARepeat.rb +66 -0
  190. data/test/test_CASelect.rb +23 -0
  191. data/test/test_CAShift.rb +17 -0
  192. data/test/test_CATranspose.rb +61 -0
  193. data/test/test_CAVirtual.rb +214 -0
  194. data/test/test_CAWindow.rb +55 -0
  195. data/test/test_CAWrap.rb +9 -0
  196. data/test/test_CArray.rb +228 -0
  197. data/test/test_CComplex.rb +83 -0
  198. data/test/test_CScalar.rb +91 -0
  199. data/test/test_attribute.rb +281 -0
  200. data/test/test_block_iterator.rb +17 -0
  201. data/test/test_boolean.rb +99 -0
  202. data/test/test_cast.rb +33 -0
  203. data/test/test_class.rb +85 -0
  204. data/test/test_complex.rb +43 -0
  205. data/test/test_composite.rb +125 -0
  206. data/test/test_convert.rb +79 -0
  207. data/test/test_copy.rb +141 -0
  208. data/test/test_creation.rb +85 -0
  209. data/test/test_element.rb +146 -0
  210. data/test/test_extream.rb +55 -0
  211. data/test/test_generate.rb +75 -0
  212. data/test/test_index.rb +71 -0
  213. data/test/test_mask.rb +578 -0
  214. data/test/test_math.rb +98 -0
  215. data/test/test_narray.rb +64 -0
  216. data/test/test_order.rb +147 -0
  217. data/test/test_random.rb +15 -0
  218. data/test/test_ref_store.rb +211 -0
  219. data/test/test_stat.rb +414 -0
  220. data/test/test_struct.rb +72 -0
  221. data/test/test_virtual.rb +49 -0
  222. data/utils/ca_ase.rb +21 -0
  223. data/utils/ca_methods.rb +15 -0
  224. data/utils/cast_checker.rb +30 -0
  225. data/utils/create_rdoc.sh +9 -0
  226. data/utils/diff_method.rb +52 -0
  227. data/utils/extract_rdoc.rb +27 -0
  228. data/utils/make_tgz.sh +3 -0
  229. data/utils/remove_resource_fork.sh +5 -0
  230. data/version.h +3 -3
  231. metadata +266 -1
@@ -0,0 +1,792 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ carray/carray_calculus.c
4
+
5
+ This file is part of Ruby/CArray extension library.
6
+ You can redistribute it and/or modify it under the terms of
7
+ the Ruby Licence.
8
+
9
+ Copyright (C) 2005 Hiroki Motoyoshi
10
+
11
+ ---------------------------------------------------------------------------- */
12
+
13
+ #include "ruby.h"
14
+ #include "carray.h"
15
+ #include <math.h>
16
+ #include <float.h>
17
+
18
+ /* ----------------------------------------------------------------- */
19
+
20
+ static double
21
+ simpson (double *x, double *y, int n)
22
+ {
23
+ double s;
24
+
25
+ if ( n < 2 ) {
26
+ return 0.0/0.0;
27
+ }
28
+ else if ( n == 2 ) {
29
+ s = (x[1]-x[0])*(y[1]+y[0])*0.5;
30
+ return s;
31
+ }
32
+ else if ( n % 2 == 0 ) {
33
+ double x0, x1, x2, x3;
34
+ double h, m, a1, a2, c0, c1, c2, c3;
35
+ x0 = x[0];
36
+ x1 = x[1];
37
+ x2 = x[2];
38
+ x3 = x[3];
39
+ h = x3 - x0;
40
+ m = (x3 + x0)/2;
41
+ a1 = x1 - m;
42
+ a2 = x2 - m;
43
+ c0 = 1.0 + 2.0*a1*a2/((x0-x1)*(x0-x2));
44
+ c1 = h*h*a2/((x1-x2)*(x1-x0)*(x1-x3));
45
+ c2 = h*h*a1/((x2-x1)*(x2-x0)*(x2-x3));
46
+ c3 = 1.0 + 2.0*a1*a2/((x3-x1)*(x3-x2));
47
+ s = (c0*y[0]+c1*y[1]+c2*y[2]+c3*y[3])*h/6.0;
48
+ if ( n > 4 ) {
49
+ s += simpson(x+3, y+3, n-3);
50
+ }
51
+ return s;
52
+ }
53
+ else {
54
+ double x0, x1, x2;
55
+ double h, m, c0, c1, c2;
56
+ int i;
57
+ s = 0.0;
58
+ for (i=0; i<n-2; i+=2) {
59
+ x0 = x[i];
60
+ x1 = x[i+1];
61
+ x2 = x[i+2];
62
+ h = x2-x0;
63
+ m = 0.5*(x2+x0);
64
+ c0 = 3.0 - h/(x1-x0);
65
+ c1 = h*(x2-x0)/((x2-x1)*(x1-x0));
66
+ c2 = 3.0 - h/(x2-x1);
67
+ s += (c0*y[i]+c1*y[i+1]+c2*y[i+2])*h/6.0;
68
+ }
69
+ return s;
70
+ }
71
+ }
72
+
73
+ static VALUE
74
+ rb_ca_integrate (volatile VALUE self, volatile VALUE vsc)
75
+ {
76
+ CArray *sc, *ca;
77
+ double ans;
78
+
79
+ ca = ca_wrap_readonly(self, CA_DOUBLE);
80
+ sc = ca_wrap_readonly(vsc, CA_DOUBLE);
81
+
82
+ if ( ca->elements != sc->elements ) {
83
+ rb_raise(rb_eRuntimeError, "data num mismatch");
84
+ }
85
+
86
+ if ( ca_is_any_masked(ca) || ca_is_any_masked(sc) ) {
87
+ rb_raise(rb_eRuntimeError,
88
+ "can't calculate integrattion when masked elements exist");
89
+ }
90
+
91
+ ca_attach_n(2, ca, sc);
92
+
93
+ ans = simpson((double*)sc->ptr, (double*)ca->ptr, ca->elements);
94
+
95
+ ca_detach_n(2, ca, sc);
96
+
97
+ return rb_float_new(ans);
98
+ }
99
+
100
+
101
+ /* ----------------------------------------------------------------- */
102
+
103
+ static int
104
+ linear_index (int n, double *y, double yy, double *idx)
105
+ {
106
+ int a, b, c, x1;
107
+ double ya, yb, yc;
108
+ double y1, y2;
109
+ double rest;
110
+
111
+ if ( yy <= y[0] ) {
112
+ x1 = 0;
113
+ goto found;
114
+ }
115
+
116
+ if ( yy >= y[n-1] ) {
117
+ x1 = n-2;
118
+ goto found;
119
+ }
120
+
121
+ /* check for equally spaced scale */
122
+
123
+ a = (int)((yy-y[0])/(y[n-1]-y[0])*(n-1));
124
+
125
+ if ( a >= 0 && a < n-1 ) {
126
+ if ( (y[a] - yy) * (y[a+1] - yy) <= 0 ) { /* lucky case */
127
+ x1 = a;
128
+ goto found;
129
+ }
130
+ }
131
+
132
+ /* binary section method */
133
+
134
+ a = 0;
135
+ b = n-1;
136
+
137
+ ya = y[a];
138
+ yb = y[b];
139
+
140
+ if ( ya > yb ) {
141
+ return -1; /* input scale array should have accending order */
142
+ }
143
+
144
+ while ( (b - a) >= 1 ) {
145
+
146
+ c = (a + b)/2;
147
+ yc = y[c];
148
+ if ( a == c ) {
149
+ break;
150
+ }
151
+
152
+ if ( yc == yy ) {
153
+ a = c;
154
+ break;
155
+ }
156
+ else if ( (ya - yy) * (yc - yy) <= 0 ) {
157
+ b = c;
158
+ yb = yc;
159
+ }
160
+ else {
161
+ a = c;
162
+ ya = yc;
163
+ }
164
+
165
+ if ( ya > yb ) {
166
+ return -1; /* input scale array should have accending order */
167
+ }
168
+ }
169
+
170
+ x1 = a;
171
+
172
+ found:
173
+
174
+ y1 = y[x1];
175
+ y2 = y[x1+1];
176
+ rest = (yy-y1)/(y2-y1);
177
+
178
+ if ( fabs(y2-yy)/fabs(y2) < DBL_EPSILON*100 ) {
179
+ *idx = (double) (x1 + 1);
180
+ }
181
+ else if ( fabs(y1-yy)/fabs(y1) < DBL_EPSILON*100 ) {
182
+ *idx = (double) x1;
183
+ }
184
+ else {
185
+ *idx = rest + (double) x1;
186
+ }
187
+
188
+ return 0;
189
+ }
190
+
191
+ static VALUE
192
+ rb_ca_binary_search_linear_index (volatile VALUE self, volatile VALUE vx)
193
+ {
194
+ volatile VALUE out, out0;
195
+ CArray *ca, *sc, *cx, *co0, *co;
196
+ int32_t n;
197
+ double *x;
198
+ double *px;
199
+ double *po;
200
+ int i;
201
+
202
+ Data_Get_Struct(self, CArray, ca);
203
+
204
+ if ( rb_ca_is_any_masked(self) ) {
205
+ rb_raise(rb_eRuntimeError, "self should not have any masked elements");
206
+ }
207
+
208
+ sc = ca_wrap_readonly(self, CA_FLOAT64);
209
+ cx = ca_wrap_readonly(vx, CA_FLOAT64);
210
+
211
+ co0 = carray_new(ca->data_type, cx->rank, cx->dim, 0, NULL);
212
+ out = out0 = ca_wrap_struct(co0);
213
+ co = ca_wrap_writable(out, CA_FLOAT64);
214
+
215
+ ca_attach_n(3, sc, cx, co);
216
+
217
+ n = sc->elements;
218
+ x = (double*) sc->ptr;
219
+ px = (double*) cx->ptr;
220
+ po = (double*) co->ptr;
221
+
222
+ ca_update_mask(cx);
223
+ if ( cx->mask ) {
224
+ boolean8_t *mx, *mo;
225
+ ca_create_mask(co);
226
+ mx = (boolean8_t *) cx->mask->ptr;
227
+ mo = (boolean8_t *) co->mask->ptr;
228
+ for (i=0; i<cx->elements; i++) {
229
+ if ( ! *mx ) {
230
+ linear_index(n, x, *px, po);
231
+ }
232
+ else {
233
+ *mo = 1;
234
+ }
235
+ mx++; mo++; px++, po++;
236
+ }
237
+ }
238
+ else {
239
+ for (i=0; i<cx->elements; i++) {
240
+ linear_index(n, x, *px, po);
241
+ px++, po++;
242
+ }
243
+ }
244
+
245
+ ca_sync(co);
246
+ ca_detach_n(3, sc, cx, co);
247
+
248
+ if ( rb_ca_is_scalar(vx) ) {
249
+ return rb_funcall(out0, rb_intern("[]"), 1, INT2FIX(0));
250
+ }
251
+ else {
252
+ return out0;
253
+ }
254
+ }
255
+
256
+ static double
257
+ interp_lin (double *x, double *y, double xx)
258
+ {
259
+ double a, b;
260
+ double xa, xb;
261
+ double ab;
262
+ double fa, fb;
263
+ a = x[0];
264
+ b = x[1];
265
+ fa = y[0];
266
+ fb = y[1];
267
+ xa = xx - a;
268
+ xb = xx - b;
269
+ ab = a - b;
270
+ return -xa*fb/ab + xb*fa/ab;
271
+ }
272
+
273
+ static double
274
+ deriv_lin (double *x, double *y, double xx)
275
+ {
276
+ double a, b;
277
+ double ab;
278
+ double fa, fb;
279
+ a = x[0];
280
+ b = x[1];
281
+ fa = y[0];
282
+ fb = y[1];
283
+ ab = a - b;
284
+ return -fb/ab + fa/ab;
285
+ }
286
+
287
+ static double
288
+ interp_qual (double *x, double *y, double xx)
289
+ {
290
+ double a, b, c;
291
+ double xa, xb, xc;
292
+ double ab, bc, ca;
293
+ double fa, fb, fc;
294
+ a = x[0];
295
+ b = x[1];
296
+ c = x[2];
297
+ fa = y[0];
298
+ fb = y[1];
299
+ fc = y[2];
300
+ xa = xx - a;
301
+ xb = xx - b;
302
+ xc = xx - c;
303
+ ab = a - b;
304
+ bc = b - c;
305
+ ca = c - a;
306
+ return -(xa*xb*fc/ca/bc + xb*xc*fa/ab/ca + xc*xa*fb/bc/ab);
307
+ }
308
+
309
+ static double
310
+ deriv_qual (double *x, double *y, double xx)
311
+ {
312
+ double a, b, c;
313
+ double xa, xb, xc;
314
+ double ab, bc, ca;
315
+ double fa, fb, fc;
316
+ a = x[0];
317
+ b = x[1];
318
+ c = x[2];
319
+ fa = y[0];
320
+ fb = y[1];
321
+ fc = y[2];
322
+ xa = xx - a;
323
+ xb = xx - b;
324
+ xc = xx - c;
325
+ ab = a - b;
326
+ bc = b - c;
327
+ ca = c - a;
328
+ return - (xa+xb)*fc/ca/bc
329
+ - (xb+xc)*fa/ab/ca
330
+ - (xc+xa)*fb/bc/ab;
331
+ }
332
+
333
+ static double
334
+ interp_cubic (double *x, double *y, double xx)
335
+ {
336
+ double a, b, c, d;
337
+ double xa, xb, xc, xd;
338
+ double ab, bc, cd, da, db, ac;
339
+ double fa, fb, fc, fd;
340
+ a = x[0];
341
+ b = x[1];
342
+ c = x[2];
343
+ d = x[3];
344
+ fa = y[0];
345
+ fb = y[1];
346
+ fc = y[2];
347
+ fd = y[3];
348
+ xa = xx - a;
349
+ xb = xx - b;
350
+ xc = xx - c;
351
+ xd = xx - d;
352
+ ab = a - b;
353
+ bc = b - c;
354
+ cd = c - d;
355
+ da = d - a;
356
+ db = d - b;
357
+ ac = a - c;
358
+ return -xa*xb*xc*fd/da/db/cd - xb*xc*xd*fa/ab/ac/da +
359
+ xc*xd*xa*fb/bc/db/ab + xd*xa*xb*fc/cd/ac/bc;
360
+ }
361
+
362
+ static double
363
+ deriv_cubic (double *x, double *y, double xx)
364
+ {
365
+ double a, b, c, d;
366
+ double xa, xb, xc, xd;
367
+ double ab, bc, cd, da, db, ac;
368
+ double fa, fb, fc, fd;
369
+ a = x[0];
370
+ b = x[1];
371
+ c = x[2];
372
+ d = x[3];
373
+ fa = y[0];
374
+ fb = y[1];
375
+ fc = y[2];
376
+ fd = y[3];
377
+ xa = xx - a;
378
+ xb = xx - b;
379
+ xc = xx - c;
380
+ xd = xx - d;
381
+ ab = a - b;
382
+ bc = b - c;
383
+ cd = c - d;
384
+ da = d - a;
385
+ db = d - b;
386
+ ac = a - c;
387
+ return - (xb*xc+xa*xc+xa*xb)*fd/da/db/cd
388
+ - (xc*xd+xb*xd+xb*xc)*fa/ab/ac/da
389
+ + (xd*xa+xc*xa+xc*xd)*fb/bc/db/ab
390
+ + (xa*xb+xd*xb+xd*xa)*fc/cd/ac/bc;
391
+ }
392
+
393
+ static double
394
+ interp_penta (double *x, double *y, double xx)
395
+ {
396
+ double a, b, c, d, e, f;
397
+ double xa, xb, xc, xd, xe, xf;
398
+ double ya, yb, yc, yd, ye, yf;
399
+ double ab, ac, ad, ae, af;
400
+ double bc, bd, be, bf;
401
+ double cd, ce, cf;
402
+ double de, df;
403
+ double ef;
404
+ a = x[0];
405
+ b = x[1];
406
+ c = x[2];
407
+ d = x[3];
408
+ e = x[4];
409
+ f = x[5];
410
+ ya = y[0];
411
+ yb = y[1];
412
+ yc = y[2];
413
+ yd = y[3];
414
+ ye = y[4];
415
+ yf = y[5];
416
+ xa = xx - a;
417
+ xb = xx - b;
418
+ xc = xx - c;
419
+ xd = xx - d;
420
+ xe = xx - e;
421
+ xf = xx - f;
422
+ ab = a - b;
423
+ ac = a - c;
424
+ ad = a - d;
425
+ ae = a - e;
426
+ af = a - f;
427
+ bc = b - c;
428
+ bd = b - d;
429
+ be = b - e;
430
+ bf = b - f;
431
+ cd = c - d;
432
+ ce = c - e;
433
+ cf = c - f;
434
+ de = d - e;
435
+ df = d - f;
436
+ ef = e - f;
437
+ return ya*xb*xc*xd*xe*xf/(ab*ac*ad*ae*af)
438
+ - xa*yb*xc*xd*xe*xf/(ab*bc*bd*be*bf)
439
+ + xa*xb*yc*xd*xe*xf/(ac*bc*cd*ce*cf)
440
+ - xa*xb*xc*yd*xe*xf/(ad*bd*cd*de*df)
441
+ + xa*xb*xc*xd*ye*xf/(ae*be*ce*de*ef)
442
+ - xa*xb*xc*xd*xe*yf/(af*bf*cf*df*ef);
443
+ }
444
+
445
+
446
+ static double
447
+ deriv_penta (double *x, double *y, double xx)
448
+ {
449
+ double a, b, c, d, e, f;
450
+ double xa, xb, xc, xd, xe, xf;
451
+ double ya, yb, yc, yd, ye, yf;
452
+ double ab, ac, ad, ae, af;
453
+ double bc, bd, be, bf;
454
+ double cd, ce, cf;
455
+ double de, df;
456
+ double ef;
457
+ a = x[0];
458
+ b = x[1];
459
+ c = x[2];
460
+ d = x[3];
461
+ e = x[4];
462
+ f = x[5];
463
+ ya = y[0];
464
+ yb = y[1];
465
+ yc = y[2];
466
+ yd = y[3];
467
+ ye = y[4];
468
+ yf = y[5];
469
+ xa = xx - a;
470
+ xb = xx - b;
471
+ xc = xx - c;
472
+ xd = xx - d;
473
+ xe = xx - e;
474
+ xf = xx - f;
475
+ ab = a - b;
476
+ ac = a - c;
477
+ ad = a - d;
478
+ ae = a - e;
479
+ af = a - f;
480
+ bc = b - c;
481
+ bd = b - d;
482
+ be = b - e;
483
+ bf = b - f;
484
+ cd = c - d;
485
+ ce = c - e;
486
+ cf = c - f;
487
+ de = d - e;
488
+ df = d - f;
489
+ ef = e - f;
490
+ return (xc*xd*xe*xf+xb*xd*xe*xf+xb*xc*xe*xf+xb*xc*xd*xf+xb*xc*xd*xe)*ya/(ab*ac*ad*ae*af)
491
+ - (xc*xd*xe*xf+xa*xd*xe*xf+xa*xc*xe*xf+xa*xc*xd*xf+xa*xc*xd*xe)*yb/(ab*bc*bd*be*bf)
492
+ + (xb*xd*xe*xf+xa*xd*xe*xf+xa*xb*xe*xf+xa*xb*xd*xf+xa*xb*xd*xe)*yc/(ac*bc*cd*ce*cf)
493
+ - (xb*xc*xe*xf+xa*xc*xe*xf+xa*xb*xe*xf+xa*xb*xc*xf+xa*xb*xc*xe)*yd/(ad*bd*cd*de*df)
494
+ + (xb*xc*xd*xf+xa*xc*xd*xf+xa*xb*xd*xf+xa*xb*xc*xf+xa*xb*xc*xd)*ye/(ae*be*ce*de*ef)
495
+ - (xb*xc*xd*xe+xa*xc*xd*xe+xa*xb*xd*xe+xa*xb*xc*xe+xa*xb*xc*xd)*yf/(af*bf*cf*df*ef);
496
+ }
497
+
498
+ static double
499
+ interpolate_linear (double *x, double *y, int n, double xx)
500
+ {
501
+ double ri;
502
+ int i0;
503
+ if ( n == 1) {
504
+ return y[0];
505
+ }
506
+ if ( xx == x[0] ) {
507
+ return y[0];
508
+ }
509
+ if ( xx == x[1] ) {
510
+ return y[1];
511
+ }
512
+ if ( n == 2 ) {
513
+ return interp_lin(x, y, xx);
514
+ }
515
+ linear_index(n, x, xx, &ri);
516
+ i0 = floor(ri);
517
+ if ( i0 <= 0 ) {
518
+ i0 = 0;
519
+ }
520
+ else if ( i0 + 1 >= n - 1 ) {
521
+ i0 = n - 2;
522
+ }
523
+ return interp_lin(&x[i0], &y[i0], xx);
524
+ }
525
+
526
+ static double
527
+ interpolate_cubic (double *x, double *y, int n, double xx)
528
+ {
529
+ double ri;
530
+ int i0;
531
+ if ( n == 1) {
532
+ return y[0];
533
+ }
534
+ if ( xx == x[0] ) {
535
+ return y[0];
536
+ }
537
+ if ( xx == x[1] ) {
538
+ return y[1];
539
+ }
540
+ if ( xx == x[2] ) {
541
+ return y[2];
542
+ }
543
+ if ( n == 2 ) {
544
+ return interp_lin(x, y, xx);
545
+ }
546
+ if ( n == 3 ) {
547
+ return interp_qual(x, y, xx);
548
+ }
549
+ linear_index(n, x, xx, &ri);
550
+ i0 = floor(ri) - 1;
551
+ if ( i0 <= 0 ) {
552
+ i0 = 0;
553
+ }
554
+ else if ( i0 + 3 >= n - 1 ) {
555
+ i0 = n - 4;
556
+ }
557
+ return interp_cubic(&x[i0], &y[i0], xx);
558
+ }
559
+
560
+ static double
561
+ differentiate (double *x, double *y, int n, double xx)
562
+ {
563
+ double ri;
564
+ int i0;
565
+ switch ( n ) {
566
+ case 1:
567
+ return 0.0/0.0;
568
+ case 2:
569
+ return deriv_lin(x, y, xx);
570
+ case 3:
571
+ return deriv_qual(x, y, xx);
572
+ case 4:
573
+ return deriv_cubic(x, y, xx);
574
+ }
575
+ linear_index(n, x, xx, &ri);
576
+ i0 = floor(ri) - 1;
577
+ if ( i0 <= 0 ) {
578
+ i0 = 0;
579
+ }
580
+ else if ( n == 5 && i0 + 4 > n - 1 ) {
581
+ i0 = n - 5;
582
+ }
583
+ else if ( i0 + 5 > n - 1 ) {
584
+ i0 = n - 6;
585
+ }
586
+ if ( n == 5 ) {
587
+ return deriv_cubic(&x[i0], &y[i0], xx);
588
+ }
589
+ else {
590
+ return deriv_penta(&x[i0], &y[i0], xx);
591
+ }
592
+ }
593
+
594
+ static VALUE
595
+ rb_ca_interpolate (int argc, VALUE *argv, VALUE self)
596
+ {
597
+ volatile VALUE rval = self;
598
+ volatile VALUE vsc, vx, ropt, rtype = Qnil, out0, out;
599
+ CArray *ca, *sc, *cv, *cx, *co0, *co;
600
+ char *typename = NULL;
601
+ int type = 0;
602
+ double *px, *po;
603
+ int32_t i;
604
+
605
+ Data_Get_Struct(self, CArray, ca);
606
+
607
+ rb_scan_args(argc, argv, "21", &vsc, &vx, &ropt);
608
+ rb_scan_options(ropt, "type", &rtype);
609
+
610
+ if ( ! NIL_P(rtype) ) {
611
+ Check_Type(rtype, T_STRING);
612
+ typename = StringValuePtr(rtype);
613
+ }
614
+
615
+
616
+ if ( typename == NULL || ! strncmp("cubic", typename, 5) ) {
617
+ type = 3;
618
+ }
619
+ else if ( ! strncmp("linear", typename, 6) ) {
620
+ type = 1;
621
+ }
622
+ else {
623
+ volatile VALUE inspect = rb_inspect(rtype);
624
+ rb_raise(rb_eRuntimeError,
625
+ "invalid interpolation type <%s>", StringValuePtr(inspect));
626
+ }
627
+
628
+ cv = ca_wrap_readonly(rval, CA_DOUBLE);
629
+ sc = ca_wrap_readonly(vsc, CA_DOUBLE);
630
+
631
+ if ( ca_is_any_masked(cv) || ca_is_any_masked(sc) ) {
632
+ rb_raise(rb_eRuntimeError,
633
+ "can't calculate interpolation when masked elements exist");
634
+ }
635
+
636
+ if ( cv->elements != sc->elements ) {
637
+ rb_raise(rb_eRuntimeError, "data num mismatch with scale");
638
+ }
639
+
640
+ cx = ca_wrap_readonly(vx, CA_DOUBLE);
641
+
642
+ co0 = carray_new(ca->data_type, cx->rank, cx->dim, 0, NULL);
643
+ out = out0 = ca_wrap_struct(co0);
644
+ co = ca_wrap_writable(out, CA_DOUBLE);
645
+
646
+ ca_attach_n(4, cv, sc, cx, co);
647
+
648
+ px = (double*) cx->ptr;
649
+ po = (double*) co->ptr;
650
+
651
+ ca_update_mask(cx);
652
+ if ( cx->mask ) {
653
+ boolean8_t *mx, *mo;
654
+ ca_create_mask(co);
655
+ mx = (boolean8_t *) cx->mask->ptr;
656
+ mo = (boolean8_t *) co->mask->ptr;
657
+ if ( type == 3 ) {
658
+ for (i=0; i<cx->elements; i++) {
659
+ if ( ! *mx ) {
660
+ *po = interpolate_cubic((double*)sc->ptr, (double*)cv->ptr,
661
+ cv->elements, *px);
662
+ }
663
+ else {
664
+ *mo = 1;
665
+ }
666
+ mx++; mo++; po++; px++;
667
+ }
668
+ }
669
+ else {
670
+ for (i=0; i<cx->elements; i++) {
671
+ if ( ! *mx ) {
672
+ *po = interpolate_linear((double*)sc->ptr, (double*)cv->ptr,
673
+ cv->elements, *px);
674
+ }
675
+ else {
676
+ *mo = 1;
677
+ }
678
+ mx++; mo++; po++; px++;
679
+ }
680
+ }
681
+ }
682
+ else {
683
+ if ( type == 3 ) {
684
+ for (i=0; i<cx->elements; i++) {
685
+ *po++ = interpolate_cubic((double*)sc->ptr, (double*)cv->ptr,
686
+ cv->elements, *px++);
687
+ }
688
+ }
689
+ else {
690
+ for (i=0; i<cx->elements; i++) {
691
+ *po++ = interpolate_linear((double*)sc->ptr, (double*)cv->ptr,
692
+ cv->elements, *px++);
693
+ }
694
+ }
695
+ }
696
+
697
+ ca_sync(co);
698
+ ca_detach_n(4, cv, sc, cx, co);
699
+
700
+ if ( rb_ca_is_scalar(vx) ) {
701
+ return rb_funcall(out0, rb_intern("[]"), 1, INT2FIX(0));
702
+ }
703
+ else {
704
+ return out0;
705
+ }
706
+ }
707
+
708
+ static VALUE
709
+ rb_ca_differentiate (volatile VALUE self,
710
+ volatile VALUE vsc, volatile VALUE vx)
711
+ {
712
+ volatile VALUE rval = self;
713
+ volatile VALUE out0, out;
714
+ CArray *ca, *cv, *sc, *cx, *co0, *co;
715
+ double *px, *po;
716
+ int32_t i;
717
+
718
+ Data_Get_Struct(self, CArray, ca);
719
+
720
+ cv = ca_wrap_readonly(rval, CA_DOUBLE);
721
+ sc = ca_wrap_readonly(vsc, CA_DOUBLE);
722
+
723
+ if ( ca_is_any_masked(cv) || ca_is_any_masked(sc) ) {
724
+ rb_raise(rb_eRuntimeError,
725
+ "can't calculate differentiation when masked elements exist");
726
+ }
727
+
728
+ if ( cv->elements != sc->elements ) {
729
+ rb_raise(rb_eRuntimeError, "data num mismatch with scale");
730
+ }
731
+
732
+ cx = ca_wrap_readonly(vx, CA_DOUBLE);
733
+
734
+ co0 = carray_new(ca->data_type, cx->rank, cx->dim, 0, NULL);
735
+ out = out0 = ca_wrap_struct(co0);
736
+ co = ca_wrap_writable(out, CA_DOUBLE);
737
+
738
+ ca_attach_n(4, cv, sc, cx, co);
739
+
740
+ px = (double*) cx->ptr;
741
+ po = (double*) co->ptr;
742
+
743
+ ca_update_mask(cx);
744
+ if ( cx->mask ) {
745
+ boolean8_t *mx, *mo;
746
+ ca_create_mask(co);
747
+ mx = (boolean8_t *) cx->mask->ptr;
748
+ mo = (boolean8_t *) co->mask->ptr;
749
+ for (i=0; i<cx->elements; i++) {
750
+ if ( ! *mx ) {
751
+ *po = differentiate((double*)sc->ptr, (double*)ca->ptr,
752
+ ca->elements, *px);
753
+ }
754
+ else {
755
+ *mo = 1;
756
+ }
757
+ mx++; mo++; px++, po++;
758
+ }
759
+ }
760
+ else {
761
+ for (i=0; i<cx->elements; i++) {
762
+ *po = differentiate((double*)sc->ptr, (double*)ca->ptr,
763
+ ca->elements, *px);
764
+ px++, po++;
765
+ }
766
+ }
767
+
768
+ ca_sync(co);
769
+ ca_detach_n(4, cv, sc, cx, co);
770
+
771
+ if ( rb_ca_is_scalar(vx) ) {
772
+ return rb_funcall(out0, rb_intern("[]"), 1, INT2FIX(0));
773
+ }
774
+ else {
775
+ return out0;
776
+ }
777
+ }
778
+
779
+ void
780
+ Init_carray_interpolate ();
781
+
782
+ void
783
+ Init_carray_calculus ()
784
+ {
785
+ rb_define_method(rb_cCArray, "section",
786
+ rb_ca_binary_search_linear_index, 1);
787
+ rb_define_method(rb_cCArray, "integrate", rb_ca_integrate, 1);
788
+ rb_define_method(rb_cCArray, "interpolate", rb_ca_interpolate, -1);
789
+ rb_define_method(rb_cCArray, "differentiate", rb_ca_differentiate, 2);
790
+
791
+ Init_carray_interpolate();
792
+ }