mdarray 0.5.0.pre-java → 0.5.3-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.
- data/README.md +89 -90
- data/Rakefile +6 -1
- data/lib/colt/cern_double_functions.rb +193 -0
- data/lib/colt/cern_float_functions.rb +193 -0
- data/lib/colt/cern_int_functions.rb +152 -0
- data/lib/colt/cern_long_functions.rb +152 -0
- data/lib/colt/colt.rb +103 -1
- data/lib/mdarray.rb +71 -23
- data/lib/mdarray/access.rb +8 -0
- data/lib/mdarray/counter.rb +43 -1
- data/lib/mdarray/creation.rb +5 -10
- data/lib/mdarray/fast_operators.rb +17 -13
- data/lib/mdarray/function_creation.rb +11 -45
- data/lib/mdarray/function_map.rb +16 -8
- data/lib/mdarray/lazy_mdarray.rb +311 -0
- data/lib/mdarray/lazy_operators.rb +166 -0
- data/lib/mdarray/operators.rb +38 -9
- data/lib/mdarray/proc_util.rb +2 -0
- data/lib/mdarray/ruby_boolean_functions.rb +24 -0
- data/lib/mdarray/ruby_functions.rb +76 -2
- data/lib/mdarray/ruby_generic_functions.rb +12 -4
- data/lib/mdarray/ruby_math.rb +180 -2
- data/lib/mdarray/ruby_numeric_functions.rb +198 -7
- data/target/helper.jar +0 -0
- data/test/colt/ColtMethods.xlsx +0 -0
- data/test/colt/test_complete.rb +1 -0
- data/test/colt/test_math.rb +249 -0
- data/test/complete.rb +1 -0
- data/test/env.rb +17 -4
- data/test/mdarray/arithmetic_casting.rb +3 -0
- data/test/mdarray/test_boolean.rb +1 -1
- data/test/mdarray/test_complete.rb +1 -0
- data/test/mdarray/test_error.rb +13 -13
- data/test/mdarray/test_lazy.rb +306 -0
- data/test/mdarray/test_operator.rb +1 -1
- data/test/mdarray/test_performance.rb +57 -4
- data/test/mdarray/test_trigonometry.rb +5 -1
- data/vendor/commons-compiler.jar +0 -0
- data/vendor/janino.jar +0 -0
- data/version.rb +1 -1
- metadata +47 -10
- data/test/mdarray/test_statistics.rb +0 -80
data/lib/mdarray/access.rb
CHANGED
@@ -70,6 +70,14 @@ class MDArray
|
|
70
70
|
@local_index.get(index)
|
71
71
|
end
|
72
72
|
|
73
|
+
#------------------------------------------------------------------------------------
|
74
|
+
#
|
75
|
+
#------------------------------------------------------------------------------------
|
76
|
+
|
77
|
+
def jget(index = nil)
|
78
|
+
@local_index.jget(index)
|
79
|
+
end
|
80
|
+
|
73
81
|
#------------------------------------------------------------------------------------
|
74
82
|
# Gets the next element of the local iterator
|
75
83
|
#------------------------------------------------------------------------------------
|
data/lib/mdarray/counter.rb
CHANGED
@@ -178,6 +178,16 @@ class MDArray
|
|
178
178
|
get_at_counter
|
179
179
|
end
|
180
180
|
|
181
|
+
#------------------------------------------------------------------------------------
|
182
|
+
# Gets the element at the given counter. Assumes that the counter is of the proper
|
183
|
+
# shape. Also, counter should be an int java array
|
184
|
+
#------------------------------------------------------------------------------------
|
185
|
+
|
186
|
+
def jget(counter)
|
187
|
+
jset_counter_fast(counter)
|
188
|
+
get_at_counter
|
189
|
+
end
|
190
|
+
|
181
191
|
#------------------------------------------------------------------------------------
|
182
192
|
# Gets element at current counter. Can be done fast, as counter is always of the
|
183
193
|
# proper shape.
|
@@ -328,6 +338,21 @@ class MDArray
|
|
328
338
|
|
329
339
|
end
|
330
340
|
|
341
|
+
#-------------------------------------------------------------------------------------
|
342
|
+
# Sets this index to point to the given counter. Assumes that the counter respects
|
343
|
+
# the shape constraints. Also, in this case, the counter should be an int java array.
|
344
|
+
#-------------------------------------------------------------------------------------
|
345
|
+
|
346
|
+
def jset_counter_fast(counter)
|
347
|
+
|
348
|
+
begin
|
349
|
+
@nc_index.set(counter)
|
350
|
+
rescue java.lang.ArrayIndexOutOfBoundsException
|
351
|
+
raise RangeError, "Invalid counter: #{counter}"
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
331
356
|
#-------------------------------------------------------------------------------------
|
332
357
|
# Sets this index to point to the given counter. If given counter has negative values
|
333
358
|
# then convert them to positive values, making sure that the counter respects the
|
@@ -500,6 +525,15 @@ class MDArray
|
|
500
525
|
@nc_index.getCurrentCounter().to_a
|
501
526
|
end
|
502
527
|
|
528
|
+
#-------------------------------------------------------------------------------------
|
529
|
+
# Returns the current counter as a java array. This is for performance improvement.
|
530
|
+
# Should be used carefully so that it doesn't permeate ruby code.
|
531
|
+
#-------------------------------------------------------------------------------------
|
532
|
+
|
533
|
+
def jget_current_counter
|
534
|
+
@nc_index.getCurrentCounter()
|
535
|
+
end
|
536
|
+
|
503
537
|
end # Counter
|
504
538
|
|
505
539
|
|
@@ -545,6 +579,15 @@ class MDArray
|
|
545
579
|
@iterator.getCurrentCounter().to_a
|
546
580
|
end
|
547
581
|
|
582
|
+
#-------------------------------------------------------------------------------------
|
583
|
+
# Returns the current counter as a java array. This is for performance improvement.
|
584
|
+
# Should be used carefully so that it doesn't permeate ruby code.
|
585
|
+
#-------------------------------------------------------------------------------------
|
586
|
+
|
587
|
+
def jget_current_counter
|
588
|
+
@iterator.getCurrentCounter()
|
589
|
+
end
|
590
|
+
|
548
591
|
#------------------------------------------------------------------------------------
|
549
592
|
#
|
550
593
|
#------------------------------------------------------------------------------------
|
@@ -611,7 +654,6 @@ class MDArray
|
|
611
654
|
#
|
612
655
|
#---------------------------------------------------------------------------------------
|
613
656
|
|
614
|
-
|
615
657
|
class IteratorFastByte < IteratorFast
|
616
658
|
|
617
659
|
def get_current
|
data/lib/mdarray/creation.rb
CHANGED
@@ -25,13 +25,6 @@
|
|
25
25
|
|
26
26
|
class MDArray
|
27
27
|
|
28
|
-
class << self
|
29
|
-
|
30
|
-
attr_accessor :binary_operator
|
31
|
-
attr_accessor :unary_operator
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
28
|
#------------------------------------------------------------------------------------
|
36
29
|
# Given two types returns the upcasted one
|
37
30
|
#------------------------------------------------------------------------------------
|
@@ -356,15 +349,17 @@ class MDArray
|
|
356
349
|
end
|
357
350
|
|
358
351
|
#------------------------------------------------------------------------------------
|
359
|
-
#
|
352
|
+
# fmap is an array with the following data: long_name, scope, function, return_type,
|
353
|
+
# input1_type, input2_type
|
360
354
|
#------------------------------------------------------------------------------------
|
361
355
|
|
362
|
-
def self.register_function(name,
|
356
|
+
def self.register_function(name, fmap, arity, helper_class)
|
363
357
|
|
364
358
|
if ((list = MDArray.function_map[name]) == nil)
|
365
359
|
list = (MDArray.function_map[name] = Array.new)
|
366
360
|
end
|
367
|
-
list << FunctionMap.new(name,
|
361
|
+
list << FunctionMap.new(name, fmap[0], fmap[1], fmap[2], fmap[3], fmap[4], fmap[5],
|
362
|
+
arity, helper_class)
|
368
363
|
|
369
364
|
end
|
370
365
|
|
@@ -69,7 +69,9 @@ class FastBinaryOperator < BinaryOperator
|
|
69
69
|
end
|
70
70
|
|
71
71
|
#---------------------------------------------------------------------------------------
|
72
|
-
#
|
72
|
+
# A default binary operator takes two arrays where one array can be degenerated (a
|
73
|
+
# number and loops through all elements of the arrays applying a given method to them.
|
74
|
+
# For instance, operator '+' in a + b is a default binary operator.
|
73
75
|
#---------------------------------------------------------------------------------------
|
74
76
|
|
75
77
|
def default(*args)
|
@@ -78,13 +80,13 @@ class FastBinaryOperator < BinaryOperator
|
|
78
80
|
get_args(*args) do |op1, op2, shape, *other_args|
|
79
81
|
calc = MDArray.build(@type, shape)
|
80
82
|
if (@coerced)
|
81
|
-
helper =
|
83
|
+
helper = @helper::CoerceBinaryOperator
|
82
84
|
helper.send("apply", calc.nc_array, op1, op2, @do_func)
|
83
85
|
elsif (@op1.is_a? NumericalMDArray)
|
84
|
-
helper =
|
86
|
+
helper = @helper::DefaultBinaryOperator
|
85
87
|
helper.send("apply", calc.nc_array, op1, op2, @do_func)
|
86
88
|
else
|
87
|
-
helper =
|
89
|
+
helper = @helper::DefaultBinaryOperator
|
88
90
|
helper.send("apply#{@op1.class}", calc.nc_array, op1, op2, @do_func)
|
89
91
|
end
|
90
92
|
end
|
@@ -93,13 +95,15 @@ class FastBinaryOperator < BinaryOperator
|
|
93
95
|
end
|
94
96
|
|
95
97
|
#---------------------------------------------------------------------------------------
|
96
|
-
#
|
98
|
+
# A fill binary operator takes two arrays where one array can be degenerated (a number)
|
99
|
+
# and loops through all elements of the arrays, setting the value of the first array
|
100
|
+
# to the values of the second.
|
97
101
|
#---------------------------------------------------------------------------------------
|
98
102
|
|
99
103
|
def fill(*args)
|
100
104
|
|
101
105
|
get_args(*args) do |op1, op2, shape, *other_args|
|
102
|
-
helper =
|
106
|
+
helper = @helper::FillBinaryOperator
|
103
107
|
helper.send("apply", op1, op2)
|
104
108
|
end
|
105
109
|
|
@@ -112,7 +116,7 @@ class FastBinaryOperator < BinaryOperator
|
|
112
116
|
def in_place(*args)
|
113
117
|
|
114
118
|
get_args(*args) do |op1, op2, shape, *other_args|
|
115
|
-
helper =
|
119
|
+
helper = @helper::InplaceBinaryOperator
|
116
120
|
helper.send("apply", op1, op2, @do_func)
|
117
121
|
end
|
118
122
|
|
@@ -127,7 +131,7 @@ class FastBinaryOperator < BinaryOperator
|
|
127
131
|
calc = nil
|
128
132
|
|
129
133
|
get_args(*args) do |op1, op2, shape, *other_args|
|
130
|
-
helper =
|
134
|
+
helper = @helper::ReduceBinaryOperator
|
131
135
|
calc = @pre_condition_result
|
132
136
|
calc = helper.send("apply", calc, op1, op2, @do_func)
|
133
137
|
end
|
@@ -145,7 +149,7 @@ class FastBinaryOperator < BinaryOperator
|
|
145
149
|
calc = nil
|
146
150
|
|
147
151
|
get_args(*args) do |op1, op2, shape, *other_args|
|
148
|
-
helper =
|
152
|
+
helper = @helper::ComplexReduceBinaryOperator
|
149
153
|
calc = @pre_condition_result
|
150
154
|
calc = helper.send("apply", calc, op1, op2, @do_func)
|
151
155
|
end
|
@@ -181,7 +185,7 @@ class FastUnaryOperator < UnaryOperator
|
|
181
185
|
|
182
186
|
get_args(*args) do |op1, shape, *other_args|
|
183
187
|
block = other_args[0]
|
184
|
-
helper =
|
188
|
+
helper = @helper::SetAll
|
185
189
|
func = (shape.size <= 7)? "apply#{shape.size}" : "apply"
|
186
190
|
helper.send(func, op1, &block) if block
|
187
191
|
end
|
@@ -197,7 +201,7 @@ class FastUnaryOperator < UnaryOperator
|
|
197
201
|
calc = nil
|
198
202
|
get_args(*args) do |op1, shape, *other_args|
|
199
203
|
calc = MDArray.build(@type, shape)
|
200
|
-
helper =
|
204
|
+
helper = @helper::DefaultUnaryOperator
|
201
205
|
helper.send("apply", calc.nc_array, op1, @do_func)
|
202
206
|
end
|
203
207
|
return calc
|
@@ -211,7 +215,7 @@ class FastUnaryOperator < UnaryOperator
|
|
211
215
|
def in_place(*args)
|
212
216
|
|
213
217
|
get_args(*args) do |op1, shape, *other_args|
|
214
|
-
helper =
|
218
|
+
helper = @helper::InplaceUnaryOperator
|
215
219
|
helper.send("apply", op1, @do_func)
|
216
220
|
end
|
217
221
|
|
@@ -226,7 +230,7 @@ class FastUnaryOperator < UnaryOperator
|
|
226
230
|
calc = nil
|
227
231
|
|
228
232
|
get_args(*args) do |op1, shape, *other_args|
|
229
|
-
helper =
|
233
|
+
helper = @helper::ReduceUnaryOperator
|
230
234
|
calc = @pre_condition_result
|
231
235
|
calc = helper.send("apply", calc, op1, @do_func)
|
232
236
|
end
|
@@ -29,16 +29,20 @@ module FunctionCreation
|
|
29
29
|
#
|
30
30
|
#------------------------------------------------------------------------------------
|
31
31
|
|
32
|
-
def make_binary_op(name, exec_type, func, force_type = nil,
|
33
|
-
post_condition = nil)
|
32
|
+
def make_binary_op(name, exec_type, func, helper_class, force_type = nil,
|
33
|
+
pre_condition = nil, post_condition = nil)
|
34
34
|
|
35
35
|
define_method(name) do |op2, requested_type = nil, *args|
|
36
|
-
|
36
|
+
if (@type == "lazy" || ((op2.is_a? MDArray) && op2.type == "lazy"))
|
37
|
+
binary_op = LazyBinaryOperator
|
38
|
+
else
|
39
|
+
binary_op = get_binary_op
|
40
|
+
end
|
37
41
|
op = binary_op.new(name, exec_type, force_type, pre_condition, post_condition)
|
38
42
|
op.exec(self, op2, requested_type, *args)
|
39
43
|
end
|
40
44
|
|
41
|
-
MDArray.register_function(name, func)
|
45
|
+
MDArray.register_function(name, func, 2, helper_class)
|
42
46
|
|
43
47
|
end
|
44
48
|
|
@@ -46,23 +50,8 @@ module FunctionCreation
|
|
46
50
|
#
|
47
51
|
#------------------------------------------------------------------------------------
|
48
52
|
|
49
|
-
def
|
50
|
-
|
51
|
-
if (default)
|
52
|
-
make_binary_op(name, "default", func)
|
53
|
-
end
|
54
|
-
if (in_place)
|
55
|
-
make_binary_op(name + "!", "in_place", func)
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
#------------------------------------------------------------------------------------
|
61
|
-
#
|
62
|
-
#------------------------------------------------------------------------------------
|
63
|
-
|
64
|
-
def make_unary_op(name, exec_type, func, force_type = nil, pre_condition = nil,
|
65
|
-
post_condition = nil)
|
53
|
+
def make_unary_op(name, exec_type, func, helper_class, force_type = nil,
|
54
|
+
pre_condition = nil, post_condition = nil)
|
66
55
|
|
67
56
|
define_method(name) do |requested_type = nil, *args|
|
68
57
|
unary_op = get_unary_op
|
@@ -70,31 +59,8 @@ module FunctionCreation
|
|
70
59
|
op.exec(self, requested_type, *args)
|
71
60
|
end
|
72
61
|
|
73
|
-
MDArray.register_function(name, func)
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
#------------------------------------------------------------------------------------
|
78
|
-
#
|
79
|
-
#------------------------------------------------------------------------------------
|
80
|
-
|
81
|
-
def make_unary_operators(name, func, default = true, in_place = true)
|
82
|
-
|
83
|
-
if (default)
|
84
|
-
make_unary_op(name, "default", func)
|
85
|
-
end
|
86
|
-
if (in_place)
|
87
|
-
make_unary_op(name + "!", "in_place", func)
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
#------------------------------------------------------------------------------------
|
93
|
-
#
|
94
|
-
#------------------------------------------------------------------------------------
|
62
|
+
MDArray.register_function(name, func, 1, helper_class)
|
95
63
|
|
96
|
-
def make_comparison_op(name, func)
|
97
|
-
make_binary_op(name, "default", func, "boolean")
|
98
64
|
end
|
99
65
|
|
100
66
|
end # FunctionCreation
|
data/lib/mdarray/function_map.rb
CHANGED
@@ -25,30 +25,38 @@
|
|
25
25
|
|
26
26
|
class FunctionMap
|
27
27
|
|
28
|
-
attr_reader :short_name
|
29
|
-
attr_reader :long_name
|
30
|
-
attr_reader :
|
31
|
-
attr_reader :function
|
28
|
+
attr_reader :short_name # short name of the function
|
29
|
+
attr_reader :long_name # long name of the function
|
30
|
+
attr_reader :package # package where the function was implemented
|
31
|
+
attr_reader :function # function to be applied to elmts
|
32
32
|
attr_reader :return_type
|
33
33
|
attr_reader :input1_type
|
34
34
|
attr_reader :input2_type
|
35
|
-
|
35
|
+
attr_reader :arity # arity of the function: 1 or 2
|
36
|
+
attr_reader :helper # Helper method to perform the function
|
37
|
+
attr_reader :is_global # set to true if function applies to all elmts of the
|
38
|
+
# array. By default set to false
|
39
|
+
attr_reader :elmtwise # works elementwise
|
36
40
|
attr_accessor :description
|
37
41
|
|
38
42
|
#------------------------------------------------------------------------------------
|
39
43
|
#
|
40
44
|
#------------------------------------------------------------------------------------
|
41
45
|
|
42
|
-
def initialize(short_name, long_name,
|
43
|
-
input2_type)
|
46
|
+
def initialize(short_name, long_name, package, function, return_type, input1_type,
|
47
|
+
input2_type, arity, helper, elmtwise = true, is_global = false)
|
44
48
|
|
45
49
|
@short_name = short_name
|
46
50
|
@long_name = long_name
|
47
|
-
@
|
51
|
+
@package = package
|
48
52
|
@function = function
|
49
53
|
@return_type = return_type
|
50
54
|
@input1_type = input1_type
|
51
55
|
@input2_type = input2_type
|
56
|
+
@arity = arity
|
57
|
+
@helper = helper
|
58
|
+
@elmtwise = elmtwise
|
59
|
+
@is_global = is_global
|
52
60
|
|
53
61
|
end # initialize
|
54
62
|
|
@@ -0,0 +1,311 @@
|
|
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 for educational, research, and
|
6
|
+
# not-for-profit purposes, without fee and without a signed licensing agreement, is hereby
|
7
|
+
# granted, provided that the above copyright notice, this paragraph and the following two
|
8
|
+
# paragraphs appear in all copies, modifications, and distributions. Contact Rodrigo
|
9
|
+
# Botafogo - rodrigo.a.botafogo@gmail.com for commercial licensing opportunities.
|
10
|
+
#
|
11
|
+
# IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
12
|
+
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
|
13
|
+
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
|
14
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
15
|
+
#
|
16
|
+
# RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
17
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
18
|
+
# SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
|
19
|
+
# RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
20
|
+
# OR MODIFICATIONS.
|
21
|
+
##########################################################################################
|
22
|
+
|
23
|
+
|
24
|
+
##########################################################################################
|
25
|
+
#
|
26
|
+
##########################################################################################
|
27
|
+
|
28
|
+
class LazyMDArray < ByteMDArray
|
29
|
+
include_package "ucar.ma2"
|
30
|
+
include_package "org.codehaus.janino"
|
31
|
+
|
32
|
+
attr_reader :stack
|
33
|
+
|
34
|
+
#=======================================================================================
|
35
|
+
# Class BinaryComp applies a function f to two arguments. The arguments can be
|
36
|
+
# functions on their own right
|
37
|
+
#=======================================================================================
|
38
|
+
|
39
|
+
class BinaryComp
|
40
|
+
|
41
|
+
def initialize(f, x, y, *args)
|
42
|
+
@x = x
|
43
|
+
@y = y
|
44
|
+
@f = f
|
45
|
+
@other_args = args
|
46
|
+
end
|
47
|
+
|
48
|
+
def apply
|
49
|
+
@f.apply(@x.apply, @y.apply)
|
50
|
+
end
|
51
|
+
|
52
|
+
end # BinaryComp
|
53
|
+
|
54
|
+
#=======================================================================================
|
55
|
+
# Class UnaryComp applies a function f to one arguments. The arguments can be a
|
56
|
+
# function on its own right
|
57
|
+
#=======================================================================================
|
58
|
+
|
59
|
+
class UnaryComp
|
60
|
+
|
61
|
+
def initialize(f, x, *args)
|
62
|
+
@x = x
|
63
|
+
@f = f
|
64
|
+
@other_args = args
|
65
|
+
end
|
66
|
+
|
67
|
+
def apply
|
68
|
+
@f.apply(@x.apply)
|
69
|
+
end
|
70
|
+
|
71
|
+
end # UnaryComp
|
72
|
+
|
73
|
+
#=======================================================================================
|
74
|
+
#
|
75
|
+
#=======================================================================================
|
76
|
+
|
77
|
+
|
78
|
+
#---------------------------------------------------------------------------------------
|
79
|
+
#
|
80
|
+
#---------------------------------------------------------------------------------------
|
81
|
+
|
82
|
+
def initialize
|
83
|
+
|
84
|
+
@stack = Array.new
|
85
|
+
@type = "lazy"
|
86
|
+
@previous_binary_operator = nil
|
87
|
+
@previous_unary_operator = nil
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
#---------------------------------------------------------------------------------------
|
92
|
+
#
|
93
|
+
#---------------------------------------------------------------------------------------
|
94
|
+
|
95
|
+
def push(elmt)
|
96
|
+
@stack << elmt
|
97
|
+
end
|
98
|
+
|
99
|
+
#---------------------------------------------------------------------------------------
|
100
|
+
#
|
101
|
+
#---------------------------------------------------------------------------------------
|
102
|
+
|
103
|
+
def pop
|
104
|
+
@stack.pop
|
105
|
+
end
|
106
|
+
|
107
|
+
#---------------------------------------------------------------------------------------
|
108
|
+
#
|
109
|
+
#---------------------------------------------------------------------------------------
|
110
|
+
|
111
|
+
def test_janino_function
|
112
|
+
$exp = ExpressionEvaluator.new
|
113
|
+
$exp.setExpressionType(Java::CernColtFunctionTdouble::DoubleFunction.java_class)
|
114
|
+
class_type = Java::JavaLang::Class.forName("java.lang.Class")
|
115
|
+
array = Java::JavaLangReflect::Array.newInstance(class_type, 2)
|
116
|
+
array[0] = Java::double.java_class
|
117
|
+
array[1] = Java::double.java_class
|
118
|
+
$exp.setParameters(["a", "b"].to_java(:string),
|
119
|
+
array)
|
120
|
+
$exp.cook("a + b")
|
121
|
+
end
|
122
|
+
|
123
|
+
#---------------------------------------------------------------------------------------
|
124
|
+
#
|
125
|
+
#---------------------------------------------------------------------------------------
|
126
|
+
|
127
|
+
def apply(*args)
|
128
|
+
|
129
|
+
type, shape, function = validate_fast(args)
|
130
|
+
|
131
|
+
result = MDArray.build(type, shape)
|
132
|
+
helper = Java::RbMdarrayLoopsLazy::DefaultLazyOperator
|
133
|
+
helper.send("apply", result.nc_array, function)
|
134
|
+
result
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
alias :[] :apply
|
139
|
+
|
140
|
+
#---------------------------------------------------------------------------------------
|
141
|
+
# Shows this LazyMDArray in Reverse Polish Notation. Mainly for debugging purposes.
|
142
|
+
#---------------------------------------------------------------------------------------
|
143
|
+
|
144
|
+
def rpn(nl = true)
|
145
|
+
|
146
|
+
exp = String.new
|
147
|
+
|
148
|
+
@stack.each do |elmt|
|
149
|
+
|
150
|
+
if (elmt.is_a? LazyMDArray)
|
151
|
+
exp << elmt.rpn(false)
|
152
|
+
elsif (elmt.is_a? Numeric)
|
153
|
+
exp << elmt << " "
|
154
|
+
elsif (elmt.is_a? Operator)
|
155
|
+
exp << elmt.name << " "
|
156
|
+
elsif (elmt.is_a? MDArray)
|
157
|
+
exp << elmt.type << " "
|
158
|
+
else
|
159
|
+
raise "Wrong element type in Array"
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
exp
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
#---------------------------------------------------------------------------------------
|
169
|
+
#
|
170
|
+
#---------------------------------------------------------------------------------------
|
171
|
+
|
172
|
+
def print
|
173
|
+
Kernel.print "[Lazy MDArray]\n"
|
174
|
+
p rpn
|
175
|
+
end
|
176
|
+
|
177
|
+
#---------------------------------------------------------------------------------------
|
178
|
+
# Validates the expression checking if it can be performed: all dimensions need to be
|
179
|
+
# compatible
|
180
|
+
#---------------------------------------------------------------------------------------
|
181
|
+
|
182
|
+
protected
|
183
|
+
|
184
|
+
def validate_fast(*args)
|
185
|
+
|
186
|
+
# test_janino_function
|
187
|
+
# p "validade_fast compile janino expression:"
|
188
|
+
# $exp.apply(100, 100)
|
189
|
+
|
190
|
+
helper_stack = Array.new
|
191
|
+
|
192
|
+
@stack.each do |elmt|
|
193
|
+
|
194
|
+
if (elmt.is_a? LazyMDArray)
|
195
|
+
helper_stack << elmt.validate_fast(*args)
|
196
|
+
elsif (elmt.is_a? MDArray)
|
197
|
+
# helper_stack << [elmt.type, elmt.shape, index_func(elmt)]
|
198
|
+
# iterator = elmt.nc_array.getIndexIterator
|
199
|
+
java_proc = Java::RbMdarrayUtil::Util.getIterator(elmt.nc_array)
|
200
|
+
helper_stack << [elmt.type, elmt.shape, java_proc]
|
201
|
+
elsif (elmt.is_a? Numeric)
|
202
|
+
# const_func is inefficient... fix!!!
|
203
|
+
helper_stack << ["numeric", 1, const_func(elmt)]
|
204
|
+
elsif (elmt.is_a? Operator)
|
205
|
+
case elmt.arity
|
206
|
+
when 1
|
207
|
+
top = helper_stack.pop
|
208
|
+
fmap = MDArray.select_function(elmt.name, MDArray.functions, top[0],
|
209
|
+
top[0], "void")
|
210
|
+
helper_stack <<
|
211
|
+
[top[0], top[1],
|
212
|
+
# UnaryComp.new(top[2], fmap.function, elmt.other_args)]
|
213
|
+
Java::RbMdarrayUtil::Util.compose(fmap.function, top[2])]
|
214
|
+
when 2
|
215
|
+
top1, top2 = helper_stack.pop(2)
|
216
|
+
if (top1[1] != top2[1] && top1[0] != "numeric" && top2[0] != "numeric")
|
217
|
+
raise "Expression involves incopatible arrays. #{top1[1]} != #{top2[1]}"
|
218
|
+
end
|
219
|
+
type = MDArray.upcast(top1[0], top2[0])
|
220
|
+
fmap = MDArray.select_function(elmt.name, MDArray.functions, type, type, type)
|
221
|
+
helper_stack <<
|
222
|
+
[type, top1[1],
|
223
|
+
Java::RbMdarrayUtil::Util.compose(fmap.function, top1[2], top2[2])]
|
224
|
+
end
|
225
|
+
else
|
226
|
+
raise "Expression is invalid: element #{elmt} is not valid in this position."
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
helper_stack[0]
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
#---------------------------------------------------------------------------------------
|
236
|
+
#
|
237
|
+
#---------------------------------------------------------------------------------------
|
238
|
+
|
239
|
+
private
|
240
|
+
|
241
|
+
#---------------------------------------------------------------------------------------
|
242
|
+
#
|
243
|
+
#---------------------------------------------------------------------------------------
|
244
|
+
|
245
|
+
def const_func(val)
|
246
|
+
Proc.new { |index| val }
|
247
|
+
end
|
248
|
+
|
249
|
+
#---------------------------------------------------------------------------------------
|
250
|
+
#
|
251
|
+
#---------------------------------------------------------------------------------------
|
252
|
+
|
253
|
+
def index_func(a)
|
254
|
+
Proc.new { |index| a.jget(index) }
|
255
|
+
end
|
256
|
+
|
257
|
+
#---------------------------------------------------------------------------------------
|
258
|
+
#
|
259
|
+
#---------------------------------------------------------------------------------------
|
260
|
+
|
261
|
+
def get_next_func(a)
|
262
|
+
Proc.new { a.getObjectNext() }
|
263
|
+
end
|
264
|
+
|
265
|
+
#---------------------------------------------------------------------------------------
|
266
|
+
#
|
267
|
+
#---------------------------------------------------------------------------------------
|
268
|
+
|
269
|
+
def binary_function_next(proc1, proc2, f, *args)
|
270
|
+
Proc.new { f.call(proc1.apply, proc2.apply, *args) }
|
271
|
+
end
|
272
|
+
|
273
|
+
end # LazyMDArray
|
274
|
+
|
275
|
+
##########################################################################################
|
276
|
+
#
|
277
|
+
##########################################################################################
|
278
|
+
|
279
|
+
class MDArray
|
280
|
+
|
281
|
+
#---------------------------------------------------------------------------------------
|
282
|
+
#
|
283
|
+
#---------------------------------------------------------------------------------------
|
284
|
+
|
285
|
+
def self.set_lazy(flag = true)
|
286
|
+
|
287
|
+
if (flag)
|
288
|
+
if (MDArray.binary_operator != LazyBinaryOperator)
|
289
|
+
MDArray.previous_binary_operator = MDArray.binary_operator
|
290
|
+
MDArray.previous_unary_operator = MDArray.unary_operator
|
291
|
+
end
|
292
|
+
MDArray.binary_operator = LazyBinaryOperator
|
293
|
+
MDArray.unary_operator = LazyUnaryOperator
|
294
|
+
else
|
295
|
+
MDArray.binary_operator = MDArray.previous_binary_operator if MDArray.previous_binary_operator != nil
|
296
|
+
MDArray.unary_operator = MDArray.previous_unary_operator if MDArray.previous_unary_operator != nil
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
#---------------------------------------------------------------------------------------
|
302
|
+
#
|
303
|
+
#---------------------------------------------------------------------------------------
|
304
|
+
|
305
|
+
def self.lazy=(flag)
|
306
|
+
set_lazy(flag)
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
require_relative 'lazy_operators'
|