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
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'