scicom 0.2.2-java → 0.2.3-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,162 @@
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
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'env'
27
+ require 'scicom'
28
+
29
+ class SciComTest < Test::Unit::TestCase
30
+
31
+ context "R environment" do
32
+
33
+ #--------------------------------------------------------------------------------------
34
+ #
35
+ #--------------------------------------------------------------------------------------
36
+
37
+ setup do
38
+
39
+ end
40
+
41
+ #--------------------------------------------------------------------------------------
42
+ #
43
+ #--------------------------------------------------------------------------------------
44
+
45
+ should "have the same backing store" do
46
+
47
+ p "arr1 and r_matrix have both the same backing store when data is converted from \
48
+ MDArray to R"
49
+ arr1 = MDArray.typed_arange("double", 12)
50
+ arr1.reshape!([4, 3])
51
+ arr1.print
52
+
53
+ p "r_matrix has the same data as arr1"
54
+ r_matrix = R.md(arr1)
55
+ r_matrix.pp
56
+
57
+ # change an element of the MDArray
58
+ arr1[0, 0] = 10.34567
59
+ p "changing element is arr1 will cause the same change in r_matrix"
60
+ arr1.print
61
+
62
+ p "element [0, 0] of r_matrix has also changed"
63
+ r_matrix.pp
64
+
65
+ # WITH GREAT POWER COMES GREAT RESPONSABILITIES!
66
+ # r_matrix also changes... arr1 and r_matrix have the same backing store. Changing
67
+ # the content of an MDArray that points to the same backing store as an R vector
68
+ # should be done with care. Renjin assumes that the vector will never change and
69
+ # delays calculation of the vector to the latest possible time. In this case, since
70
+ # the value of the vector is changing, one can get unexpected behaviour. Use with
71
+ # care. We could prevent MDArray from being editable, however, we believe that
72
+ # allowing access to the backing store will have important implications for
73
+ # performance. If we have indication that this is not a good thing, then we will
74
+ # remove MDArrays ability to change the backing store of a Vector.
75
+ compare = MDArray.byte(arr1.shape)
76
+ arr1.get_index.each do |ct|
77
+ compare[*ct] = (arr1[*ct] == (r_matrix.ri(*ct).gz))? 1 : 0
78
+ end
79
+ comp = R.md(compare)
80
+ assert_equal(true, comp.all.gt)
81
+
82
+ end
83
+
84
+ #--------------------------------------------------------------------------------------
85
+ # Assign an MDArray to an R vector (array)
86
+ #--------------------------------------------------------------------------------------
87
+
88
+ should "MDArray is organized row-major while R vectors are column-major" do
89
+
90
+ # this is a row-major matrix
91
+ p "arr1 is in row-major order"
92
+ arr1 = MDArray.typed_arange(:double, 12)
93
+ arr1.reshape!([4, 3])
94
+ arr1.print
95
+
96
+ # a vector in R is column-major
97
+ p "however vec is in column-major order as vec was created in R"
98
+ vec = R.seq(0, 11)
99
+ vec.attr.dim = R.c(4, 3)
100
+ vec.pp
101
+
102
+ # arr1 and vec are not identical, since one is organized in row-major order while
103
+ # the other is organized in column-major order
104
+ compare = MDArray.byte(arr1.shape)
105
+ arr1.get_index.each do |ct|
106
+ compare[*ct] = (arr1[*ct] == (vec.ri(*ct).gz))? 1 : 0
107
+ end
108
+ comp = R.md(compare)
109
+ assert_equal(false, comp.all.gt)
110
+
111
+ # Note that when creating a matrix in MDArray and converting to an R vector, the
112
+ # same order is preserved, i.e., the R vector will see the data as in row-major
113
+ # order. On the other hand, when a vector is created in R, it will have column-
114
+ # major order. Maintaining the order from MDArray to R allows for easy and
115
+ # compatible use of array in both views.
116
+
117
+ end
118
+
119
+ #--------------------------------------------------------------------------------------
120
+ #
121
+ #--------------------------------------------------------------------------------------
122
+
123
+ should "change backing store of R vector when changing the vector" do
124
+
125
+ # create an MDArray
126
+ arr1 = MDArray.typed_arange("double", 12)
127
+ arr1.reshape!([4, 3])
128
+ p "Making any changes in an Renjin object changes the object itself"
129
+ arr1.print
130
+ r_matrix = R.md(arr1)
131
+ p "r_matrix has the same data as arr1"
132
+
133
+ # Both arr1 and r_matrix point to the same backing store as seen above.
134
+
135
+ # Now, changing the r_matrix dimension will create a new r_matrix and arr1 and
136
+ # r_matrix will now point to different backstores. By design, any changes in a Renjin
137
+ # object actually creates a new object.
138
+ r_matrix.attr.dim = R.c(4, 3)
139
+ p "just by setting the dimension, even with the same values as before, creates a new object"
140
+ r_matrix.pp
141
+
142
+ # changing the value of arr1 will have no impact in r_matrix
143
+ arr1[1, 1] = 1000.34
144
+ p "changing arr1 element will not change r_matrix element anymore"
145
+ arr1.print
146
+ p "r_matrix is unchanged"
147
+ r_matrix.pp
148
+
149
+ compare = MDArray.byte([4,3])
150
+ (0..3).each do |row|
151
+ (0..2).each do |col|
152
+ compare[row, col] = (arr1[row, col] == (r_matrix[row + 1, col + 1].gz))? 1 : 0
153
+ end
154
+ end
155
+ comp = R.md(compare)
156
+ assert_equal(false, comp.all.gt)
157
+
158
+ end
159
+
160
+ end
161
+
162
+ end
@@ -0,0 +1,201 @@
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
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'env'
27
+ require 'scicom'
28
+
29
+ class SciComTest < Test::Unit::TestCase
30
+
31
+ context "R environment" do
32
+
33
+ #--------------------------------------------------------------------------------------
34
+ #
35
+ #--------------------------------------------------------------------------------------
36
+
37
+ setup do
38
+
39
+ end
40
+
41
+ #--------------------------------------------------------------------------------------
42
+ #
43
+ #--------------------------------------------------------------------------------------
44
+
45
+ should "convert a 3D MDArray onto a R matrix" do
46
+
47
+ # create a 1D MDArray
48
+ arr1 = MDArray.typed_arange("double", 12)
49
+ arr1.reshape!([3, 2, 2])
50
+
51
+ # Dimensions definitions are treated differently between MDArray and R. In MDArray
52
+ # a [3, 2, 2] specification indicates that there are 3 vector of 2 x 2 dimensions.
53
+ # So arr1 is the following array:
54
+ # [[[0.0 1.0]
55
+ # [2.0 3.0]]
56
+ #
57
+ # [[4.0 5.0]
58
+ # [6.0 7.0]]
59
+ #
60
+ # [[8.0 9.0]
61
+ # [10.0 11.0]]]
62
+ #
63
+ # in R the same specification indicates that we have two vectors each of 3 x 2. So,
64
+ # this would be the vector with the same [3, 2, 2] specification.
65
+ # [,1] [,2]
66
+ # [1,] 1 2
67
+ # [2,] 3 4
68
+ # [3,] 5 6
69
+ #
70
+ # , , 2
71
+ #
72
+ # [,1] [,2]
73
+ # [1,] 7 8
74
+ # [2,] 9 10
75
+ # [3,] 11 12
76
+ #
77
+ # When converting a multi-dimensional array from MDArray to R, SciCom also fixes
78
+ # the vector specification and the [3, 2, 2] MDArray specification becomes a
79
+ # [2, 2, 3] R vector specification.
80
+ # In general converting from MDArray index to R index is done as follows:
81
+ # Let [i1, i2, i3, ... in] be the MDArray index, the corresponding R index is
82
+ # [i(n-1)+1, in+1, ..., i3+1, i2+1, i1+1].
83
+
84
+ # convert to an R matrix
85
+ r_matrix = R.md(arr1)
86
+
87
+ # Renjin does not yet print correctly N > 2 dimensional vectors
88
+ p "this is a 3D vector, but Renjin has a bug and prints it as a 1D vector"
89
+ r_matrix.pp
90
+
91
+ # In order to simplify access to the R vector with different dimension specification
92
+ # SciCom implements method 'ri' (r-indexing), so that arr1[dim1, dim2, dim3] is
93
+ # equal to r_matrix.ri(dim1, dim2, dim3)
94
+
95
+ compare = MDArray.byte(arr1.shape)
96
+ arr1.get_index.each do |ct|
97
+ compare[*ct] = (arr1[*ct] == (r_matrix.ri(*ct).gz))? 1 : 0
98
+ end
99
+ comp = R.md(compare)
100
+ assert_equal(true, comp.all.gt)
101
+
102
+ p "dimension of r_matrix in R"
103
+ R.vec = r_matrix
104
+ R.eval("print(dim(vec))")
105
+
106
+ end
107
+
108
+ #--------------------------------------------------------------------------------------
109
+ #
110
+ #--------------------------------------------------------------------------------------
111
+
112
+ should "work with MDArray slices" do
113
+
114
+ # create a 3D MDArray
115
+ # [[[0.0 1.0]
116
+ # [2.0 3.0]]
117
+ #
118
+ # [[4.0 5.0]
119
+ # [6.0 7.0]]
120
+ #
121
+ # [[8.0 9.0]
122
+ # [10.0 11.0]]]
123
+ arr1 = MDArray.typed_arange("double", 12)
124
+ arr1.reshape!([3, 2, 2])
125
+ arr1.print
126
+
127
+ # This array has 3 vectors of size 2 x 2. Getting slice(0, 0) returns the first
128
+ # 2 x 2 vector.
129
+ # [[0.0 1.0]
130
+ # [2.0 3.0]]
131
+ p "slice(0, 0): this is a 2D slice of the original array"
132
+ mat = arr1.slice(0, 0)
133
+
134
+ # MDArray will be converted to the following R matrix
135
+ # [,1] [,2]
136
+ # [1,] 0 1
137
+ # [2,] 2 3
138
+ p "now converting the slice into an R matrix"
139
+ r_mat = R.md(mat)
140
+
141
+ # Compare mat and r_mat
142
+ compare = MDArray.byte(mat.shape)
143
+ mat.get_index.each do |ct|
144
+ compare[*ct] = (mat[*ct] == (r_mat.ri(*ct).gz))? 1 : 0
145
+ end
146
+ comp = R.md(compare)
147
+ assert_equal(true, comp.all.gt)
148
+
149
+
150
+ # Getting slice(0, 2) returns the third 2 x 2 vector.
151
+ # [[8.0 9.0]
152
+ # [10.0 11.0]]
153
+ p "slice(0, 2): this is a 2D slice of the original array"
154
+ mat = arr1.slice(0, 2)
155
+
156
+ # [,1] [,2]
157
+ # [1,] 8 9
158
+ # [2,] 10 11
159
+ p "now converting the slice into an R matrix"
160
+ r_mat = R.md(mat)
161
+
162
+ # Compare mat and r_mat
163
+ compare = MDArray.byte(mat.shape)
164
+ mat.get_index.each do |ct|
165
+ compare[*ct] = (mat[*ct] == (r_mat.ri(*ct).gz))? 1 : 0
166
+ end
167
+ comp = R.md(compare)
168
+ assert_equal(true, comp.all.gt)
169
+
170
+ # slice(1, 0) gets the first row of all three vectors and thus returns a 3 x 2
171
+ # vector:
172
+ # [[0.0 1.0]
173
+ # [4.0 5.0]
174
+ # [8.0 9.0]]
175
+ p "slice(1, 0): this is a 2D slice of the original array"
176
+ mat = arr1.slice(1, 0)
177
+
178
+ # The above will become the following R matrix
179
+ # [,1] [,2]
180
+ # [1,] 0 1
181
+ # [2,] 4 5
182
+ # [3,] 8 9
183
+ p "now converting the slice into an R matrix"
184
+ r_mat = R.md(mat)
185
+
186
+ compare = MDArray.byte(mat.shape)
187
+ mat.get_index.each do |ct|
188
+ compare[*ct] = (mat[*ct] == (r_mat.ri(*ct).gz))? 1 : 0
189
+ end
190
+ comp = R.md(compare)
191
+ assert_equal(true, comp.all.gt)
192
+
193
+ # Note that there is no data copying when an MDArray is sliced and this is an
194
+ # efficient operation.
195
+
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
@@ -1,8 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ##########################################################################################
4
- # @author Rodrigo Botafogo
5
- #
6
4
  # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
5
  # and distribute this software and its documentation, without fee and without a signed
8
6
  # licensing agreement, is hereby granted, provided that the above copyright notice, this
@@ -21,36 +19,52 @@
21
19
  # OR MODIFICATIONS.
22
20
  ##########################################################################################
23
21
 
24
- require 'java'
22
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
25
 
26
- class Renjin
26
+ require 'env'
27
+ require 'scicom'
27
28
 
28
- class Sequence < Renjin::RubySexp
29
- include Renjin::Index
30
-
31
- end
29
+ class SciComTest < Test::Unit::TestCase
32
30
 
33
- end
31
+ context "R environment" do
34
32
 
35
- =begin
36
- #==========================================================================================
37
- #
38
- #==========================================================================================
33
+ #--------------------------------------------------------------------------------------
34
+ #
35
+ #--------------------------------------------------------------------------------------
36
+
37
+ setup do
39
38
 
40
- class Renjin
39
+ end
41
40
 
42
- class IntSequence < Renjin::Sequence
43
- include_package "org.renjin.primitives.sequence"
44
41
 
45
- #----------------------------------------------------------------------------------------
42
+ =begin
43
+ #--------------------------------------------------------------------------------------
46
44
  #
47
- #----------------------------------------------------------------------------------------
48
-
49
- def getElement(index)
50
- @sexp.getElementAsInt(index)
45
+ #--------------------------------------------------------------------------------------
46
+
47
+ should "work with MDArray slices" do
48
+
49
+ dim = [6, 4, 3, 2]
50
+
51
+ # create a 1D MDArray
52
+ arr1 = MDArray.typed_arange(:double, dim.inject(:*))
53
+ arr1.reshape!(dim)
54
+
55
+ slice = arr1.slice(0, 0)
56
+ slice.print
57
+ mat = R.md(slice)
58
+ mat.pp
59
+
60
+ slice = arr1.slice(0, 1)
61
+ slice.print
62
+ mat = R.md(slice)
63
+ mat.pp
64
+
51
65
  end
52
-
66
+ =end
53
67
  end
54
-
68
+
55
69
  end
56
- =end
70
+
@@ -39,10 +39,13 @@ require_relative 'test_matrix'
39
39
  require_relative 'test_dataframe'
40
40
  require_relative 'test_linear_model'
41
41
 
42
+ require_relative 'test_assign_mdarray'
43
+ require_relative 'test_assign_mdarray_2d'
44
+ require_relative 'test_assign_mdarray_3d'
45
+
42
46
  =begin
43
47
  require_relative 'test_subsetting'
44
48
  require_relative 'test_double_receive'
45
- require_relative 'test_double_assign'
46
49
  require_relative 'test_functions'
47
50
  require_relative 'test_user_function'
48
51
  require_relative 'test_column-major'