mdarray 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/LICENSE.txt +54 -0
  2. data/LICENSE.txt~ +32 -0
  3. data/README.md +21 -0
  4. data/Rakefile +40 -0
  5. data/lib/env.rb +11 -0
  6. data/lib/mdarray.rb +414 -0
  7. data/lib/mdarray/access.rb +237 -0
  8. data/lib/mdarray/counter.rb +779 -0
  9. data/lib/mdarray/creation.rb +413 -0
  10. data/lib/mdarray/fast_non_numerical.rb +102 -0
  11. data/lib/mdarray/function_creation.rb +100 -0
  12. data/lib/mdarray/function_map.rb +56 -0
  13. data/lib/mdarray/hierarchy.rb +177 -0
  14. data/lib/mdarray/operators.rb +220 -0
  15. data/lib/mdarray/printing.rb +275 -0
  16. data/lib/mdarray/proc_util.rb +159 -0
  17. data/lib/mdarray/ruby_functions.rb +78 -0
  18. data/lib/mdarray/ruby_generic_functions.rb +37 -0
  19. data/lib/mdarray/ruby_math.rb +57 -0
  20. data/lib/mdarray/ruby_numeric_functions.rb +187 -0
  21. data/lib/mdarray/ruby_operators.rb +201 -0
  22. data/lib/mdarray/ruby_stats.rb +149 -0
  23. data/lib/mdarray/slices.rb +185 -0
  24. data/lib/mdarray/statistics.rb +86 -0
  25. data/test/arithmetic_casting.rb +195 -0
  26. data/test/env.rb +50 -0
  27. data/test/test_access.rb +247 -0
  28. data/test/test_boolean.rb +67 -0
  29. data/test/test_comparison.rb +126 -0
  30. data/test/test_complete.rb +69 -0
  31. data/test/test_counter.rb +184 -0
  32. data/test/test_creation.rb +364 -0
  33. data/test/test_error.rb +53 -0
  34. data/test/test_lazy.rb +52 -0
  35. data/test/test_operator.rb +337 -0
  36. data/test/test_printing.rb +66 -0
  37. data/test/test_shape.rb +96 -0
  38. data/test/test_slices.rb +146 -0
  39. data/test/test_speed.rb +311 -0
  40. data/test/test_statistics.rb +45 -0
  41. data/test/test_trigonometry.rb +60 -0
  42. data/vendor/netcdfAll-4.3.16.jar +0 -0
  43. data/version.rb +2 -0
  44. metadata +197 -0
@@ -0,0 +1,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'