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,149 @@
1
+ ##########################################################################################
2
+ #
3
+ ##########################################################################################
4
+
5
+ module RubyStats
6
+ extend FunctionCreation
7
+ extend RubyFunctions
8
+
9
+ #======================================================================================
10
+ # Statistics
11
+ #======================================================================================
12
+
13
+ =begin
14
+ func = ["ruby_sum", "RubyFunction", Proc.new { |sum, val| sum + val }, "*", "*", "void"]
15
+ make_unary_op("sum", "reduce", func, nil, Proc.new { 0 })
16
+
17
+ #---------------------------------------------------------------------------------------
18
+ # calculates the minimum
19
+ #---------------------------------------------------------------------------------------
20
+
21
+ pre_calc = Proc.new { |arr1, *args| arr1[0] }
22
+
23
+ calc = Proc.new { |min, val| min = (min < val)? min : val }
24
+
25
+ make_unary_op("min", :reduce, calc, nil, pre_calc)
26
+
27
+ #---------------------------------------------------------------------------------------
28
+ # calculates the maximum
29
+ #---------------------------------------------------------------------------------------
30
+
31
+ pre_calc = Proc.new { |arr1, *args| arr1[0] }
32
+
33
+ calc = Proc.new { |max, val| max = (max > val)? max : val }
34
+
35
+ make_unary_op("max", :reduce, calc, nil, pre_calc)
36
+
37
+ #---------------------------------------------------------------------------------------
38
+ # calculates the mean
39
+ #---------------------------------------------------------------------------------------
40
+
41
+ pre_calc = Proc.new { 0 }
42
+
43
+ calc = Proc.new { |start, val| start += val }
44
+
45
+ post_calc = Proc.new do |result, *args|
46
+ arr = args.shift
47
+ if (arr.size == 0)
48
+ next nil
49
+ end
50
+ result / arr.size
51
+ end
52
+
53
+ make_unary_op("mean", :reduce, calc, nil, pre_calc, post_calc)
54
+
55
+ #---------------------------------------------------------------------------------------
56
+ # calculates the weighted mean
57
+ #---------------------------------------------------------------------------------------
58
+
59
+ pre_calc = Proc.new { [0, 0] }
60
+
61
+ calc = Proc.new do |result, val, weight|
62
+ result[0] += (val * weight)
63
+ result[1] += weight
64
+ result
65
+ end
66
+
67
+ post_calc = Proc.new do |result, *args|
68
+ arr = args.shift
69
+ if (arr.size == 0)
70
+ next [nil, nil]
71
+ end
72
+ [result[0] / result[1], arr.size]
73
+ end
74
+
75
+ make_binary_op("weighted_mean", :reduce, calc, nil, pre_calc, post_calc)
76
+
77
+ #---------------------------------------------------------------------------------------
78
+ # Expectation value
79
+ #---------------------------------------------------------------------------------------
80
+
81
+ pre_calc = Proc.new do |*args|
82
+ arr = args.shift
83
+ mean = arr.mean
84
+ method = MDArray.method(:square).to_proc * MDArray.method(:sub).to_proc.bind2nd(mean)
85
+ [0, 0, method]
86
+ end
87
+
88
+ calc = Proc.new do |result, val, method|
89
+ result[0] += (method.call(val) * weight)
90
+ result[1] += weight
91
+ result
92
+ end
93
+
94
+ post_calc = Proc.new do |result, *args|
95
+ arr = args.shift
96
+ if (arr.size == 0)
97
+ next nil
98
+ end
99
+ result / arr.size
100
+ end
101
+ =end
102
+ =begin
103
+
104
+ def mean
105
+ expectation_value(Proc.identity, Proc.everywhere)[0]
106
+ end
107
+
108
+ #---------------------------------------------------------------------------------------
109
+ #
110
+ #---------------------------------------------------------------------------------------
111
+
112
+ def variance
113
+
114
+ s2 = expectation_value(MDArray.method(:square).to_proc *
115
+ MDArray.method(:sub).to_proc.bind2nd(mean),
116
+ Proc.everywhere)[0]
117
+ return s2*size/(size-1)
118
+
119
+ end
120
+
121
+ #---------------------------------------------------------------------------------------
122
+ #
123
+ #---------------------------------------------------------------------------------------
124
+
125
+ def expectation_value(method, in_range, weight = nil)
126
+
127
+ num = 0
128
+ den = 0
129
+ n = 0
130
+ each do |elmt|
131
+ if (in_range.call(elmt))
132
+ num += method.call(elmt)
133
+ den += 1
134
+ n += 1
135
+ end
136
+ end
137
+ if (n == 0)
138
+ return [nil, nil]
139
+ else
140
+ return [num / den, n]
141
+ end
142
+
143
+ end
144
+
145
+ # calculates the mean
146
+
147
+ =end
148
+
149
+ end # RubyStats
@@ -0,0 +1,185 @@
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
+ class MDArray
23
+
24
+ #------------------------------------------------------------------------------------
25
+ # Create a copy of this Array, copying the data so that physical order is the same as
26
+ # logical order
27
+ #------------------------------------------------------------------------------------
28
+
29
+ def copy
30
+ MDArray.new(@nc_array.copy())
31
+ end
32
+
33
+ #------------------------------------------------------------------------------------
34
+ #
35
+ #------------------------------------------------------------------------------------
36
+
37
+ def reshape(shape, copy = false)
38
+
39
+ new_shape = shape.to_java :int
40
+
41
+ if (copy)
42
+ nc_array = @nc_array.reshape(new_shape)
43
+ else
44
+ nc_array = @nc_array.reshapeNoCopy(new_shape)
45
+ end
46
+
47
+ MDArray.new(@type, nc_array)
48
+
49
+ end
50
+
51
+ #------------------------------------------------------------------------------------
52
+ #
53
+ #------------------------------------------------------------------------------------
54
+
55
+ def reshape!(shape)
56
+ new_shape = shape.to_java :int
57
+ @nc_array = @nc_array.reshapeNoCopy(new_shape)
58
+ # when we reshape an array we need to re-initialize its index and local_iterator
59
+ @local_index = Counter.new(self)
60
+ @local_iterator = nil
61
+ end
62
+
63
+ #------------------------------------------------------------------------------------
64
+ #
65
+ #------------------------------------------------------------------------------------
66
+
67
+ def reduce(dim = nil)
68
+
69
+ if (dim)
70
+ nc_array = @nc_array.reduce(dim.to_java :int)
71
+ else
72
+ nc_array = @nc_array.reduce
73
+ end
74
+
75
+ shape = MDArray.get_shape(nc_array)
76
+ MDArray.new(@type, nc_array)
77
+
78
+ end
79
+
80
+ #---------------------------------------------------------------------------------------
81
+ # Create a new Array using same backing store as this Array, by permuting the indices.
82
+ # Parameters:
83
+ # <tt>indices</tt> the old index dims[k] becomes the new kth index.
84
+ # Returns:
85
+ # the new Array
86
+ # Throws:
87
+ # IllegalArgumentException: - wrong rank or dim[k] not valid
88
+ #---------------------------------------------------------------------------------------
89
+
90
+ def permute(indices)
91
+
92
+ ind = indices.to_java :int
93
+
94
+ begin
95
+ perm = @nc_array.permute(ind)
96
+ rescue # should catch IllegalArgumentException
97
+ raise "Illegal argument"
98
+ end
99
+
100
+ MDArray.new(@type, perm)
101
+
102
+ end
103
+
104
+ #------------------------------------------------------------------------------------
105
+ # Create a new Array as a subsection of this Array, without rank reduction. No data
106
+ # is moved, so the new Array references the same backing store as the original.
107
+ # Parameters:
108
+ # origin - int array specifying the starting index. Must be same rank as original Array.
109
+ # shape - int array specifying the extents in each dimension. This becomes the shape
110
+ # of the returned Array. Must be same rank as original Array.
111
+ # stride - int array specifying the strides in each dimension. If null, assume all ones.
112
+ # Returns:
113
+ # the new Array
114
+ # Throws:
115
+ # InvalidRangeException - if ranges is invalid
116
+ #------------------------------------------------------------------------------------
117
+
118
+ def section(origin, shape, reduce = false)
119
+
120
+ jorigin = origin.to_java :int
121
+ jshape = shape.to_java :int
122
+
123
+ if (reduce)
124
+ arr = @nc_array.section(jorigin, jshape)
125
+ else
126
+ arr = @nc_array.sectionNoReduce(jorigin, jshape, nil)
127
+ end
128
+
129
+ # this is an array section, set it to true
130
+ if (arr.rank == 0)
131
+ return arr.get()
132
+ end
133
+
134
+ section = MDArray.new(@type, arr, true)
135
+ copy_print_parameters(section)
136
+ return section
137
+
138
+ end
139
+
140
+ #------------------------------------------------------------------------------------
141
+ #
142
+ #------------------------------------------------------------------------------------
143
+
144
+ def section_with_stride(origin, shape, stride, reduce = false)
145
+
146
+ jorigin = origin.to_java :int
147
+ jshape = shape.to_java :int
148
+ jstride = stride.to_java :int
149
+
150
+ if (reduce)
151
+ arr = @nc_array.section(jorigin, jshape, jstride)
152
+ else
153
+ arr = @nc_array.sectionNoReduce(jorigin, jshape, jstride)
154
+ end
155
+
156
+ # this is an array section, set it to true
157
+ section = MDArray.new(@type, arr, true)
158
+ copy_print_parameters(section)
159
+ return section
160
+
161
+ end
162
+
163
+ #------------------------------------------------------------------------------------
164
+ #
165
+ #------------------------------------------------------------------------------------
166
+
167
+ def section?
168
+ @section
169
+ end
170
+
171
+ #------------------------------------------------------------------------------------
172
+ #
173
+ #------------------------------------------------------------------------------------
174
+
175
+ private
176
+
177
+ #------------------------------------------------------------------------------------
178
+ #
179
+ #------------------------------------------------------------------------------------
180
+
181
+ def section=(value)
182
+ @section = value
183
+ end
184
+
185
+ end
@@ -0,0 +1,86 @@
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
+ class MDArray
23
+
24
+ #---------------------------------------------------------------------------------------
25
+ #
26
+ #---------------------------------------------------------------------------------------
27
+
28
+ def stdev
29
+ return Math.sqrt(variance)
30
+ end
31
+
32
+ alias standard_deviation :stdev
33
+
34
+ #---------------------------------------------------------------------------------------
35
+ #
36
+ #---------------------------------------------------------------------------------------
37
+
38
+ def error_estimate
39
+ Math.sqrt(variance/size)
40
+ end
41
+
42
+ #---------------------------------------------------------------------------------------
43
+ #
44
+ #---------------------------------------------------------------------------------------
45
+
46
+ def skewness
47
+
48
+ n = size
49
+
50
+ if (n <= 2)
51
+ raise "Cannot calculate skewness on array with less than 3 elements"
52
+ end
53
+
54
+ x = expectation_value(MDArray.method(:cube).to_proc *
55
+ MDArray.method(:sub).to_proc.bind2nd(mean),
56
+ Proc.everywhere)[0]
57
+ sigma = stdev
58
+
59
+ return (x/(sigma*sigma*sigma)) * (n/(n-1)) * (n/(n-2))
60
+
61
+ end
62
+
63
+ #---------------------------------------------------------------------------------------
64
+ #
65
+ #---------------------------------------------------------------------------------------
66
+
67
+ def kurtosis
68
+
69
+ n = size
70
+
71
+ if (n <= 3)
72
+ raise "Cannot calculate kurtosis on array with less than 4 elements"
73
+ end
74
+
75
+ x = expectation_value(MDArray.method(:fourth).to_proc *
76
+ MDArray.method(:sub).to_proc.bind2nd(mean),
77
+ Proc.everywhere)[0]
78
+
79
+ sigma2 = variance
80
+ c1 = (n/(n-1)) * (n/(n-2)) * ((n+1)/(n-3))
81
+ c2 = 3 * ((n-1)/(n-2)) * ((n-1)/(n-3))
82
+ return c1 * (x/(sigma2*sigma2)) - c2
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,195 @@
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
+ require 'rubygems'
24
+ require "test/unit"
25
+ require 'shoulda'
26
+
27
+ require 'mdarray'
28
+
29
+ class MDArrayTest < Test::Unit::TestCase
30
+
31
+ context "Arithmetic Tests" do
32
+
33
+ setup do
34
+
35
+ # create a = [20 30 40 50]
36
+ @a = MDArray.arange(20, 60, 10)
37
+ # create b = [0 1 2 3]
38
+ @b = MDArray.arange(4)
39
+ # create c = [1.87 5.34 7.18 8.84]
40
+ @c = MDArray.double([4], [1.87, 5.34, 7.18, 8.84])
41
+ # create d = [[1 2] [3 4]]
42
+ @d = MDArray.int([2, 2], [1, 2, 3, 4])
43
+ # creates an array from a function (actually a block). The name fromfunction
44
+ # is preserved to maintain API compatibility with NumPy (is it necessary?)
45
+ @e = MDArray.fromfunction("double", [4, 5, 6]) do |x, y, z|
46
+ 3.21 * (x + y + z)
47
+ end
48
+ @f = MDArray.fromfunction("double", [4, 5, 6]) do |x, y, z|
49
+ 9.57 * x + y + z
50
+ end
51
+ @bool = MDArray.boolean([4], [true, true, false, false])
52
+
53
+ end # setup
54
+
55
+ #-------------------------------------------------------------------------------------
56
+ #
57
+ #-------------------------------------------------------------------------------------
58
+
59
+ should "do down-casting when in-place operation" do
60
+
61
+ # in place operation between an "int" array and a "double" array will keep the
62
+ # type of a to "int", no up-casting. Values will be truncated
63
+ @a.add! @c
64
+ assert_equal(21, @a[0])
65
+ assert_equal(@a.type, "int")
66
+
67
+ end
68
+
69
+ #-------------------------------------------------------------------------------------
70
+ #
71
+ #-------------------------------------------------------------------------------------
72
+
73
+ should "do up-casting" do
74
+
75
+ # when doing operations between two arrays, the resulting array will have the
76
+ # highest casting value. result will be of type double
77
+ result = @a + @c
78
+ assert_equal(21.87, result[0])
79
+ assert_equal("double", result.dtype)
80
+
81
+ end
82
+
83
+ #-------------------------------------------------------------------------------------
84
+ #
85
+ #-------------------------------------------------------------------------------------
86
+
87
+ should "do up-casting with basic types" do
88
+
89
+ result = 1.57 * @a
90
+ # since @a is an int, this should be converted to double, as there is no "float"
91
+ # type in ruby
92
+ assert_equal("double", result.dtype)
93
+ assert_equal(result.to_string, "31.400000000000002 47.1 62.800000000000004 78.5 ")
94
+
95
+ result = @c * 1.57
96
+ assert_equal("double", result.dtype)
97
+
98
+ # array @a will be cast to "double"
99
+ result = @a ** 2.5
100
+ assert_equal("double", result.dtype)
101
+
102
+ # array @c will keep its double type
103
+ result = @c ** 2.5
104
+ assert_equal("double", result.dtype)
105
+
106
+ # force result to be of given type. Cannot use binary operators, need to use the
107
+ # corresponding function. Upcast int @a to float
108
+ result = @a.mul(1.57, "float")
109
+ assert_equal("float", result.dtype)
110
+
111
+ result = @a.div(2, "short")
112
+ assert_equal("short", result.dtype)
113
+
114
+ # force result to be of given type. Cannot use binary operators, need to use the
115
+ # corresponding function.
116
+ result = @e.mul(1.57, "float")
117
+ assert_equal("float", result.dtype)
118
+
119
+
120
+ end
121
+
122
+ #-------------------------------------------------------------------------------------
123
+ #
124
+ #-------------------------------------------------------------------------------------
125
+
126
+ should "allow forced casting" do
127
+
128
+ # force result to be of type float, by normal rules it would be of type double
129
+ result = @a.mul(1.57, "float")
130
+ assert_equal("float", result.dtype)
131
+ # final result depends on when casting occurs. It is possible that the operation
132
+ # is done in double and cast when storing on the float array, or the operation
133
+ # can be done in float already. Ruby operations perform the former, i.e.,
134
+ # double operation and cast to float.
135
+ if (MDArray.binary_operator == RubyBinaryOperator)
136
+ assert_equal("31.4 47.1 62.8 78.5 ", result.to_string)
137
+ else
138
+ assert_equal("31.400002 47.100002 62.800003 78.5 ", result.to_string)
139
+ end
140
+
141
+ # force result to be ot type "int"
142
+ # @a.binary_operator = BinaryOperator
143
+ result = @a.mul(3.43, "int")
144
+ assert_equal(result.type, "int")
145
+ if (MDArray.binary_operator == RubyBinaryOperator)
146
+ # When BinaryOperator with force casting, values are operated first and then
147
+ # casted. So, in the example above we have 20 * 3.43 = 68,6 and then the value
148
+ # is casted to int for a result of 68
149
+ assert_equal(68, result[0])
150
+ else
151
+ # When we cast earlier values are first cast to the the selected type
152
+ # and then operated upon. So, in the example we have 20 * 3.43, which becomes
153
+ # 20 * 3 = 60
154
+ assert_equal(60, result[0])
155
+ end
156
+
157
+ end
158
+
159
+ #-------------------------------------------------------------------------------------
160
+ #
161
+ #-------------------------------------------------------------------------------------
162
+
163
+ should "allow mixing types" do
164
+
165
+ # adding double to number
166
+ res = @c + 10.5
167
+ assert_equal(res.to_string, "12.370000000000001 15.84 17.68 19.34 ")
168
+ # adding two double arrays
169
+ res = @e + @f
170
+
171
+ # adding a double to an int, should cast to double
172
+ res = @c + @a
173
+ assert_equal("21.87 35.34 47.18 58.84 ", res.to_string)
174
+ # adding an int to a double, should cast to double
175
+ res = @a + @c
176
+ assert_equal("21.87 35.34 47.18 58.84 ", res.to_string)
177
+ # adding an int array to a (ruby) float/double number, should cast to double
178
+ res = @a + 10.55
179
+ assert_equal("30.55 40.55 50.55 60.55 ", res.to_string)
180
+ # adding two ints
181
+ res = @a + @b
182
+ assert_equal(res.to_string, "20 31 42 53 ")
183
+ # unary operation on arrays
184
+ res = @c.floor
185
+ assert_equal(res.to_string, "1.0 5.0 7.0 8.0 ")
186
+ # Can also operate with the number first. Still doing elementwise operation
187
+ c = 10 / @c
188
+ assert_equal("5.347593582887701 1.8726591760299627 1.392757660167131 1.1312217194570136 ",
189
+ c.to_string)
190
+
191
+ end
192
+
193
+ end
194
+
195
+ end