mdarray 0.4.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +54 -0
- data/LICENSE.txt~ +32 -0
- data/README.md +21 -0
- data/Rakefile +40 -0
- data/lib/env.rb +11 -0
- data/lib/mdarray.rb +414 -0
- data/lib/mdarray/access.rb +237 -0
- data/lib/mdarray/counter.rb +779 -0
- data/lib/mdarray/creation.rb +413 -0
- data/lib/mdarray/fast_non_numerical.rb +102 -0
- data/lib/mdarray/function_creation.rb +100 -0
- data/lib/mdarray/function_map.rb +56 -0
- data/lib/mdarray/hierarchy.rb +177 -0
- data/lib/mdarray/operators.rb +220 -0
- data/lib/mdarray/printing.rb +275 -0
- data/lib/mdarray/proc_util.rb +159 -0
- data/lib/mdarray/ruby_functions.rb +78 -0
- data/lib/mdarray/ruby_generic_functions.rb +37 -0
- data/lib/mdarray/ruby_math.rb +57 -0
- data/lib/mdarray/ruby_numeric_functions.rb +187 -0
- data/lib/mdarray/ruby_operators.rb +201 -0
- data/lib/mdarray/ruby_stats.rb +149 -0
- data/lib/mdarray/slices.rb +185 -0
- data/lib/mdarray/statistics.rb +86 -0
- data/test/arithmetic_casting.rb +195 -0
- data/test/env.rb +50 -0
- data/test/test_access.rb +247 -0
- data/test/test_boolean.rb +67 -0
- data/test/test_comparison.rb +126 -0
- data/test/test_complete.rb +69 -0
- data/test/test_counter.rb +184 -0
- data/test/test_creation.rb +364 -0
- data/test/test_error.rb +53 -0
- data/test/test_lazy.rb +52 -0
- data/test/test_operator.rb +337 -0
- data/test/test_printing.rb +66 -0
- data/test/test_shape.rb +96 -0
- data/test/test_slices.rb +146 -0
- data/test/test_speed.rb +311 -0
- data/test/test_statistics.rb +45 -0
- data/test/test_trigonometry.rb +60 -0
- data/vendor/netcdfAll-4.3.16.jar +0 -0
- data/version.rb +2 -0
- 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
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'
|