mdarray 0.4.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/LICENSE.txt +54 -0
  2. data/LICENSE.txt~ +32 -0
  3. data/README.md +21 -0
  4. data/Rakefile +40 -0
  5. data/lib/env.rb +11 -0
  6. data/lib/mdarray.rb +414 -0
  7. data/lib/mdarray/access.rb +237 -0
  8. data/lib/mdarray/counter.rb +779 -0
  9. data/lib/mdarray/creation.rb +413 -0
  10. data/lib/mdarray/fast_non_numerical.rb +102 -0
  11. data/lib/mdarray/function_creation.rb +100 -0
  12. data/lib/mdarray/function_map.rb +56 -0
  13. data/lib/mdarray/hierarchy.rb +177 -0
  14. data/lib/mdarray/operators.rb +220 -0
  15. data/lib/mdarray/printing.rb +275 -0
  16. data/lib/mdarray/proc_util.rb +159 -0
  17. data/lib/mdarray/ruby_functions.rb +78 -0
  18. data/lib/mdarray/ruby_generic_functions.rb +37 -0
  19. data/lib/mdarray/ruby_math.rb +57 -0
  20. data/lib/mdarray/ruby_numeric_functions.rb +187 -0
  21. data/lib/mdarray/ruby_operators.rb +201 -0
  22. data/lib/mdarray/ruby_stats.rb +149 -0
  23. data/lib/mdarray/slices.rb +185 -0
  24. data/lib/mdarray/statistics.rb +86 -0
  25. data/test/arithmetic_casting.rb +195 -0
  26. data/test/env.rb +50 -0
  27. data/test/test_access.rb +247 -0
  28. data/test/test_boolean.rb +67 -0
  29. data/test/test_comparison.rb +126 -0
  30. data/test/test_complete.rb +69 -0
  31. data/test/test_counter.rb +184 -0
  32. data/test/test_creation.rb +364 -0
  33. data/test/test_error.rb +53 -0
  34. data/test/test_lazy.rb +52 -0
  35. data/test/test_operator.rb +337 -0
  36. data/test/test_printing.rb +66 -0
  37. data/test/test_shape.rb +96 -0
  38. data/test/test_slices.rb +146 -0
  39. data/test/test_speed.rb +311 -0
  40. data/test/test_statistics.rb +45 -0
  41. data/test/test_trigonometry.rb +60 -0
  42. data/vendor/netcdfAll-4.3.16.jar +0 -0
  43. data/version.rb +2 -0
  44. metadata +197 -0
@@ -0,0 +1,275 @@
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
+
28
+ # attributes necessary for printing
29
+ attr_writer :nan_str
30
+ attr_writer :inf_str
31
+ attr_writer :summary_edge_items
32
+ attr_writer :summary_threshold
33
+
34
+ attr_writer :max_line_width
35
+ attr_writer :separator
36
+ attr_writer :prefix
37
+ attr_writer :formatter
38
+
39
+ attr_writer :int_output_size
40
+ attr_writer :float_output_precision
41
+ attr_writer :float_output_suppress_small
42
+
43
+ #------------------------------------------------------------------------------------
44
+ #
45
+ #------------------------------------------------------------------------------------
46
+
47
+ def printing_defaults
48
+
49
+ @nan_str = "nan"
50
+ @inf_str = "inf"
51
+ @summary_edge_items = 3 # repr N leading and trailing items of each dimension
52
+ @summary_threshold = 1000 # total items > triggers array summarization
53
+
54
+ @max_line_width = 80
55
+ @separator = " "
56
+ @prefix = " "
57
+
58
+ @int_output_size = 2
59
+ @float_output_precision = 2
60
+ @float_output_suppress_small = false
61
+
62
+ case type
63
+ when "int"
64
+ @formatter = method(:integer_formatter)
65
+ when "float"
66
+ @formatter = method(:float_formatter)
67
+ when "double"
68
+ @formatter = method(:float_formatter)
69
+ else
70
+ @formatter = method(:default_formatter)
71
+ end
72
+
73
+ end
74
+
75
+ #------------------------------------------------------------------------------------
76
+ #
77
+ #------------------------------------------------------------------------------------
78
+
79
+ def print
80
+ (rank == 1)? print1d : printnd
81
+ Kernel.print "\n"
82
+ end
83
+
84
+ #------------------------------------------------------------------------------------
85
+ #
86
+ #------------------------------------------------------------------------------------
87
+
88
+ def csv1d
89
+
90
+ each_with_counter do |elmt, index|
91
+ if (!is_zero?(index))
92
+ Kernel.print @separator
93
+ end
94
+ Kernel.printf @formatter.call(elmt)
95
+ end
96
+ Kernel.print "\n"
97
+
98
+ end
99
+
100
+ #------------------------------------------------------------------------------------
101
+ #
102
+ #------------------------------------------------------------------------------------
103
+
104
+ def to_csv
105
+
106
+ @separator = ", "
107
+
108
+ counter = Counter.new(self)
109
+ # find the axes and sizes
110
+ axes = Array.new
111
+ sizes = Array.new
112
+ (0..(rank - 2)).each do |val|
113
+ axes << val
114
+ sizes << 1
115
+ end
116
+ sizes << shape[rank - 1]
117
+
118
+ counter.each_along_axes(axes) do |ct, axis|
119
+ (0..ct.size - 2).each do |i|
120
+ Kernel.print ct[i]
121
+ Kernel.print @separator
122
+ end
123
+ section(ct, sizes).csv1d
124
+ end
125
+
126
+ end
127
+
128
+ #------------------------------------------------------------------------------------
129
+ #
130
+ #------------------------------------------------------------------------------------
131
+
132
+ def print1d
133
+
134
+ Kernel.print "["
135
+ each_with_counter do |elmt, index|
136
+ if (!is_zero?(index))
137
+ Kernel.print @separator
138
+ end
139
+ Kernel.printf @formatter.call(elmt)
140
+ end
141
+ Kernel.print "]"
142
+
143
+ end
144
+
145
+ #------------------------------------------------------------------------------------
146
+ #
147
+ #------------------------------------------------------------------------------------
148
+
149
+ def apply_over_axes(axes)
150
+
151
+ counter = Counter.new(self)
152
+ # find the axes and sizes
153
+ slice = Array.new(rank, 0)
154
+ sizes = Array.new(rank, 1)
155
+ (0..rank).each do |i|
156
+ if (axes[i] != i)
157
+ sizes[i] = shape[i]
158
+ end
159
+ end
160
+
161
+ p "axes: #{axes}, slice: #{slice}, sizes: #{sizes}"
162
+
163
+ counter.each_along_axes(axes) do |ct, axis|
164
+ section(ct, sizes)
165
+ end
166
+
167
+ end
168
+
169
+ #------------------------------------------------------------------------------------
170
+ #
171
+ #------------------------------------------------------------------------------------
172
+
173
+ private
174
+
175
+ #------------------------------------------------------------------------------------
176
+ #
177
+ #------------------------------------------------------------------------------------
178
+
179
+ def integer_formatter(integer)
180
+ # "%0#{@int_output_size}d" % integer
181
+ integer.to_s
182
+ end
183
+
184
+ #------------------------------------------------------------------------------------
185
+ #
186
+ #------------------------------------------------------------------------------------
187
+
188
+ def float_formatter(float)
189
+ "%.#{@float_output_precision}f" % float
190
+ end
191
+
192
+ #------------------------------------------------------------------------------------
193
+ #
194
+ #------------------------------------------------------------------------------------
195
+
196
+ def default_formatter(val)
197
+ val.to_s
198
+ end
199
+
200
+ #------------------------------------------------------------------------------------
201
+ #
202
+ #------------------------------------------------------------------------------------
203
+
204
+ def is_zero?(counter)
205
+
206
+ counter.each do |i|
207
+ if (i != 0)
208
+ return false
209
+ end
210
+ end
211
+ return true
212
+
213
+ end
214
+
215
+ #------------------------------------------------------------------------------------
216
+ #
217
+ #------------------------------------------------------------------------------------
218
+
219
+ def printnd
220
+
221
+ counter = Counter.new(self)
222
+ # find the axes and sizes
223
+ axes = Array.new
224
+ sizes = Array.new
225
+ (0..(rank - 2)).each do |val|
226
+ axes << val
227
+ sizes << 1
228
+ end
229
+ sizes << shape[rank - 1]
230
+
231
+ Kernel.print "[" * (rank - 1)
232
+ last_axis = -1
233
+ counter.each_along_axes(axes) do |ct, axis|
234
+
235
+ if (axis == last_axis)
236
+ Kernel.print "\n"
237
+ Kernel.print @prefix * (axis + 1)
238
+ elsif (axis < last_axis)
239
+ Kernel.print "]" * (last_axis - axis) + "\n\n"
240
+ Kernel.print @prefix * (axis + 1)
241
+ Kernel.print "[" * (last_axis - axis)
242
+ axis = last_axis
243
+ end
244
+
245
+ section(ct, sizes).print1d
246
+ last_axis = rank - 2
247
+
248
+ end
249
+
250
+ Kernel.print "]" * (rank - 1) + "\n"
251
+
252
+ end
253
+
254
+ #------------------------------------------------------------------------------------
255
+ #
256
+ #------------------------------------------------------------------------------------
257
+
258
+ def copy_print_parameters(section)
259
+
260
+ # section printing paramters should be the same as the original MDArray
261
+ section.nan_str = @nan_str
262
+ section.inf_str = @inf_str
263
+ section.summary_edge_items = @summary_edge_items
264
+ section.summary_threshold = @summary_threshold
265
+ section.max_line_width = @max_line_width
266
+ section.separator = @separator
267
+ section.prefix = @prefix
268
+ section.int_output_size = @int_output_size
269
+ section.float_output_precision = @float_output_precision
270
+ section.float_output_suppress_small = @float_output_suppress_small
271
+
272
+ end
273
+
274
+ end # MDArray
275
+
@@ -0,0 +1,159 @@
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
+ # Proc methods
25
+ #=========================================================================================
26
+
27
+ class Proc
28
+
29
+ #------------------------------------------------------------------------------------
30
+ #
31
+ #------------------------------------------------------------------------------------
32
+
33
+ def self.compose(f, g)
34
+ lambda { |*args| f[g[*args]] }
35
+ end
36
+
37
+ #------------------------------------------------------------------------------------
38
+ #
39
+ #------------------------------------------------------------------------------------
40
+
41
+ def *(g)
42
+ Proc.compose(self, g)
43
+ end
44
+
45
+ #------------------------------------------------------------------------------------
46
+ # Builds a function that returns true
47
+ # when 'f' returns false, and vice versa.
48
+ #------------------------------------------------------------------------------------
49
+
50
+ def self.complement f
51
+ lambda {|*args| not f.call(*args) }
52
+ end
53
+
54
+ #------------------------------------------------------------------------------------
55
+ #
56
+ #------------------------------------------------------------------------------------
57
+
58
+ def neg
59
+ Proc.complement(self)
60
+ end
61
+
62
+ #------------------------------------------------------------------------------------
63
+ # Builds a function which returns true
64
+ # whenever _every_ function in 'predicates'
65
+ # returns true.
66
+ #------------------------------------------------------------------------------------
67
+
68
+ def self.conjoin(*predicates)
69
+
70
+ base = lambda {|*args| true }
71
+ predicates.inject(base) do |built, pred|
72
+ lambda do |*args|
73
+ built.call(*args) && pred.call(*args)
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ #------------------------------------------------------------------------------------
80
+ # Builds a function which returns true
81
+ # whenever _any_ function in 'predicates'
82
+ # returns true.
83
+ #------------------------------------------------------------------------------------
84
+
85
+ def self.disjoin(*predicates)
86
+
87
+ base = lambda {|*args| false }
88
+ predicates.inject(base) do |built, pred|
89
+ lambda do |*args|
90
+ built.call(*args) || pred.call(*args)
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ #------------------------------------------------------------------------------------
97
+ # This method binds the 1st argument of a binary function to a scalar value,
98
+ # effectively enabling a binary function to be called in a context intended for a
99
+ # unary function.
100
+ #------------------------------------------------------------------------------------
101
+
102
+ def bind1st(val)
103
+ lambda { |arg| self.call(val, arg) }
104
+ end
105
+
106
+ #------------------------------------------------------------------------------------
107
+ # This method binds the 2nd argument of a binary function to a scalar value,
108
+ # effectively enabling a binary function to be called in a context intended for a
109
+ # unary function.
110
+ #------------------------------------------------------------------------------------
111
+
112
+ def bind2nd(val)
113
+ lambda { |arg| self.call(arg,val) }
114
+ end
115
+
116
+ #------------------------------------------------------------------------------------
117
+ # This class verifies a condition and if true, returns the evaluation of a function,
118
+ # otherwise returns NaN.
119
+ #------------------------------------------------------------------------------------
120
+
121
+ def self.clipped(predicate, method)
122
+ lambda { |*args| predicate.call(*args)? method.call(*args) : Float::NAN }
123
+ end
124
+
125
+ #------------------------------------------------------------------------------------
126
+ # Returns a constant value
127
+ #------------------------------------------------------------------------------------
128
+
129
+ def self.constant(val)
130
+ lambda { |arg| return val }
131
+ end
132
+
133
+ #------------------------------------------------------------------------------------
134
+ # Always returns true
135
+ #------------------------------------------------------------------------------------
136
+
137
+ def self.everywhere
138
+ lambda { |arg| return true}
139
+ end
140
+
141
+ #------------------------------------------------------------------------------------
142
+ # Always returns false
143
+ #------------------------------------------------------------------------------------
144
+
145
+ def self.nowhere
146
+ lambda { |arg| return false}
147
+ end
148
+
149
+ #------------------------------------------------------------------------------------
150
+ # The identity function
151
+ #------------------------------------------------------------------------------------
152
+
153
+ def self.identity
154
+ lambda { |arg| return arg }
155
+ end
156
+
157
+ end # Proc
158
+
159
+
@@ -0,0 +1,78 @@
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
+ module RubyFunctions
27
+
28
+ def ruby_binary_function(long_name, proc)
29
+ [long_name, "RubyFunctions", proc, "*", "*", "*"]
30
+ end
31
+
32
+ def ruby_unary_function(long_name, proc)
33
+ [long_name, "RubyFunctions", proc, "*", "*", "*"]
34
+ end
35
+
36
+ end # RubyFunctions
37
+
38
+ ##########################################################################################
39
+ #
40
+ ##########################################################################################
41
+
42
+ module UserFunction
43
+ extend RubyFunctions
44
+
45
+ #---------------------------------------------------------------------------------------
46
+ # Creates a binary operator in the given class. For direct creation of operators
47
+ # directly by the user.
48
+ #---------------------------------------------------------------------------------------
49
+
50
+ def self.binary_operator(name, exec_type, func, where, force_type = nil,
51
+ pre_condition = nil, post_condition = nil)
52
+
53
+ function = ruby_binary_function("#{name}_user", func)
54
+ klass = Object.const_get("#{where.capitalize}MDArray")
55
+ klass.make_binary_op(name, exec_type, function, force_type, pre_condition, post_condition)
56
+
57
+ end
58
+
59
+ #---------------------------------------------------------------------------------------
60
+ # Creates a unary operator in the given class. For direct creation of operators
61
+ # directly by the user.
62
+ #---------------------------------------------------------------------------------------
63
+
64
+ def self.unary_operator(name, exec_type, func, where, force_type = nil,
65
+ pre_condition = nil, post_condition = nil)
66
+
67
+ function = ruby_unary_function("#{name}_user", func)
68
+ klass = Object.const_get("#{where.capitalize}MDArray")
69
+ klass.make_unary_op(name, exec_type, function, force_type, pre_condition, post_condition)
70
+
71
+ end
72
+
73
+ end # UserFunction
74
+
75
+ require_relative 'ruby_generic_functions'
76
+ require_relative 'ruby_numeric_functions'
77
+ require_relative 'ruby_math'
78
+ require_relative 'ruby_stats'