mdarray 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
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