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,952 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_obj_shift.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 "carray.h"
14
+
15
+ /* rdoc:
16
+ class CAShift < CAVirtual # :nodoc:
17
+ end
18
+ */
19
+
20
+ static VALUE rb_cCAShift;
21
+
22
+ typedef struct {
23
+ int16_t obj_type;
24
+ int8_t data_type;
25
+ int8_t rank;
26
+ int32_t flags;
27
+ int32_t bytes;
28
+ int32_t elements;
29
+ int32_t *dim;
30
+ char *ptr;
31
+ CArray *mask;
32
+ CArray *parent;
33
+ uint32_t attach;
34
+ uint8_t nosync;
35
+ /* -------------*/
36
+ int32_t *shift;
37
+ char *fill;
38
+ int8_t *roll;
39
+ int fill_mask;
40
+ } CAShift;
41
+
42
+ static int8_t CA_OBJ_SHIFT;
43
+
44
+ /* ------------------------------------------------------------------- */
45
+
46
+ int
47
+ ca_shift_setup (CAShift *ca, CArray *parent,
48
+ int32_t *shift, char *fill, int8_t *roll)
49
+ {
50
+ int8_t data_type, rank;
51
+ int32_t elements, bytes;
52
+
53
+ data_type = parent->data_type;
54
+ bytes = parent->bytes;
55
+ rank = parent->rank;
56
+ elements = parent->elements;
57
+
58
+
59
+ ca->obj_type = CA_OBJ_SHIFT;
60
+ ca->data_type = data_type;
61
+ ca->flags = 0;
62
+ ca->rank = rank;
63
+ ca->bytes = bytes;
64
+ ca->elements = elements;
65
+ ca->ptr = NULL;
66
+ ca->mask = NULL;
67
+ ca->dim = ALLOC_N(int32_t, rank);
68
+
69
+ ca->parent = parent;
70
+ ca->attach = 0;
71
+ ca->nosync = 0;
72
+ ca->shift = ALLOC_N(int32_t, rank);
73
+ ca->fill = ALLOC_N(char, ca->bytes);
74
+ ca->roll = ALLOC_N(int8_t, rank);
75
+
76
+ memcpy(ca->dim, parent->dim, rank * sizeof(int32_t));
77
+ memcpy(ca->shift, shift, rank * sizeof(int32_t));
78
+ memcpy(ca->roll, roll, rank * sizeof(int8_t));
79
+
80
+ if ( fill ) {
81
+ ca->fill_mask = 0;
82
+ memcpy(ca->fill, fill, ca->bytes);
83
+ }
84
+ else {
85
+ ca->fill_mask = 1;
86
+ memset(ca->fill, 0, ca->bytes);
87
+ }
88
+
89
+ if ( ca_has_mask(parent) ) {
90
+ ca_create_mask(ca);
91
+ }
92
+
93
+ return 0;
94
+ }
95
+
96
+ CAShift *
97
+ ca_shift_new (CArray *parent, int32_t *shift, char *fill, int8_t *roll)
98
+ {
99
+ CAShift *ca = ALLOC(CAShift);
100
+ ca_shift_setup(ca, parent, shift, fill, roll);
101
+ return ca;
102
+ }
103
+
104
+ static void
105
+ free_ca_shift (void *ap)
106
+ {
107
+ CAShift *ca = (CAShift *) ap;
108
+ if ( ca != NULL ) {
109
+ xfree(ca->fill);
110
+ xfree(ca->shift);
111
+ xfree(ca->roll);
112
+ ca_free(ca->mask);
113
+ xfree(ca->dim);
114
+ xfree(ca);
115
+ }
116
+ }
117
+
118
+ static void ca_shift_attach (CAShift *ca);
119
+ static void ca_shift_sync (CAShift *ca);
120
+ static void ca_shift_fill (CAShift *ca, char *ptr);
121
+
122
+ static int32_t
123
+ ca_shift_normalized_roll_shift (CAShift *ca, int32_t i)
124
+ {
125
+ int32_t dim = ca->dim[i];
126
+ int32_t shift = ca->shift[i];
127
+ if ( shift >= 0 ) {
128
+ return shift % dim;
129
+ }
130
+ else {
131
+ return -((-shift) % dim);
132
+ }
133
+ }
134
+
135
+ static int32_t
136
+ ca_shift_rolled_index (CAShift *ca, int32_t i, int32_t k)
137
+ {
138
+ int32_t dim = ca->dim[i];
139
+ int32_t shift = ca->shift[i];
140
+ int32_t idx = k - shift;
141
+ if ( idx >= 0 ) {
142
+ return idx % dim;
143
+ }
144
+ else {
145
+ idx = (-idx) % dim;
146
+ return ( ! idx ) ? 0 : dim - idx;
147
+ }
148
+ }
149
+
150
+ static int32_t
151
+ ca_shift_shifted_index (CAShift *ca, int32_t i, int32_t k)
152
+ {
153
+ int32_t dim = ca->dim[i];
154
+ int32_t shift = ca->shift[i];
155
+ int32_t idx = k - shift;
156
+ if ( idx < 0 || idx >= dim ) {
157
+ return -1;
158
+ }
159
+ else {
160
+ return idx;
161
+ }
162
+ }
163
+
164
+ /* ------------------------------------------------------------------- */
165
+
166
+ static void *
167
+ ca_shift_func_clone (void *ap)
168
+ {
169
+ CAShift *ca = (CAShift *) ap;
170
+ return ca_shift_new(ca->parent, ca->shift, ca->fill, ca->roll);
171
+ }
172
+
173
+ static char *
174
+ ca_shift_func_ptr_at_addr (void *ap, int32_t addr)
175
+ {
176
+ CAShift *ca = (CAShift *) ap;
177
+ if ( ! ca->ptr ) {
178
+ int32_t idx[CA_RANK_MAX];
179
+ ca_addr2index((CArray *)ca, addr, idx);
180
+ return ca_ptr_at_index(ca, idx);
181
+ }
182
+ else {
183
+ return ca->ptr + ca->bytes * addr;
184
+ }
185
+ }
186
+
187
+ static char *
188
+ ca_shift_func_ptr_at_index (void *ap, int32_t *idx)
189
+ {
190
+ CAShift *ca = (CAShift *) ap;
191
+ if ( ! ca->ptr ) {
192
+ int32_t *dim = ca->dim;
193
+ int8_t *roll = ca->roll;
194
+ int32_t i, k, n;
195
+ n = 0;
196
+ for (i=0; i<ca->rank; i++) {
197
+ k = idx[i];
198
+ if ( roll[i] ) {
199
+ k = ca_shift_rolled_index(ca, i, k);
200
+ }
201
+ else {
202
+ k = ca_shift_shifted_index(ca, i, k);
203
+ }
204
+
205
+ if ( k < 0 ) {
206
+ return ca->fill;
207
+ }
208
+ n = dim[i] * n + k;
209
+ }
210
+
211
+ if ( ca->parent->ptr == NULL ) {
212
+ return ca_ptr_at_addr(ca->parent, n);
213
+ }
214
+ else {
215
+ return ca->parent->ptr + ca->bytes * n;
216
+ }
217
+ }
218
+ else {
219
+ return ca_func[CA_OBJ_ARRAY].ptr_at_index(ca, idx);
220
+ }
221
+ }
222
+
223
+ static void
224
+ ca_shift_func_fetch_index (void *ap, int32_t *idx, void *ptr)
225
+ {
226
+ CAShift *ca = (CAShift *) ap;
227
+ int32_t *dim = ca->dim;
228
+ int8_t *roll = ca->roll;
229
+ int32_t i, k, n;
230
+ n = 0;
231
+ for (i=0; i<ca->rank; i++) {
232
+ k = idx[i];
233
+ if ( roll[i] ) {
234
+ k = ca_shift_rolled_index(ca, i, k);
235
+ }
236
+ else {
237
+ k = ca_shift_shifted_index(ca, i, k);
238
+ }
239
+
240
+ if ( k < 0 ) {
241
+ memcpy(ptr, ca->fill, ca->bytes);
242
+ return;
243
+ }
244
+ n = dim[i] * n + k;
245
+ }
246
+ ca_fetch_addr(ca->parent, n, ptr);
247
+ }
248
+
249
+ static void
250
+ ca_shift_func_store_index (void *ap, int32_t *idx, void *ptr)
251
+ {
252
+ CAShift *ca = (CAShift *) ap;
253
+ int32_t *dim = ca->dim;
254
+ int8_t *roll = ca->roll;
255
+ int32_t i, k, n;
256
+ n = 0;
257
+ for (i=0; i<ca->rank; i++) {
258
+ k = idx[i];
259
+ if ( roll[i] ) {
260
+ k = ca_shift_rolled_index(ca, i, k);
261
+ }
262
+ else {
263
+ k = ca_shift_shifted_index(ca, i, k);
264
+ }
265
+
266
+ if ( k < 0 ) {
267
+ return;
268
+ }
269
+ n = dim[i] * n + k;
270
+ }
271
+ ca_store_addr(ca->parent, n, ptr);
272
+ }
273
+
274
+ static void
275
+ ca_shift_func_allocate (void *ap)
276
+ {
277
+ CAShift *ca = (CAShift *) ap;
278
+ ca_attach(ca->parent);
279
+ /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
280
+ ca->ptr = malloc_with_check(ca_length(ca));
281
+ }
282
+
283
+ static void
284
+ ca_shift_func_attach (void *ap)
285
+ {
286
+ void ca_shift_attach (CAShift *cb);
287
+
288
+ CAShift *ca = (CAShift *) ap;
289
+ ca_attach(ca->parent);
290
+ /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
291
+ ca->ptr = malloc_with_check(ca_length(ca));
292
+ ca_shift_attach(ca);
293
+ }
294
+
295
+ static void
296
+ ca_shift_func_sync (void *ap)
297
+ {
298
+ CAShift *ca = (CAShift *) ap;
299
+ ca_shift_sync(ca);
300
+ ca_sync(ca->parent);
301
+ }
302
+
303
+ static void
304
+ ca_shift_func_detach (void *ap)
305
+ {
306
+ CAShift *ca = (CAShift *) ap;
307
+ free(ca->ptr);
308
+ ca->ptr = NULL;
309
+ ca_detach(ca->parent);
310
+ }
311
+
312
+ static void
313
+ ca_shift_func_copy_data (void *ap, void *ptr)
314
+ {
315
+ CAShift *ca = (CAShift *) ap;
316
+ char *ptr0 = ca->ptr;
317
+ ca_attach(ca->parent);
318
+ ca->ptr = ptr;
319
+ ca_shift_attach(ca);
320
+ ca->ptr = ptr0;
321
+ ca_detach(ca->parent);
322
+ }
323
+
324
+ static void
325
+ ca_shift_func_sync_data (void *ap, void *ptr)
326
+ {
327
+ CAShift *ca = (CAShift *) ap;
328
+ char *ptr0 = ca->ptr;
329
+ ca_attach(ca->parent);
330
+ ca->ptr = ptr;
331
+ ca_shift_sync(ca);
332
+ ca->ptr = ptr0;
333
+ ca_sync(ca->parent);
334
+ ca_detach(ca->parent);
335
+ }
336
+
337
+ static void
338
+ ca_shift_func_fill_data (void *ap, void *ptr)
339
+ {
340
+ CAShift *ca = (CAShift *) ap;
341
+ ca_attach(ca->parent);
342
+ ca_shift_fill(ca, ptr);
343
+ ca_sync(ca->parent);
344
+ ca_detach(ca->parent);
345
+ }
346
+
347
+ static void
348
+ ca_shift_func_create_mask (void *ap)
349
+ {
350
+ CAShift *ca = (CAShift *) ap;
351
+ boolean8_t one = 1;
352
+ boolean8_t zero = 0;
353
+
354
+ ca_update_mask(ca->parent);
355
+
356
+ if ( ! ca->parent->mask ) {
357
+ ca_create_mask(ca->parent);
358
+ }
359
+
360
+ if ( ca->fill_mask ) {
361
+ ca->mask = (CArray *) ca_shift_new(ca->parent->mask,
362
+ ca->shift, (char *) &one, ca->roll);
363
+ }
364
+ else {
365
+ ca->mask = (CArray *) ca_shift_new(ca->parent->mask,
366
+ ca->shift, (char *) &zero, ca->roll);
367
+ }
368
+ }
369
+
370
+ ca_operation_function_t ca_shift_func = {
371
+ -1, /* CA_OBJ_SHIFT */
372
+ CA_VIRTUAL_ARRAY,
373
+ free_ca_shift,
374
+ ca_shift_func_clone,
375
+ ca_shift_func_ptr_at_addr,
376
+ ca_shift_func_ptr_at_index,
377
+ NULL,
378
+ ca_shift_func_fetch_index,
379
+ NULL,
380
+ ca_shift_func_store_index,
381
+ ca_shift_func_allocate,
382
+ ca_shift_func_attach,
383
+ ca_shift_func_sync,
384
+ ca_shift_func_detach,
385
+ ca_shift_func_copy_data,
386
+ ca_shift_func_sync_data,
387
+ ca_shift_func_fill_data,
388
+ ca_shift_func_create_mask,
389
+ };
390
+
391
+ /* ------------------------------------------------------------------- */
392
+
393
+ static void
394
+ ca_shift_attach_loop (CAShift *ca, int16_t level, int32_t *idx, int32_t *idx0,
395
+ int32_t fill)
396
+ {
397
+ int32_t dim = ca->dim[level];
398
+ int32_t shift = ca->shift[level];
399
+ int8_t roll = ca->roll[level];
400
+ int32_t i;
401
+
402
+ if ( level == ca->rank - 1 ) {
403
+ if ( fill ) {
404
+ for (i=0; i<ca->dim[level]; i++) {
405
+ idx[level] = i;
406
+ memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
407
+ }
408
+ }
409
+ else if ( ! shift ) {
410
+ idx[level] = 0;
411
+ idx0[level] = 0;
412
+ memcpy(ca_ptr_at_index(ca, idx), ca_ptr_at_index(ca->parent, idx0), dim * ca->bytes);
413
+ }
414
+ else if ( roll ) {
415
+ shift = ca_shift_normalized_roll_shift(ca, level);
416
+ if ( shift > 0 ) {
417
+ idx[level] = 0;
418
+ idx0[level] = dim-shift;
419
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), shift*ca->bytes);
420
+ idx[level] = shift;
421
+ idx0[level] = 0;
422
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (dim-shift)*ca->bytes);
423
+ }
424
+ else {
425
+ idx[level] = 0;
426
+ idx0[level] = -shift;
427
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (dim+shift)*ca->bytes);
428
+ idx[level] = dim + shift;
429
+ idx0[level] = 0;
430
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0), (-shift)*ca->bytes);
431
+ }
432
+ }
433
+ else {
434
+ if ( shift > 0 ) {
435
+ shift = ( shift >= dim ) ? dim : shift;
436
+
437
+ for (i=0; i<shift; i++) {
438
+ idx[level] = i;
439
+ memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
440
+ }
441
+
442
+ if ( shift < dim ) {
443
+ idx[level] = shift;
444
+ idx0[level] = 0;
445
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0),(dim-shift)*ca->bytes);
446
+ }
447
+ }
448
+ else {
449
+ shift = ( -shift >= dim ) ? -dim : shift;
450
+
451
+ if ( -shift < dim ) {
452
+ idx[level] = 0;
453
+ idx0[level] = -shift;
454
+ memcpy(ca_ptr_at_index(ca,idx), ca_ptr_at_index(ca->parent,idx0),(dim+shift)*ca->bytes);
455
+ }
456
+
457
+ for (i=0; i<-shift; i++) {
458
+ idx[level] = dim+shift+i;
459
+ memcpy(ca_ptr_at_index(ca, idx), ca->fill, ca->bytes);
460
+ }
461
+ }
462
+ }
463
+ }
464
+ else {
465
+ if ( fill ) {
466
+ for (i=0; i<dim; i++) {
467
+ idx[level] = i;
468
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
469
+ }
470
+ }
471
+ else if ( ! shift ) {
472
+ for (i=0; i<dim; i++) {
473
+ idx[level] = i;
474
+ idx0[level] = i;
475
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
476
+ }
477
+ }
478
+ else if ( roll ) {
479
+ shift = ca_shift_normalized_roll_shift(ca, level);
480
+
481
+ if ( shift > 0 ) {
482
+ for (i=0; i<shift; i++) {
483
+ idx[level] = i;
484
+ idx0[level] = dim-shift+i;
485
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
486
+ }
487
+
488
+ for (i=0; i<dim-shift; i++) {
489
+ idx[level] = shift+i;
490
+ idx0[level] = i;
491
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
492
+ }
493
+ }
494
+ else {
495
+ for (i=0; i<dim+shift; i++) {
496
+ idx[level] = i;
497
+ idx0[level] = -shift+i;
498
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
499
+ }
500
+
501
+ for (i=0; i<-shift; i++) {
502
+ idx[level] = dim + shift + i;
503
+ idx0[level] = i;
504
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
505
+ }
506
+ }
507
+ }
508
+ else {
509
+ if ( shift > 0 ) {
510
+ shift = ( shift >= dim ) ? dim : shift;
511
+
512
+ for (i=0; i<shift; i++) {
513
+ idx[level] = i;
514
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
515
+ }
516
+
517
+ if ( shift < dim ) {
518
+ for (i=0; i<dim-shift; i++) {
519
+ idx[level] = shift+i;
520
+ idx0[level] = i;
521
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
522
+ }
523
+ }
524
+ }
525
+ else {
526
+ shift = ( -shift >= dim ) ? -dim : shift;
527
+
528
+ if ( -shift < dim ) {
529
+ for (i=0; i<dim+shift; i++) {
530
+ idx[level] = i;
531
+ idx0[level] = -shift+i;
532
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 0);
533
+ }
534
+ }
535
+
536
+ for (i=0; i<-shift; i++) {
537
+ idx[level] = dim+shift+i;
538
+ ca_shift_attach_loop(ca, level+1, idx, idx0, 1); /* fill */
539
+ }
540
+ }
541
+ }
542
+ }
543
+ }
544
+
545
+ static void
546
+ ca_shift_attach (CAShift *ca)
547
+ {
548
+ int32_t idx[CA_RANK_MAX];
549
+ int32_t idx0[CA_RANK_MAX];
550
+ ca_shift_attach_loop(ca, (int16_t) 0, idx, idx0, 0);
551
+ }
552
+
553
+ static void
554
+ ca_shift_sync_loop (CAShift *ca, int16_t level, int32_t *idx, int32_t *idx0)
555
+ {
556
+ int32_t dim = ca->dim[level];
557
+ int32_t shift = ca->shift[level];
558
+ int8_t roll = ca->roll[level];
559
+ int32_t i;
560
+
561
+ if ( level == ca->rank - 1 ) {
562
+ if ( ! shift ) {
563
+ idx[level] = 0;
564
+ idx0[level] = 0;
565
+ memcpy(ca_ptr_at_index(ca->parent, idx0), ca_ptr_at_index(ca, idx), dim * ca->bytes);
566
+ }
567
+ else if ( roll ) {
568
+ shift = ca_shift_normalized_roll_shift(ca, level);
569
+
570
+ if ( shift > 0 ) {
571
+ idx[level] = 0;
572
+ idx0[level] = dim-shift;
573
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), shift*ca->bytes);
574
+ idx[level] = shift;
575
+ idx0[level] = 0;
576
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (dim-shift)*ca->bytes);
577
+ }
578
+ else {
579
+ idx[level] = 0;
580
+ idx0[level] = -shift;
581
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (dim+shift)*ca->bytes);
582
+ idx[level] = dim + shift;
583
+ idx0[level] = 0;
584
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx), (-shift)*ca->bytes);
585
+ }
586
+ }
587
+ else {
588
+ if ( shift > 0 ) {
589
+ shift = ( shift >= dim ) ? dim : shift;
590
+
591
+ for (i=0; i<shift; i++) {
592
+ ; /* do nothing */
593
+ }
594
+
595
+ if ( shift < dim ) {
596
+ idx[level] = shift;
597
+ idx0[level] = 0;
598
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx),(dim-shift)*ca->bytes);
599
+ }
600
+ }
601
+ else {
602
+ shift = ( -shift >= dim ) ? -dim : shift;
603
+
604
+ if ( -shift < dim ) {
605
+ idx[level] = 0;
606
+ idx0[level] = -shift;
607
+ memcpy(ca_ptr_at_index(ca->parent,idx0), ca_ptr_at_index(ca,idx),(dim+shift)*ca->bytes);
608
+ }
609
+
610
+ for (i=0; i<-shift; i++) {
611
+ ; /* do nothing */
612
+ }
613
+ }
614
+ }
615
+ }
616
+ else {
617
+ if ( ! shift ) {
618
+ for (i=0; i<dim; i++) {
619
+ idx[level] = i;
620
+ idx0[level] = i;
621
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
622
+ }
623
+ }
624
+ else if ( roll ) {
625
+ shift = ca_shift_normalized_roll_shift(ca, level);
626
+ if ( shift > 0 ) {
627
+ for (i=0; i<shift; i++) {
628
+ idx[level] = i;
629
+ idx0[level] = dim-shift+i;
630
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
631
+ }
632
+
633
+ for (i=0; i<dim-shift; i++) {
634
+ idx[level] = shift+i;
635
+ idx0[level] = i;
636
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
637
+ }
638
+ }
639
+ else {
640
+ for (i=0; i<dim+shift; i++) {
641
+ idx[level] = i;
642
+ idx0[level] = -shift+i;
643
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
644
+ }
645
+
646
+ for (i=0; i<-shift; i++) {
647
+ idx[level] = dim + shift + i;
648
+ idx0[level] = i;
649
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
650
+ }
651
+ }
652
+ }
653
+ else {
654
+ if ( shift > 0 ) {
655
+ shift = ( shift >= dim ) ? dim : shift;
656
+
657
+ for (i=0; i<shift; i++) {
658
+ ; /* do nothing */
659
+ }
660
+
661
+ if ( shift < dim ) {
662
+ for (i=0; i<dim-shift; i++) {
663
+ idx[level] = shift+i;
664
+ idx0[level] = i;
665
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
666
+ }
667
+ }
668
+ }
669
+ else {
670
+ shift = ( -shift >= dim ) ? -dim : shift;
671
+
672
+ if ( -shift < dim ) {
673
+ for (i=0; i<dim+shift; i++) {
674
+ idx[level] = i;
675
+ idx0[level] = -shift+i;
676
+ ca_shift_sync_loop(ca, level+1, idx, idx0);
677
+ }
678
+ }
679
+
680
+ for (i=0; i<-shift; i++) {
681
+ ; /* do nothing */
682
+ }
683
+ }
684
+ }
685
+ }
686
+ }
687
+
688
+ static void
689
+ ca_shift_sync (CAShift *ca)
690
+ {
691
+ int32_t idx[CA_RANK_MAX];
692
+ int32_t idx0[CA_RANK_MAX];
693
+ ca_shift_sync_loop(ca, (int16_t) 0, idx, idx0);
694
+ }
695
+
696
+ static void
697
+ ca_shift_fill_loop (CAShift *ca, char *ptr,
698
+ int16_t level, int32_t *idx0)
699
+ {
700
+ int32_t dim = ca->dim[level];
701
+ int32_t shift = ca->shift[level];
702
+ int8_t roll = ca->roll[level];
703
+ int32_t i;
704
+
705
+ if ( level == ca->rank - 1 ) {
706
+ if ( ( ! shift ) || roll ) {
707
+ for (i=0; i<dim; i++) {
708
+ idx0[level] = i;
709
+ memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
710
+ }
711
+ }
712
+ else {
713
+ if ( shift > 0 ) {
714
+ shift = ( shift >= dim ) ? dim : shift;
715
+
716
+ for (i=0; i<shift; i++) {
717
+ ; /* do nothing */
718
+ }
719
+
720
+ if ( shift < dim ) {
721
+ for (i=0; i<dim-shift; i++) {
722
+ idx0[level] = i;
723
+ memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
724
+ }
725
+ }
726
+ }
727
+ else {
728
+ shift = ( -shift >= dim ) ? -dim : shift;
729
+
730
+ if ( -shift < dim ) {
731
+ for (i=0; i<dim+shift; i++) {
732
+ idx0[level] = -shift+i;
733
+ memcpy(ca_ptr_at_index(ca->parent, idx0), ptr, ca->bytes);
734
+ }
735
+ }
736
+
737
+ for (i=0; i<-shift; i++) {
738
+ ; /* do nothing */
739
+ }
740
+ }
741
+ }
742
+ }
743
+ else {
744
+ if ( ( ! shift ) || roll ) {
745
+ for (i=0; i<dim; i++) {
746
+ idx0[level] = i;
747
+ ca_shift_fill_loop(ca, ptr, level+1, idx0);
748
+ }
749
+ }
750
+ else {
751
+ if ( shift > 0 ) {
752
+ shift = ( shift >= dim ) ? dim : shift;
753
+
754
+ for (i=0; i<shift; i++) {
755
+ ; /* do nothing */
756
+ }
757
+
758
+ if ( shift < dim ) {
759
+ for (i=0; i<dim-shift; i++) {
760
+ idx0[level] = i;
761
+ ca_shift_fill_loop(ca, ptr, level+1, idx0);
762
+ }
763
+ }
764
+ }
765
+ else {
766
+ shift = ( -shift >= dim ) ? -dim : shift;
767
+
768
+ if ( -shift < dim ) {
769
+ for (i=0; i<dim+shift; i++) {
770
+ idx0[level] = -shift+i;
771
+ ca_shift_fill_loop(ca, ptr, level+1, idx0);
772
+ }
773
+ }
774
+
775
+ for (i=0; i<-shift; i++) {
776
+ ; /* do nothing */
777
+ }
778
+ }
779
+ }
780
+ }
781
+ }
782
+
783
+ static void
784
+ ca_shift_fill (CAShift *ca, char *ptr)
785
+ {
786
+ int32_t idx0[CA_RANK_MAX];
787
+ ca_shift_fill_loop(ca, ptr, (int16_t) 0, idx0);
788
+ }
789
+
790
+ /* ------------------------------------------------------------------- */
791
+
792
+ /*
793
+ static VALUE
794
+ rb_ca_shift_set_fill_value (VALUE self, VALUE rfval)
795
+ {
796
+ CAShift *ca;
797
+ CArray *cs;
798
+
799
+ Data_Get_Struct(self, CAShift, ca);
800
+
801
+ if ( NIL_P(rfval) ) {
802
+ memset(ca->fill, 0, ca->bytes);
803
+ }
804
+ else {
805
+ cs = ca_wrap_readonly(rfval, ca->data_type);
806
+ memcpy(ca->fill, cs->ptr, ca->bytes);
807
+ }
808
+
809
+ return rfval;
810
+ }
811
+ */
812
+
813
+ VALUE
814
+ rb_ca_shift_new (VALUE cary, int32_t *shift, char *fill, int8_t *roll)
815
+ {
816
+ volatile VALUE obj;
817
+ CArray *parent;
818
+ CAShift *ca;
819
+ rb_check_carray_object(cary);
820
+ Data_Get_Struct(cary, CArray, parent);
821
+ ca = ca_shift_new(parent, shift, fill, roll);
822
+ obj = ca_wrap_struct(ca);
823
+ rb_ca_set_parent(obj, cary);
824
+ rb_ca_data_type_inherit(obj, cary);
825
+ return obj;
826
+ }
827
+
828
+ /* rdoc:
829
+ class CArray
830
+ def shifted
831
+ end
832
+ end
833
+ */
834
+
835
+ VALUE
836
+ rb_ca_shift (int argc, VALUE *argv, VALUE self)
837
+ {
838
+ volatile VALUE obj, ropt, rfval = CA_NIL, rroll = Qnil, rcs;
839
+ CArray *ca;
840
+ CScalar *cs;
841
+ int32_t shift[CA_RANK_MAX];
842
+ int8_t roll[CA_RANK_MAX];
843
+ char *fill = NULL;
844
+ int32_t i;
845
+
846
+ Data_Get_Struct(self, CArray, ca);
847
+
848
+ ropt = rb_pop_options(&argc, &argv);
849
+ rb_scan_options(ropt, "roll,fill_value", &rroll, &rfval);
850
+
851
+ if ( argc != ca->rank ) {
852
+ rb_raise(rb_eArgError, "# of arguments mismatch with rank");
853
+ }
854
+
855
+ for (i=0; i<ca->rank; i++) {
856
+ shift[i] = NUM2INT(argv[i]);
857
+ }
858
+
859
+ if ( rfval == CA_NIL ) {
860
+ if ( rb_block_given_p() ) {
861
+ rfval = rb_yield(self);
862
+ }
863
+ }
864
+ else {
865
+ /* rb_warn(":fill_value option for CArray#shifted will be obsoleted."); */
866
+ }
867
+
868
+ if ( rfval == CA_NIL ) {
869
+ rcs = rb_cscalar_new(ca->data_type, ca->bytes, NULL);
870
+ Data_Get_Struct(rcs, CScalar, cs);
871
+ fill = cs->ptr;
872
+ if ( ca_is_object_type(ca) ) {
873
+ *(VALUE *)fill = INT2FIX(0);
874
+ }
875
+ else {
876
+ memset(fill, 0, cs->bytes);
877
+ }
878
+ }
879
+ else if ( rfval == CA_UNDEF ) {
880
+ fill = NULL;
881
+ }
882
+ else {
883
+ rcs = rb_cscalar_new_with_value(ca->data_type, ca->bytes, rfval);
884
+ Data_Get_Struct(rcs, CScalar, cs);
885
+ fill = cs->ptr;
886
+ }
887
+
888
+ if ( NIL_P(rroll) ) {
889
+ for (i=0; i<ca->rank; i++) {
890
+ roll[i] = 0;
891
+ }
892
+ }
893
+ else {
894
+ Check_Type(rroll, T_ARRAY);
895
+
896
+ if ( RARRAY_LEN(rroll) != ca->rank ) {
897
+ rb_raise(rb_eArgError, "# of arguments mismatch with rank");
898
+ }
899
+
900
+ for (i=0; i<ca->rank; i++) {
901
+ roll[i] = NUM2INT(rb_ary_entry(rroll, i));
902
+ }
903
+ }
904
+
905
+ obj = rb_ca_shift_new(self, shift, fill, roll);
906
+
907
+ if ( rfval == CA_UNDEF ) {
908
+ CArray *co;
909
+ Data_Get_Struct(obj, CArray, co);
910
+ ca_create_mask(co);
911
+ }
912
+
913
+ return obj;
914
+ }
915
+
916
+ /* ------------------------------------------------------------------- */
917
+
918
+ static VALUE
919
+ rb_ca_shift_s_allocate (VALUE klass)
920
+ {
921
+ CAShift *ca;
922
+ return Data_Make_Struct(klass, CAShift, ca_mark, ca_free, ca);
923
+ }
924
+
925
+ static VALUE
926
+ rb_ca_shift_initialize_copy (VALUE self, VALUE other)
927
+ {
928
+ CAShift *ca, *cs;
929
+
930
+ Data_Get_Struct(self, CAShift, ca);
931
+ Data_Get_Struct(other, CAShift, cs);
932
+
933
+ ca_shift_setup(ca, cs->parent, cs->shift, cs->fill, cs->roll);
934
+
935
+ return self;
936
+ }
937
+
938
+ void
939
+ Init_ca_obj_shift ()
940
+ {
941
+ rb_cCAShift = rb_define_class("CAShift", rb_cCAVirtual);
942
+
943
+ CA_OBJ_SHIFT = ca_install_obj_type(rb_cCAShift, ca_shift_func);
944
+ rb_define_const(rb_cObject, "CA_OBJ_SHIFT", INT2NUM(CA_OBJ_SHIFT));
945
+
946
+ rb_define_method(rb_cCArray, "shifted", rb_ca_shift, -1);
947
+
948
+ rb_define_alloc_func(rb_cCAShift, rb_ca_shift_s_allocate);
949
+ rb_define_method(rb_cCAShift, "initialize_copy",
950
+ rb_ca_shift_initialize_copy, 1);
951
+ }
952
+