mdarray 0.4.0-java

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.
Files changed (44) hide show
  1. data/LICENSE.txt +54 -0
  2. data/LICENSE.txt~ +32 -0
  3. data/README.md +21 -0
  4. data/Rakefile +40 -0
  5. data/lib/env.rb +11 -0
  6. data/lib/mdarray.rb +414 -0
  7. data/lib/mdarray/access.rb +237 -0
  8. data/lib/mdarray/counter.rb +779 -0
  9. data/lib/mdarray/creation.rb +413 -0
  10. data/lib/mdarray/fast_non_numerical.rb +102 -0
  11. data/lib/mdarray/function_creation.rb +100 -0
  12. data/lib/mdarray/function_map.rb +56 -0
  13. data/lib/mdarray/hierarchy.rb +177 -0
  14. data/lib/mdarray/operators.rb +220 -0
  15. data/lib/mdarray/printing.rb +275 -0
  16. data/lib/mdarray/proc_util.rb +159 -0
  17. data/lib/mdarray/ruby_functions.rb +78 -0
  18. data/lib/mdarray/ruby_generic_functions.rb +37 -0
  19. data/lib/mdarray/ruby_math.rb +57 -0
  20. data/lib/mdarray/ruby_numeric_functions.rb +187 -0
  21. data/lib/mdarray/ruby_operators.rb +201 -0
  22. data/lib/mdarray/ruby_stats.rb +149 -0
  23. data/lib/mdarray/slices.rb +185 -0
  24. data/lib/mdarray/statistics.rb +86 -0
  25. data/test/arithmetic_casting.rb +195 -0
  26. data/test/env.rb +50 -0
  27. data/test/test_access.rb +247 -0
  28. data/test/test_boolean.rb +67 -0
  29. data/test/test_comparison.rb +126 -0
  30. data/test/test_complete.rb +69 -0
  31. data/test/test_counter.rb +184 -0
  32. data/test/test_creation.rb +364 -0
  33. data/test/test_error.rb +53 -0
  34. data/test/test_lazy.rb +52 -0
  35. data/test/test_operator.rb +337 -0
  36. data/test/test_printing.rb +66 -0
  37. data/test/test_shape.rb +96 -0
  38. data/test/test_slices.rb +146 -0
  39. data/test/test_speed.rb +311 -0
  40. data/test/test_statistics.rb +45 -0
  41. data/test/test_trigonometry.rb +60 -0
  42. data/vendor/netcdfAll-4.3.16.jar +0 -0
  43. data/version.rb +2 -0
  44. metadata +197 -0
@@ -0,0 +1,237 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ class MDArray
23
+
24
+ #------------------------------------------------------------------------------------
25
+ #
26
+ #------------------------------------------------------------------------------------
27
+
28
+ def get_current_index
29
+ @local_iterator.get_current_index
30
+ end
31
+
32
+ #------------------------------------------------------------------------------------
33
+ # Returns the next element of the local_iterator or nil if no next element available
34
+ #------------------------------------------------------------------------------------
35
+
36
+ def next
37
+
38
+ if (@local_iterator && @local_iterator.has_next?)
39
+ @local_iterator.get_next
40
+ else
41
+ nil
42
+ end
43
+
44
+ end
45
+
46
+ #------------------------------------------------------------------------------------
47
+ # When get is used to retrieve an element, it is assumed that the index does not need
48
+ # correction, for instance, no negative index is allowed. If one wants to use
49
+ # negative indexes, then method [] should be used. So mat.get([-1, 0, 0]) raises an
50
+ # exception while mat[-1, 0, 0] gets the last value for the first dimension.
51
+ #------------------------------------------------------------------------------------
52
+
53
+ def [](*index)
54
+
55
+ if (index.size != 0)
56
+ @local_index[*index]
57
+ elsif (@local_iterator)
58
+ @local_iterator.get_current
59
+ else
60
+ raise "No iterator defined! Cannot get element"
61
+ end
62
+
63
+ end
64
+
65
+ #------------------------------------------------------------------------------------
66
+ #
67
+ #------------------------------------------------------------------------------------
68
+
69
+ def get(index = nil)
70
+ @local_index.get(index)
71
+ end
72
+
73
+ #------------------------------------------------------------------------------------
74
+ # Gets the next element of the local iterator
75
+ #------------------------------------------------------------------------------------
76
+
77
+ def get_next
78
+
79
+ if (@local_iterator)
80
+ @local_iterator.get_next
81
+ else
82
+ raise "No iterator defined! Cannot get next element"
83
+ end
84
+
85
+ end
86
+
87
+ #------------------------------------------------------------------------------------
88
+ #
89
+ #------------------------------------------------------------------------------------
90
+
91
+ def []=(*index, value)
92
+
93
+ if (index.size != 0)
94
+ @local_index[index] = value
95
+ elsif (@local_iterator)
96
+ @local_iterator.set_current(value)
97
+ else
98
+ raise "No iterator defined! Cannot set element value"
99
+ end
100
+
101
+ end
102
+
103
+ #---------------------------------------------------------------------------------------
104
+ # When set is used to assign to an element, it is assumed that the index does not need
105
+ # correction, for instance, no negative index is allowed. If one wants to use
106
+ # negative indexes, then method set should be used. So mat[-1, 0, 0] = 10, raises an
107
+ # exection while mat.set([-1, 0, 0], 10) sets the last value for the first dimension.
108
+ # *<tt>index</tt>: array with the index position
109
+ # *<tt>value</tt>: value to be set
110
+ #---------------------------------------------------------------------------------------
111
+
112
+ def set(index, value)
113
+ @local_index.set(index, value)
114
+ end
115
+
116
+ #---------------------------------------------------------------------------------------
117
+ #
118
+ #---------------------------------------------------------------------------------------
119
+
120
+ def set_next(value)
121
+
122
+ if (@local_iterator)
123
+ @local_iterator.set_next(value)
124
+ else
125
+ raise "No iterator defined! Cannot set element value"
126
+ end
127
+
128
+ end
129
+
130
+ #------------------------------------------------------------------------------------
131
+ #
132
+ #------------------------------------------------------------------------------------
133
+
134
+ def get_counter
135
+ Counter.new(self)
136
+ end
137
+
138
+ #------------------------------------------------------------------------------------
139
+ #
140
+ #------------------------------------------------------------------------------------
141
+
142
+ def reset_traversal
143
+ @local_iterator = get_iterator_fast
144
+ end
145
+
146
+ #------------------------------------------------------------------------------------
147
+ #
148
+ #------------------------------------------------------------------------------------
149
+
150
+ def each
151
+
152
+ iterator = get_iterator_fast
153
+ while (iterator.has_next?)
154
+ yield iterator.get_next if block_given?
155
+ end
156
+
157
+ end
158
+
159
+ # (1) Each creates a new iterator and does not touch the @local_iterator so that
160
+ # one should be able to call each from different threads. Still, should be careful
161
+ # if another thread adds or removes elements from the array. Needs to check what
162
+ # happens in this situation
163
+
164
+ #------------------------------------------------------------------------------------
165
+ # Cycles through the whole list of elements yielding to a block (if given) the next
166
+ # element and its index. The index is a ruby array.
167
+ #------------------------------------------------------------------------------------
168
+
169
+ def each_with_counter
170
+
171
+ iterator = get_iterator_fast
172
+ while (iterator.has_next?)
173
+ yield iterator.get_next, iterator.get_current_counter if block_given?
174
+ end
175
+
176
+ end
177
+
178
+ #------------------------------------------------------------------------------------
179
+ # Continues a each from the position the @local_iterator is in. each_cont cannot be
180
+ # called from multiple threads as there is only one @local_iterator.
181
+ #------------------------------------------------------------------------------------
182
+
183
+ def each_cont
184
+
185
+ while (elmt = self.next)
186
+ yield elmt if block_given?
187
+ end
188
+
189
+ end
190
+
191
+ #------------------------------------------------------------------------------------
192
+ #
193
+ #------------------------------------------------------------------------------------
194
+
195
+ def each_along_axes(axes)
196
+
197
+ counter = Counter.new(self)
198
+
199
+ sizes = Array.new
200
+ (0..rank - 1).each do |axis|
201
+ if (axes.include?(axis))
202
+ sizes[axis] = 1
203
+ else
204
+ sizes[axis] = shape[axis]
205
+ end
206
+ end
207
+
208
+ counter.each_along_axes(axes) do |ct|
209
+ # yield ct, sizes if block_given?
210
+ yield section(ct, sizes, true) if block_given?
211
+ end
212
+
213
+ end
214
+
215
+ #------------------------------------------------------------------------------------
216
+ #
217
+ #------------------------------------------------------------------------------------
218
+
219
+ private
220
+
221
+ #------------------------------------------------------------------------------------
222
+ # Cycles through the whole list of elements yielding to a block (if given) the next
223
+ # element and its iterator. Was made private so that users do not need to know about
224
+ # iterator. Giving iterator could be a speed up usefule for final users concerned
225
+ # about performance.
226
+ #------------------------------------------------------------------------------------
227
+
228
+ def each_with_iterator
229
+
230
+ iterator = get_iterator_fast
231
+ while (iterator.has_next?)
232
+ yield iterator.get_next, iterator if block_given?
233
+ end
234
+
235
+ end
236
+
237
+ end
@@ -0,0 +1,779 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ #=========================================================================================
23
+ #
24
+ #=========================================================================================
25
+
26
+ class MDArray
27
+ java_import 'java.lang.ClassCastException'
28
+
29
+ #---------------------------------------------------------------------------------------
30
+ #
31
+ #---------------------------------------------------------------------------------------
32
+
33
+ def get_index
34
+ MDArray::Counter.new(self)
35
+ end
36
+
37
+ #---------------------------------------------------------------------------------------
38
+ # Counters for Multidimensional arrays. A Counter refers to a particular element of an
39
+ # array. This is a generalization of index as int[].
40
+ #---------------------------------------------------------------------------------------
41
+
42
+ class Counter
43
+ include Enumerable
44
+
45
+ attr_reader :mdarray
46
+ attr_reader :nc_index
47
+ attr_reader :shape
48
+ attr_reader :start
49
+ attr_reader :finish
50
+ attr_reader :counter
51
+
52
+ #------------------------------------------------------------------------------------
53
+ #
54
+ #------------------------------------------------------------------------------------
55
+
56
+ def initialize(mdarray)
57
+
58
+ @mdarray = mdarray
59
+ @nc_index = mdarray.nc_array.getIndex()
60
+ @shape = @nc_index.getShape().to_a
61
+
62
+ # by default the starting index is the [0] index (first element)
63
+ shape = @shape.dup
64
+ set_start(shape.fill(0))
65
+ # by default the finish index is the last element of the array
66
+ finish = Array.new
67
+ @shape.each do |val|
68
+ finish << val - 1
69
+ end
70
+
71
+ set_finish(finish)
72
+
73
+ end
74
+
75
+ #-------------------------------------------------------------------------------------
76
+ # Sets the starting position of the index
77
+ #-------------------------------------------------------------------------------------
78
+
79
+ def set_start(start)
80
+
81
+ start = reshape(start)
82
+ if (start[0])
83
+ raise "Cannot set index starting position to an array section"
84
+ else
85
+ @start = start[1].reverse
86
+ reset_counter
87
+ end
88
+
89
+ end
90
+
91
+ #-------------------------------------------------------------------------------------
92
+ # Sets the finishing position of the index
93
+ #-------------------------------------------------------------------------------------
94
+
95
+ def set_finish(finish)
96
+
97
+ finish = reshape(finish)
98
+ if (finish[0])
99
+ raise "Cannot set index finish position to an array section"
100
+ else
101
+ @finish = finish[1].reverse
102
+ end
103
+
104
+ end
105
+
106
+ #-------------------------------------------------------------------------------------
107
+ # Accessor methods for start, finish and position.
108
+ #-------------------------------------------------------------------------------------
109
+
110
+ def start
111
+ @start.reverse
112
+ end
113
+
114
+ def finish
115
+ @finish.reverse
116
+ end
117
+
118
+ def counter
119
+ @counter.reverse
120
+ end
121
+
122
+ #------------------------------------------------------------------------------------
123
+ # Reset the counter to the defined start value
124
+ #------------------------------------------------------------------------------------
125
+
126
+ def reset_counter
127
+ @counter = @start.dup
128
+ end
129
+
130
+ #-------------------------------------------------------------------------------------
131
+ #
132
+ #-------------------------------------------------------------------------------------
133
+
134
+ def each
135
+
136
+ reset_counter
137
+ begin
138
+ yield self.counter if block_given?
139
+ end while(get_next_counter)
140
+
141
+ end
142
+
143
+ #-------------------------------------------------------------------------------------
144
+ # Walks the counter along each of the axes. For instance if given axes [0, 2] and
145
+ # the array shape is [4, 3, 2], then the counter will be [0, 0, 0], [0, 0, 1],
146
+ # [1, 0, 1], [1, 0, 1], [2, 0, 0], ... [3, 0, 1]
147
+ #-------------------------------------------------------------------------------------
148
+
149
+ def each_along_axes(axes)
150
+
151
+ reset_counter
152
+ @axes = axes
153
+
154
+ axis = [0, self.counter.size - 2]
155
+ begin
156
+ yield self.counter, axis[1] if block_given?
157
+ end while (axis = walk_along_axes)
158
+
159
+ end
160
+
161
+ #------------------------------------------------------------------------------------
162
+ # Gets the element at the given counter. If counter is not basic, try to fix it to
163
+ # its basic form.
164
+ #------------------------------------------------------------------------------------
165
+
166
+ def [](*counter)
167
+ set_counter(counter)
168
+ get_at_counter
169
+ end
170
+
171
+ #------------------------------------------------------------------------------------
172
+ # Gets the element at the given counter. Assumes that the counter is of the proper
173
+ # shape.
174
+ #------------------------------------------------------------------------------------
175
+
176
+ def get(counter)
177
+ set_counter_fast(counter)
178
+ get_at_counter
179
+ end
180
+
181
+ #------------------------------------------------------------------------------------
182
+ # Gets element at current counter. Can be done fast, as counter is always of the
183
+ # proper shape.
184
+ #------------------------------------------------------------------------------------
185
+
186
+ def get_current
187
+ set_counter_fast(self.counter)
188
+ get_at_counter
189
+ end
190
+
191
+ #------------------------------------------------------------------------------------
192
+ # Sets the value of counter. If counter is not basic, try to fix it to its basic
193
+ # form.
194
+ #------------------------------------------------------------------------------------
195
+
196
+ def []= (counter, value)
197
+ set_counter(counter)
198
+ set_at_counter(value)
199
+ end
200
+
201
+ #------------------------------------------------------------------------------------
202
+ # Sets the value of counter. Assume that counter is on its basic form.
203
+ #------------------------------------------------------------------------------------
204
+
205
+ def set(counter, value)
206
+ set_counter_fast(counter)
207
+ set_at_counter(value)
208
+ end
209
+
210
+ #------------------------------------------------------------------------------------
211
+ # Sets value of current counter. Can be done fast, as the current counter is always
212
+ # in its basic shape.
213
+ #------------------------------------------------------------------------------------
214
+
215
+ def set_current(value)
216
+ set_counter_fast(self.counter)
217
+ set_at_counter(value)
218
+ end
219
+
220
+ #-------------------------------------------------------------------------------------
221
+ #
222
+ #-------------------------------------------------------------------------------------
223
+
224
+ private
225
+
226
+ #-------------------------------------------------------------------------------------
227
+ # Returns next counter if no overflow, otherwise returns nil
228
+ #-------------------------------------------------------------------------------------
229
+
230
+ def get_next_counter
231
+
232
+ # gets the next counter
233
+ shape = @shape.dup.reverse
234
+
235
+ @counter.each_with_index do |val, index|
236
+
237
+ if val < shape[index] - 1
238
+ @counter[index] = val + 1
239
+ return counter
240
+ else
241
+ @counter[index] = 0
242
+ end
243
+
244
+ end
245
+
246
+ return nil
247
+
248
+ end
249
+
250
+ #-------------------------------------------------------------------------------------
251
+ #
252
+ #-------------------------------------------------------------------------------------
253
+
254
+ def walk_along_axes
255
+
256
+ axes = @axes.dup.reverse
257
+
258
+ axes.each do |axis|
259
+
260
+ index = @counter.size - axis - 1
261
+ if (@counter[index] < @shape[axis] - 1)
262
+ @counter[index] = @counter[index] + 1
263
+ return @counter, axis
264
+ else
265
+ @counter[index] = 0
266
+ end
267
+
268
+ end
269
+
270
+ return nil
271
+
272
+ end
273
+
274
+ #-------------------------------------------------------------------------------------
275
+ # If given index has negative values, then reshape it so that it only has positive
276
+ # values.
277
+ # check if it is a range: regex of the form /x/ or /x:y/ or /x:y:z/
278
+ #-------------------------------------------------------------------------------------
279
+
280
+ def reshape(counter)
281
+
282
+ if (counter.size != @shape.size)
283
+ raise "Counter shape #{counter} is not compatible with iterator shape #{@shape}"
284
+ end
285
+
286
+ reshaped_counter = Array.new
287
+ section = false
288
+
289
+ counter.each_with_index do |val, ind|
290
+
291
+ if (val.is_a? Integer)
292
+ if (val < 0)
293
+ new_ind = @shape[ind] + val
294
+ if (new_ind < 0)
295
+ raise "Counter shape #{counter} is not compatible with iterator shape #{@shape}"
296
+ end
297
+ reshaped_counter[ind] = new_ind
298
+ elsif (val >= @shape[ind])
299
+ raise "Counter shape #{counter} is not compatible with iterator shape #{@shape}"
300
+ else
301
+ reshaped_counter[ind] = counter[ind]
302
+ end
303
+
304
+ elsif (val.is_a? Regexp)
305
+ section = true
306
+ else
307
+ raise "Invalid index format: #{val}"
308
+ end
309
+
310
+ end
311
+
312
+ [section, reshaped_counter]
313
+
314
+ end
315
+
316
+ #-------------------------------------------------------------------------------------
317
+ # Sets this index to point to the given counter. assumes that the counter respects
318
+ # the shape constraints.
319
+ #-------------------------------------------------------------------------------------
320
+
321
+ def set_counter_fast(counter)
322
+
323
+ begin
324
+ @nc_index.set(counter.to_java :int)
325
+ rescue java.lang.ArrayIndexOutOfBoundsException
326
+ raise RangeError, "Invalid counter: #{counter}"
327
+ end
328
+
329
+ end
330
+
331
+ #-------------------------------------------------------------------------------------
332
+ # Sets this index to point to the given counter. If given counter has negative values
333
+ # then convert them to positive values, making sure that the counter respects the
334
+ # shape constraints. The given counter is a list of elements as (2, 3, 3) and not and
335
+ # array.
336
+ #-------------------------------------------------------------------------------------
337
+
338
+ def set_counter(counter)
339
+
340
+ counter = reshape(counter)
341
+ set_counter_fast(counter[1])
342
+
343
+ end
344
+
345
+ #------------------------------------------------------------------------------------
346
+ # Sets the value of the array at counter with value. If type is given, cast the value
347
+ # to type before assignment
348
+ #------------------------------------------------------------------------------------
349
+
350
+ def set_at_counter(value)
351
+
352
+ begin
353
+
354
+ case @type
355
+ when "boolean"
356
+ @mdarray.nc_array.setBoolean(@nc_index, value)
357
+ when "byte"
358
+ @mdarray.nc_array.setByte(@nc_index, value)
359
+ when "char"
360
+ @mdarray.nc_array.setChar(@nc_index, value)
361
+ when "short"
362
+ @mdarray.nc_array.setShort(@nc_index, value)
363
+ when "unsigned"
364
+ @mdarray.nc_array.setUnsigned(@nc_index, value)
365
+ when "int"
366
+ @mdarray.nc_array.setInt(@nc_index, value)
367
+ when "long"
368
+ @mdarray.nc_array.setLong(@nc_index, value)
369
+ when "float"
370
+ @mdarray.nc_array.setFloat(@nc_index, value)
371
+ when "double"
372
+ @mdarray.nc_array.setDouble(@nc_index, value)
373
+ else
374
+ @mdarray.nc_array.setObject(@nc_index, value)
375
+ end
376
+
377
+ rescue ClassCastException
378
+ raise "Cannot cast element to array type"
379
+ end
380
+
381
+ end
382
+
383
+ #------------------------------------------------------------------------------------
384
+ #
385
+ #------------------------------------------------------------------------------------
386
+
387
+ def get_at_counter
388
+
389
+ case @type
390
+ when "boolean"
391
+ @mdarray.nc_array.getBoolean(@nc_index)
392
+ when "byte"
393
+ @mdarra.nc_array.getByte(@nc_index)
394
+ when "char"
395
+ @mdarray.nc_array.getChar(@nc_index)
396
+ when "double"
397
+ @mdarray.nc_array.getDouble(@nc_index)
398
+ when "float"
399
+ @mdarray.nc_array.getFloat(@nc_index)
400
+ when "int"
401
+ @mdarray.nc_array.getInt(@nc_index)
402
+ when "long"
403
+ @mdarray.nc_array.getLong(@nc_index)
404
+ when "short"
405
+ @mdarray.nc_array.getShort(@nc_index)
406
+ when "unsigned"
407
+ @mdarray.nc_array.getUnsigned(@nc_index)
408
+ else
409
+ @mdarray.nc_array.getObject(@nc_index)
410
+ end
411
+
412
+ end
413
+
414
+ #------------------------------------------------------------------------------------
415
+ #
416
+ #------------------------------------------------------------------------------------
417
+
418
+ def set_i(dim, index)
419
+
420
+ index = reshape(index)
421
+
422
+ case dim
423
+ when 0
424
+ @nc_index.set0(index)
425
+ when 1
426
+ @nc_index.set1(index)
427
+ when 2
428
+ @nc_index.set2(index)
429
+ when 3
430
+ @nc_index.set3(index)
431
+ when 4
432
+ @nc_index.set4(index)
433
+ when 5
434
+ @nc_index.set5(index)
435
+ when 6
436
+ @nc_index.set6(index)
437
+ else
438
+ raise "Maximum allowed dimension is 6. Please, use method set to set this index"
439
+ end
440
+
441
+ end
442
+
443
+ #------------------------------------------------------------------------------------
444
+ #
445
+ #------------------------------------------------------------------------------------
446
+
447
+ def set_i_fast(dim, index)
448
+
449
+ case dim
450
+ when 0
451
+ @nc_index.set0(index)
452
+ when 1
453
+ @nc_index.set1(index)
454
+ when 2
455
+ @nc_index.set2(index)
456
+ when 3
457
+ @nc_index.set3(index)
458
+ when 4
459
+ @nc_index.set4(index)
460
+ when 5
461
+ @nc_index.set5(index)
462
+ when 6
463
+ @nc_index.set6(index)
464
+ else
465
+ raise "Maximum allowed dimension is 6. Please, use method set to set this index"
466
+ end
467
+
468
+ end
469
+
470
+ #------------------------------------------------------------------------------------
471
+ # Increment the current element by 1.
472
+ #------------------------------------------------------------------------------------
473
+
474
+ def incr
475
+ @nc_index.incr()
476
+ end
477
+
478
+ #------------------------------------------------------------------------------------
479
+ # Get the length of the ith dimension.
480
+ #------------------------------------------------------------------------------------
481
+
482
+ def get_shape(dim_i)
483
+ @nc_index.getShape(dim_i)
484
+ end
485
+
486
+ #------------------------------------------------------------------------------------
487
+ # Compute total number of elements in the array.
488
+ #------------------------------------------------------------------------------------
489
+
490
+ def compute_size
491
+ @nc_index.computeSize(@mdarray.nc_array.getShape())
492
+ end
493
+
494
+ #------------------------------------------------------------------------------------
495
+ # Gets the current counter from the underlining storage. Should be the same as
496
+ # @counter
497
+ #------------------------------------------------------------------------------------
498
+
499
+ def get_current_counter
500
+ @nc_index.getCurrentCounter().to_a
501
+ end
502
+
503
+ end # Counter
504
+
505
+
506
+ #---------------------------------------------------------------------------------------
507
+ #
508
+ #---------------------------------------------------------------------------------------
509
+
510
+ class IteratorFast
511
+
512
+ attr_reader :mdarray
513
+ attr_reader :iterator
514
+
515
+ #-------------------------------------------------------------------------------------
516
+ #
517
+ #-------------------------------------------------------------------------------------
518
+
519
+ def initialize(mdarray)
520
+ @mdarray = mdarray
521
+ @iterator = mdarray.nc_array.getIndexIterator()
522
+ end
523
+
524
+ #------------------------------------------------------------------------------------
525
+ #
526
+ #------------------------------------------------------------------------------------
527
+
528
+ def has_next?
529
+ @iterator.hasNext()
530
+ end
531
+
532
+ #------------------------------------------------------------------------------------
533
+ #
534
+ #------------------------------------------------------------------------------------
535
+
536
+ def next
537
+ @iterator.next()
538
+ end
539
+
540
+ #------------------------------------------------------------------------------------
541
+ # Returns the current counter as a ruby array
542
+ #------------------------------------------------------------------------------------
543
+
544
+ def get_current_counter
545
+ @iterator.getCurrentCounter().to_a
546
+ end
547
+
548
+ #------------------------------------------------------------------------------------
549
+ #
550
+ #------------------------------------------------------------------------------------
551
+
552
+ def get_current
553
+ @iterator.getObjectCurrent()
554
+ end
555
+
556
+ alias :[] :get_current
557
+
558
+ #------------------------------------------------------------------------------------
559
+ #
560
+ #------------------------------------------------------------------------------------
561
+
562
+ def get_next
563
+ @iterator.getObjectNext()
564
+ end
565
+
566
+ #------------------------------------------------------------------------------------
567
+ #
568
+ #------------------------------------------------------------------------------------
569
+
570
+ def set_current(value)
571
+ @iterator.setObjectCurrent(value)
572
+ end
573
+
574
+ alias :[]= :set_current
575
+
576
+ #------------------------------------------------------------------------------------
577
+ #
578
+ #------------------------------------------------------------------------------------
579
+
580
+ def set_next(value)
581
+ @iterator.setObjectNext(value)
582
+ end
583
+
584
+ end # IteratorFast
585
+
586
+ #---------------------------------------------------------------------------------------
587
+ #
588
+ #---------------------------------------------------------------------------------------
589
+
590
+ class IteratorFastBoolean < IteratorFast
591
+
592
+ def get_current
593
+ @iterator.getBoolenaCurrent
594
+ end
595
+
596
+ def get_next
597
+ @iterator.getBooleanNext
598
+ end
599
+
600
+ def set_current(value)
601
+ @iterator.setBooleanCurrent(value)
602
+ end
603
+
604
+ def set_next(value)
605
+ @iterator.setBooleanNext(value)
606
+ end
607
+
608
+ end # IteratorFastBoolean
609
+
610
+ #---------------------------------------------------------------------------------------
611
+ #
612
+ #---------------------------------------------------------------------------------------
613
+
614
+
615
+ class IteratorFastByte < IteratorFast
616
+
617
+ def get_current
618
+ @iterator.getByteCurrent
619
+ end
620
+
621
+ def get_next
622
+ @iterator.getByteNext
623
+ end
624
+
625
+ def set_current(value)
626
+ @iterator.setByteCurrent(value)
627
+ end
628
+
629
+ def set_next(value)
630
+ @iterator.setByteNext(value)
631
+ end
632
+
633
+ end # IteratorFastByte
634
+
635
+ #---------------------------------------------------------------------------------------
636
+ #
637
+ #---------------------------------------------------------------------------------------
638
+
639
+ class IteratorFastChar < IteratorFast
640
+
641
+ def get_current
642
+ @iterator.getCharCurrent
643
+ end
644
+
645
+ def get_next
646
+ @iterator.getCharNext
647
+ end
648
+
649
+ def set_current(value)
650
+ @iterator.setCharCurrent(value)
651
+ end
652
+
653
+ def set_next(value)
654
+ @iterator.setCharNext(value)
655
+ end
656
+
657
+ end # IteratorFastChar
658
+
659
+ #---------------------------------------------------------------------------------------
660
+ #
661
+ #---------------------------------------------------------------------------------------
662
+
663
+ class IteratorFastShort < IteratorFast
664
+
665
+ def get_current
666
+ @iterator.getShortCurrent
667
+ end
668
+
669
+ def get_next
670
+ @iterator.getShortNext
671
+ end
672
+
673
+ def set_current(value)
674
+ @iterator.setShortCurrent(value)
675
+ end
676
+
677
+ def set_next(value)
678
+ @iterator.setShortNext(value)
679
+ end
680
+
681
+ end # IteratorFastShort
682
+
683
+ #---------------------------------------------------------------------------------------
684
+ #
685
+ #---------------------------------------------------------------------------------------
686
+
687
+ class IteratorFastInt < IteratorFast
688
+
689
+ def get_current
690
+ @iterator.getIntCurrent
691
+ end
692
+
693
+ def get_next
694
+ @iterator.getIntNext
695
+ end
696
+
697
+ def set_current(value)
698
+ @iterator.setIntCurrent(value)
699
+ end
700
+
701
+ def set_next(value)
702
+ @iterator.setIntNext(value)
703
+ end
704
+
705
+ end # IteratorFastInt
706
+
707
+ #---------------------------------------------------------------------------------------
708
+ #
709
+ #---------------------------------------------------------------------------------------
710
+
711
+ class IteratorFastLong < IteratorFast
712
+
713
+ def get_current
714
+ @iterator.getLongCurrent
715
+ end
716
+
717
+ def get_next
718
+ @iterator.getLongNext
719
+ end
720
+
721
+ def set_current(value)
722
+ @iterator.setLongCurrent(value)
723
+ end
724
+
725
+ def set_next(value)
726
+ @iterator.setLongNext(value)
727
+ end
728
+
729
+ end # IteratorFastLong
730
+
731
+ #---------------------------------------------------------------------------------------
732
+ #
733
+ #---------------------------------------------------------------------------------------
734
+
735
+ class IteratorFastFloat < IteratorFast
736
+
737
+ def get_current
738
+ @iterator.getFloatCurrent
739
+ end
740
+
741
+ def get_next
742
+ @iterator.getFloatNext
743
+ end
744
+
745
+ def set_current(value)
746
+ @iterator.setFloatCurrent(value)
747
+ end
748
+
749
+ def set_next(value)
750
+ @iterator.setFloatNext(value)
751
+ end
752
+
753
+ end # IteratorFastFloat
754
+
755
+ #---------------------------------------------------------------------------------------
756
+ #
757
+ #---------------------------------------------------------------------------------------
758
+
759
+ class IteratorFastDouble < IteratorFast
760
+
761
+ def get_current
762
+ @iterator.getDoubleCurrent
763
+ end
764
+
765
+ def get_next
766
+ @iterator.getDoubleNext
767
+ end
768
+
769
+ def set_current(value)
770
+ @iterator.setDoubleCurrent(value)
771
+ end
772
+
773
+ def set_next(value)
774
+ @iterator.setDoubleNext(value)
775
+ end
776
+
777
+ end # IteratorFastDouble
778
+
779
+ end