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
data/LICENSE.txt ADDED
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ #
5
+ # Copyright 1998-2008 University Corporation for Atmospheric Research/Unidata
6
+ #
7
+ # Portions of this software were developed by the Unidata Program at the
8
+ # University Corporation for Atmospheric Research.
9
+ #
10
+ # Access and use of this software shall impose the following obligations
11
+ # and understandings on the user. The user is granted the right, without
12
+ # any fee or cost, to use, copy, modify, alter, enhance and distribute
13
+ # this software, and any derivative works thereof, and its supporting
14
+ # documentation for any purpose whatsoever, provided that this entire
15
+ # notice appears in all copies of the software, derivative works and
16
+ # supporting documentation. Further, UCAR requests that the user credit
17
+ # UCAR/Unidata in any publications that result from the use of this
18
+ # software or in any product that includes this software. The names UCAR
19
+ # and/or Unidata, however, may not be used in any advertising or publicity
20
+ # to endorse or promote any products or commercial entity unless specific
21
+ # written permission is obtained from UCAR/Unidata. The user also
22
+ # understands that UCAR/Unidata is not obligated to provide the user with
23
+ # any support, consulting, training or assistance of any kind with regard
24
+ # to the use, operation and performance of this software nor to provide
25
+ # the user with any updates, revisions, new versions or "bug fixes."
26
+ #
27
+ # THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
28
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30
+ # DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
31
+ # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
32
+ # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
33
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
34
+ # WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
35
+ ##########################################################################################
36
+
37
+ ##########################################################################################
38
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
39
+ # and distribute this software and its documentation, without fee and without a signed
40
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
41
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
42
+ # distributions.
43
+ #
44
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
45
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
46
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
47
+ # POSSIBILITY OF SUCH DAMAGE.
48
+ #
49
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
50
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
51
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
52
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
53
+ # OR MODIFICATIONS.
54
+ ##########################################################################################
data/LICENSE.txt~ ADDED
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright 1998-2008 University Corporation for Atmospheric Research/Unidata
3
+ *
4
+ * Portions of this software were developed by the Unidata Program at the
5
+ * University Corporation for Atmospheric Research.
6
+ *
7
+ * Access and use of this software shall impose the following obligations
8
+ * and understandings on the user. The user is granted the right, without
9
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
10
+ * this software, and any derivative works thereof, and its supporting
11
+ * documentation for any purpose whatsoever, provided that this entire
12
+ * notice appears in all copies of the software, derivative works and
13
+ * supporting documentation. Further, UCAR requests that the user credit
14
+ * UCAR/Unidata in any publications that result from the use of this
15
+ * software or in any product that includes this software. The names UCAR
16
+ * and/or Unidata, however, may not be used in any advertising or publicity
17
+ * to endorse or promote any products or commercial entity unless specific
18
+ * written permission is obtained from UCAR/Unidata. The user also
19
+ * understands that UCAR/Unidata is not obligated to provide the user with
20
+ * any support, consulting, training or assistance of any kind with regard
21
+ * to the use, operation and performance of this software nor to provide
22
+ * the user with any updates, revisions, new versions or "bug fixes."
23
+ *
24
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
25
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
28
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
29
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
30
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
31
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
32
+ */
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ MDArray
2
+ =======
3
+
4
+ MDArray is a multi dimensional array implemented for JRuby with similar functionalities
5
+ (but still less) to numpy and narray by Masahiro Tanaka. MDArray targets specifically JRuby
6
+ as it uses Java-NetCDF library from Unidata (http://www.unidata.ucar.edu).
7
+
8
+ Copying from numpy documentation but also valid for MDArray:
9
+
10
+ MDArray main object is the homogeneous multidimensional array. It is a table of elements
11
+ (usually numbers), all of the same type, indexed by a tuple of positive integers. In
12
+ MDArray dimensions are called axes. The number of axes is rank.
13
+
14
+ For example, the coordinates of a point in 3D space [1, 2, 1] is an array of rank 1,
15
+ because it has one axis. That axis has a length of 3. In example pictured below, the array
16
+ has rank 2 (it is 2-dimensional). The first dimension (axis) has a length of 2, the
17
+ second dimension has a length of 3.
18
+
19
+ [[ 1., 0., 0.],
20
+ [ 0., 1., 2.]]
21
+
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rake/testtask'
2
+ require_relative 'version'
3
+
4
+ name = "#{$gem_name}-#{$version}.gem"
5
+
6
+ rule '.class' => '.java' do |t|
7
+ sh "javac #{t.source}"
8
+ end
9
+
10
+ desc 'default task'
11
+ task :default => [:install_gem]
12
+
13
+ desc 'Makes a Gem'
14
+ task :make_gem do
15
+ sh "gem build #{$gem_name}.gemspec"
16
+ end
17
+
18
+ desc 'Install the gem in the standard location'
19
+ task :install_gem => [:make_gem] do
20
+ sh "gem install #{$gem_name}-#{$version}.gem"
21
+ end
22
+
23
+ desc 'Make documentation'
24
+ task :make_doc do
25
+ sh "yard doc lib/*.rb lib/**/*.rb"
26
+ end
27
+
28
+ desc 'Push project to github'
29
+ task :push do
30
+ sh "git push origin master"
31
+ end
32
+
33
+ =begin
34
+ Rake::TestTask.new do |t|
35
+ t.libs << "test"
36
+ t.test_files = FileList['test/test_complete.rb']
37
+ t.verbose = true
38
+ t.warning = true
39
+ end
40
+ =end
data/lib/env.rb ADDED
@@ -0,0 +1,11 @@
1
+ # Add path to CLASSPATH
2
+
3
+ def add_path(path)
4
+
5
+ $CLASSPATH << `cygpath -p -m #{path}`.tr("\n", "")
6
+
7
+ end
8
+
9
+ add_path("../vendor/netcdfAll-4.3.16.jar")
10
+ add_path(":../vendor/parallelcolt-0.9.4.jar")
11
+ add_path(":../target/mdarray_helper.jar")
data/lib/mdarray.rb ADDED
@@ -0,0 +1,414 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # @author Rodrigo Botafogo
5
+ #
6
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
+ # and distribute this software and its documentation, without fee and without a signed
8
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
9
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
10
+ # distributions.
11
+ #
12
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
13
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
14
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
15
+ # POSSIBILITY OF SUCH DAMAGE.
16
+ #
17
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
19
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
20
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
+ # OR MODIFICATIONS.
22
+ ##########################################################################################
23
+
24
+ require 'map'
25
+ require_relative 'env'
26
+
27
+ ##########################################################################################
28
+ # Superclass for implementations of multidimensional arrays. An Array has a classType
29
+ # which gives the Class of its elements, and a shape which describes the number of
30
+ # elements in each index. The rank is the number of indices. A scalar Array has
31
+ # rank = 0. An Array may have arbitrary rank. The Array size is the total number of
32
+ # elements, which must be less than 2^31 (about 2x10^9).
33
+ #
34
+ # Actual data storage is done with Java 1D arrays and stride index calculations.
35
+ # This makes our Arrays rectangular, i.e. no "ragged arrays" where different elements
36
+ # can have different lengths as in Java multidimensional arrays, which are arrays of
37
+ # arrays.
38
+ #
39
+ # Each primitive Java type (boolean, byte, char, short, int, long, float, double) has
40
+ # a corresponding concrete implementation, e.g. ArrayBoolean, ArrayDouble. Reference
41
+ # types are all implemented using the ArrayObject class, with the exceptions of the
42
+ # reference types that correspond to the primitive types, eg Double.class is mapped
43
+ # to double.class.
44
+ #
45
+ # For efficiency, each Array type implementation has concrete subclasses for ranks 0-7,
46
+ # eg ArrayDouble.D0 is a double array of rank 0, ArrayDouble.D1 is a double array of
47
+ # rank 1, etc. These type and rank specific classes are convenient to work with when you
48
+ # know the type and rank of the Array. Ranks greater than 7 are handled by the
49
+ # type-specific superclass e.g. ArrayDouble. The Array class itself is used for fully
50
+ # general handling of any type and rank array. Use the Array.factory() methods to create
51
+ # Arrays in a general way.
52
+ #
53
+ # The stride index calculations allow logical views to be efficiently implemented, eg
54
+ # subset, transpose, slice, etc. These views use the same data storage as the original
55
+ # Array they # are derived from. The index stride calculations are equally efficient
56
+ # for any composition of logical views.
57
+ #
58
+ # The type, shape and backing storage of an Array are immutable. The data itself is read
59
+ # or written using a Counter or an IndexIterator, which stores any needed state information
60
+ # for efficient traversal. This makes use of Arrays thread-safe (as long as you dont share
61
+ # the Counter or IndexIterator) except for the possibility of non-atomic read/write on
62
+ # long/doubles. If this is the case, you should probably synchronize your calls.
63
+ # Presumably 64-bit CPUs will make those operations atomic also.
64
+ ##########################################################################################
65
+
66
+ class MDArray
67
+ include_package "ucar.ma2"
68
+ include Enumerable
69
+
70
+ attr_reader :type
71
+ attr_reader :nc_array
72
+ attr_reader :local_index # internal helper index for this array
73
+ attr_reader :local_iterator
74
+ # binary_operator and unary_operator are instance variables that allow overwriting the
75
+ # class variables binary_operator and unary_operator
76
+ attr_accessor :binary_operator
77
+ attr_accessor :unary_operator
78
+ attr_accessor :coerced
79
+
80
+ @numerical = ["byte", "short", "int", "long", "float", "double"]
81
+ @non_numerical = ["boolean", "char", "string", "sequence"]
82
+
83
+ class << self
84
+
85
+ attr_accessor :functions
86
+ attr_accessor :function_map
87
+
88
+ attr_reader :numerical
89
+ attr_reader :non_numerical
90
+
91
+ end
92
+
93
+ MDArray.function_map = Map.new
94
+
95
+ #------------------------------------------------------------------------------------
96
+ # Initializes an MDArray
97
+ # @param type [String] the type of the mdarray: boolean, byte, int, short, long,
98
+ # float, double
99
+ # @param storage [Array] a ruby array with the initialization data to the MDArray
100
+ # @param section True if this is an mdarray section
101
+ #------------------------------------------------------------------------------------
102
+
103
+ def initialize(type, storage, section = false)
104
+
105
+ @type = type
106
+ @nc_array = storage
107
+ @local_index = Counter.new(self)
108
+ @local_iterator = nil
109
+ @section = section
110
+ @coerced = false # should never be set by the user! For internal use only!
111
+
112
+ # initialize printing defaults
113
+ printing_defaults
114
+
115
+ end
116
+
117
+ #------------------------------------------------------------------------------------
118
+ # Get the number of dimensions of the array.
119
+ #------------------------------------------------------------------------------------
120
+
121
+ def get_rank
122
+ @nc_array.getRank()
123
+ end
124
+
125
+ alias ndim :get_rank
126
+ alias rank :get_rank
127
+
128
+ #------------------------------------------------------------------------------------
129
+ # Gets the size of the array.
130
+ #------------------------------------------------------------------------------------
131
+
132
+ def get_size
133
+ @nc_array.getSize()
134
+ end
135
+
136
+ alias size :get_size
137
+
138
+ #------------------------------------------------------------------------------------
139
+ # Gets the shape of the array
140
+ #------------------------------------------------------------------------------------
141
+
142
+ def get_shape
143
+ @nc_array.getShape().to_a
144
+ end
145
+
146
+ alias shape :get_shape
147
+
148
+ #------------------------------------------------------------------------------------
149
+ # Gets the element type of this array
150
+ #------------------------------------------------------------------------------------
151
+
152
+ def get_element_type
153
+ @nc_array.getElementType().toString()
154
+ end
155
+
156
+ alias dtype :get_element_type
157
+
158
+ #------------------------------------------------------------------------------------
159
+ # Prints the content of the netcdf_array. Mainly for debugging purposes.
160
+ # @param max_size [int]
161
+ #------------------------------------------------------------------------------------
162
+
163
+ def to_string(max_size = 3)
164
+ if (size > max_size * 2)
165
+ @nc_array.toString()
166
+ else
167
+ @nc_array.toString()
168
+ end
169
+
170
+ end
171
+
172
+ #------------------------------------------------------------------------------------
173
+ # Prints the array
174
+ #------------------------------------------------------------------------------------
175
+
176
+ def to_s
177
+ self.print
178
+ end
179
+
180
+ #------------------------------------------------------------------------------------
181
+ # Method to print all elements of the array for debuging purposes only. Does not
182
+ # need to be very efficient.
183
+ #------------------------------------------------------------------------------------
184
+
185
+ def ndenumerate
186
+
187
+ reset_traversal
188
+ while (@local_iterator.has_next?) do
189
+ @local_iterator.next
190
+ print "#{get_current_index} #{@local_iterator.get_current}\n"
191
+ end
192
+
193
+ end
194
+
195
+ #---------------------------------------------------------------------------------------
196
+ # Checks to see if this array is compatible with another array. Two arrays are
197
+ # compatible if they have the same shape
198
+ #---------------------------------------------------------------------------------------
199
+
200
+ def compatible(array)
201
+ (get_shape == array.get_shape)? true : false
202
+ end
203
+
204
+ #---------------------------------------------------------------------------------------
205
+ # Returns the upcasted type between the type of this array and another array
206
+ # @param other_val [MDArray] the other array
207
+ # @param force_cast [Type] will return force_cast. This is used when one wants to
208
+ # force the resulting type on a new array.
209
+ # @return upcasted type between the two arrays or forced type
210
+ #---------------------------------------------------------------------------------------
211
+
212
+ def get_type(other_val, force_cast = nil)
213
+
214
+ if (force_cast != nil)
215
+ type = force_cast
216
+ elsif (other_val.is_a? Numeric)
217
+ # if type is integer, then make it the smaller possible integer and then let upcast
218
+ # do its work
219
+ if (other_val.integer?)
220
+ type = "short"
221
+ else
222
+ type = "double"
223
+ end
224
+ type = MDArray.upcast(@type, type)
225
+ else
226
+ type = MDArray.upcast(@type, other_val.type)
227
+ end
228
+
229
+ return type
230
+
231
+ end
232
+
233
+ #---------------------------------------------------------------------------------------
234
+ # Prints a list of all available functions know to MDArray. Should be reimplemented.
235
+ # For debuging only for now.
236
+ #---------------------------------------------------------------------------------------
237
+
238
+ def self.print_function_map
239
+
240
+ MDArray.function_map.each_pair do |key, value|
241
+
242
+ value.each do |func|
243
+
244
+ p "scope: #{func.scope}, short name: #{key}, long name: #{func.long_name}, return type: #{func.return_type}, input1 type: #{func.input1_type}, input2 type: #{func.input2_type}"
245
+
246
+ end
247
+
248
+ end
249
+
250
+ end # print_function_map
251
+
252
+ #---------------------------------------------------------------------------------------
253
+ # Prints a list of all available functions know to MDArray is csv. Should be
254
+ # reimplemented. For debuging only for now.
255
+ #---------------------------------------------------------------------------------------
256
+
257
+ def self.function_map_to_csv
258
+
259
+ p "scope, short name, long name, return type, input1 type, input2 type"
260
+
261
+ MDArray.function_map.each_pair do |key, value|
262
+ value.each do |func|
263
+ p "#{func.scope}, #{key}, #{func.long_name}, #{func.return_type}, #{func.input1_type}, #{func.input2_type}"
264
+ end
265
+ end
266
+
267
+ end # print_function_map
268
+
269
+ #------------------------------------------------------------------------------------
270
+ # Makes a new binary operator for this MDArray. All binary operators are created
271
+ # using this method or the one in module FunctionCreation.
272
+ # @param name [String] name of the new binary operator
273
+ # @param exec_type execution type of the binary operator. Existing execution types
274
+ # at present are: :default, :fill, :in_place, :reduce.
275
+ # @param func the function to be applied for this binary operator. For instance,
276
+ # lets say we are build the "add" binary operator. exec_type is :default, func
277
+ # is a ruby proc Proc.new { |val1, val2| val1 + val2 }
278
+ # @param force_type forces the type of the resulting array after executing the
279
+ # binary operator. For instance, if we force type "int", then even adding two
280
+ # double arrays the resulting array will be of type int
281
+ # @param pre_condition Proc to be executed before the operator's execution
282
+ # @param post_condition Proc to be executed after the operator's execution
283
+ #------------------------------------------------------------------------------------
284
+
285
+ def self.make_binary_op(name, exec_type, func, force_type = nil, pre_condition = nil,
286
+ post_condition = nil)
287
+
288
+ define_method(name) do |op2, requested_type = nil, *args|
289
+ binary_op = get_binary_op
290
+ op = binary_op.new(name, exec_type, force_type, pre_condition, post_condition)
291
+ op.exec(self, op2, requested_type, *args)
292
+ end
293
+
294
+ MDArray.register_function(name, func)
295
+
296
+ end
297
+
298
+ #------------------------------------------------------------------------------------
299
+ # Makes a new unary operator for this MDArray. All unary operators are created
300
+ # using this method or the one in module FunctionCreation.
301
+ # @param name [String] name of the new binary operator
302
+ # @param exec_type execution type of the binary operator. Existing execution types
303
+ # at present are: :default, :fill, :in_place, :reduce.
304
+ # @param func the function to be applied for this binary operator. For instance,
305
+ # lets say we are build the "add" binary operator. exec_type is :default, func
306
+ # is a ruby proc Proc.new { |val1, val2| val1 + val2 }
307
+ # @param force_type forces the type of the resulting array after executing the
308
+ # binary operator. For instance, if we force type "int", then even adding two
309
+ # double arrays the resulting array will be of type int
310
+ # @param pre_condition Proc to be executed before the operator's execution
311
+ # @param post_condition Proc to be executed after the operator's execution
312
+ #------------------------------------------------------------------------------------
313
+
314
+ def self.make_unary_op(name, exec_type, func, force_type = nil, pre_condition = nil,
315
+ post_condition = nil)
316
+
317
+ define_method(name) do |requested_type = nil, *args|
318
+ unary_op = get_unary_op
319
+ op = unary_op.new(name, exec_type, force_type, pre_condition, post_condition)
320
+ op.exec(self, requested_type, *args)
321
+ end
322
+
323
+ MDArray.register_function(name, func)
324
+
325
+ end
326
+
327
+ #---------------------------------------------------------------------------------------
328
+ # Selects the best function to use at execution time for a given operation. MDArray
329
+ # allow for many implementations of the same function. For instance, one could
330
+ # implement the add operation as a ruby proc Proc.new { |val1, val2| val1 + val2 } or
331
+ # as a Java method. At execution time the system will select the best function to
332
+ # execute given a set of decision paramenters.
333
+ # At this time, this method needs to be improved.
334
+ # @param name the name of the function
335
+ # @param scope [String] a given scope defined by the user, used as a decision parameter
336
+ # @param return_type the return type of the function
337
+ # @param input1_type the type of the first argument to the function
338
+ # @param input2_type the type of the second argument to the function
339
+ #---------------------------------------------------------------------------------------
340
+
341
+ def self.select_function(name, scope = nil, return_type = nil, input1_type = nil,
342
+ input2_type = nil)
343
+
344
+ list = MDArray.function_map[name]
345
+ best_value = -1
346
+ func = nil
347
+
348
+ list.each do |function|
349
+
350
+ value = 0
351
+ value += (scope == function.scope)? 8 : 0
352
+ value += (return_type == function.return_type)? 4 : 0
353
+ value += (input1_type == function.input1_type)? 2 : 0
354
+ value += (input2_type == function.input2_type)? 1 : 0
355
+ if (value > best_value)
356
+ func = function.function
357
+ best_value = value
358
+ # p "best value: #{best_value}, func: #{func}"
359
+ end
360
+ end
361
+
362
+ func
363
+
364
+ end
365
+
366
+ #------------------------------------------------------------------------------------
367
+ # Methods that are implemented in subclasses and are not really necessary, they are
368
+ # used only if MDArray is created with some of the capitalized types, e.g., Double
369
+ # Integer, etc. instead of double, integer which are preferred and execute faster.
370
+ #------------------------------------------------------------------------------------
371
+
372
+ #------------------------------------------------------------------------------------
373
+ # @return IteratorFast a fast iterator onto the this array.
374
+ #------------------------------------------------------------------------------------
375
+
376
+ def get_iterator_fast
377
+
378
+ case type
379
+ when "boolean"
380
+ IteratorFastBoolean.new(self)
381
+ when "char"
382
+ IteratorFastChar.new(self)
383
+ when "short"
384
+ IteratorFastShort.new(self)
385
+ when "int"
386
+ IteratorFastInt.new(self)
387
+ when "long"
388
+ IteratorFastLong.new(self)
389
+ when "float"
390
+ IteratorFastFloat.new(self)
391
+ when "double"
392
+ IteratorFastDouble.new(self)
393
+ else
394
+ IteratorFast.new(self)
395
+ end
396
+
397
+ end
398
+
399
+ end
400
+
401
+ require_relative 'mdarray/proc_util'
402
+ require_relative 'mdarray/function_map'
403
+ require_relative 'mdarray/creation'
404
+ require_relative 'mdarray/hierarchy'
405
+ require_relative 'mdarray/function_creation'
406
+ require_relative 'mdarray/ruby_functions'
407
+ require_relative 'mdarray/operators'
408
+ require_relative 'mdarray/ruby_operators'
409
+ # require_relative 'mdarray/fast_non_numerical'
410
+ require_relative 'mdarray/access'
411
+ require_relative 'mdarray/slices'
412
+ require_relative 'mdarray/printing'
413
+ require_relative 'mdarray/counter'
414
+ # require_relative 'mdarray/statistics'