How to solve a special JRuby and Java syntax conflict?

Dear all,

I am trying to use a Java class in JRuby from an external Java
library. This runs all very nicely, yet at some point,
I have to define a matrix. In the Java library, this is
supposed to be done using this syntax:

double[][] a = { { 1.1, 1.2, 1.3, 1.4 }, { 2.1, 2.2, 2.3, 2.4 }, { 3.1,
3.2, 3.3, 3.4 } };

There does not seem to be another way of populating a matrix, however
using curly braces in JRuby mistakes “a” for a Hash.

Is there a workaround for this problem ?

Thank you very much !

Best regards,

Axel

On Tue, Oct 13, 2009 at 8:52 PM, Axel E. [email protected] wrote:

Dear all,

I am trying to use a Java class in JRuby from an external Java
library. This runs all very nicely, yet at some point,
I have to define a matrix. In the Java library, this is
supposed to be done using this syntax:

double[][] a = { { 1.1, 1.2, 1.3, 1.4 }, { 2.1, 2.2, 2.3, 2.4 }, { 3.1, 3.2, 3.3, 3.4 } };

a = [[1.1, 1.2, 1.3, 1.4], [2.1, 2.2, 2.3, 2.4], [3.1, 3.2, 3.3, 3.4]]

?


Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3.5 -
sicherer, schneller und einfacher! Aktuelle Nachrichten aus Politik, Wirtschaft & Panorama | GMX


Paul S.
http://www.nomadicfun.co.uk

[email protected]

On Tue, Oct 13, 2009 at 9:52 PM, Paul S. [email protected]
wrote:

a = [[1.1, 1.2, 1.3, 1.4], [2.1, 2.2, 2.3, 2.4], [3.1, 3.2, 3.3, 3.4]]

?

Sorry, I just realised I haven’t got a clue what I’m talking about
when it comes to JRuby. However, the [[],[]] notation is how to
describe an array of arrays in Ruby, which is what a matrix
essentially is.


Paul S.
http://www.nomadicfun.co.uk

[email protected]

Dear Paul,

thank you for responding. However, I am not looking for a way of dealing
with a Matrix as such ( there would be no need to use Java for it),
but I need to talk to a specific implementation of Matrix methods in
Java.

I can do that nicely in JRuby, since the latter is basically Ruby 1.8.6
implemented in Java (rather than in C), but I have this syntax issue:

I want to use a Java class from JRuby (that’s in principle possible),
but my JRuby script reads the definition with the curly brackets as
a Hash (Ruby syntax), and I am searching for a way to prevent that.

Thank you very much for further help!

Best regards,

Axel

Axel E. wrote:

GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter Aktuelle Nachrichten aus Politik, Wirtschaft & Panorama | GMX

I think I must be missing something. Where is this definition coming
from?

Correct me if I’m wrong, but this is what I think you’re asking…

You have a java library with a method that takes an matrix (an array of
arrays) and need to call that method using an object created in JRuby
yes?

If that’s the case you should (and I’m not a JRuby user so don’t shoot
me
if I’m wrong) be able to create an matrix using the ruby syntax:

a = [[1.1, 1.2, 1.3, 1.4], [2.1, 2.2, 2.3, 2.4], [3.1, 3.2, 3.3, 3.4]]

and then call the Java method on that JRuby maxtrix:
b=Class.method(a)

and through the magic of JRuby all should be well.

If I’ve misunderstood please clarify. I think half the reason you
haven’t gotten many responses is no one understands the question.

-------- Original-Nachricht --------

Datum: Wed, 14 Oct 2009 06:19:01 +0900
Von: “Walton H.” [email protected]
An: [email protected]
Betreff: Re: how to solve a special JRuby and Java syntax conflict?

implemented in Java (rather than in C), but I have this syntax issue:

If I’ve misunderstood please clarify. I think half the reason you
haven’t gotten many responses is no one understands the question.

Walton,

thanks for responding. Unfortunately, this is not a solution.
I really need some advice from somebody who has worked with JRuby here,
I guess. I just cannot find a way of writing a Java Matrix without curly
braces, yet the Ruby part of JRuby interprets curly braces as Hashes.

For conflicts of Java and Ruby classes that have the same name, there
is this ( from the JRuby cookbook):

Example 1-7. Creating an alias to avoid class name conflicts
include Java

include_class ‘java.lang.String’ do |package,name|
“JString”
end

p JString.new(“A quick brown fox”).indexOf(“brown”)

In this example, there is now a way of using Ruby Strings and Java
Strings alongside, in the same program, without mixing them up,
by introducing a new name “JString” for the Java class “String”.

I am looking for something similar that would work with curly braces
as a class method of the Java Matrix class in the *jar file I am using,
distinguishing it from the Ruby Hash declaration with curly braces,
preferably in a way that I could still use Ruby Hashes somewhere else
in my programs… an alias or whatever, but cannot figure out how to do
that.

Best regards,

Axel

On Wed, Oct 14, 2009 at 11:10 AM, Paul S. [email protected]
wrote:

but my JRuby script reads the definition with the curly brackets as
a Hash (Ruby syntax), and I am searching for a way to prevent that.

Have you tried [[1,2,3],[2,3,4]].to_java ?

Maybe you should try posting your question to one of the resource
available from http://jrubyhub.com

Could you give some more information about your Java matrix class -->
ie,
where is it from? That way we might be able to write some sample
code…

Also, I think you might be hung up on using the {} notation – there’s
likely another way of doing it…

Matt


“… if you do follow your bliss you put yourself on a kind of
track that has been there all the while, waiting for you, and the life
that you ought to be living is the one you are living. When you can
see that, you begin to meet people who are in your field of bliss, and
they open doors to you. I say, follow your bliss and don’t be afraid,
and doors will open where you didn’t know they were going to be.” –
Joseph Campbell

On Wed, Oct 14, 2009 at 11:51, Axel E. [email protected] wrote:

I really need some advice from somebody who has worked with JRuby here,
I guess. I just cannot find a way of writing a Java Matrix without curly
braces, yet the Ruby part of JRuby interprets curly braces as Hashes.

I think most of the people on this list have worked with JRuby.

Here’s the thing. If you’re programming in JRuby, you’re still
programming
in Ruby. So you need to use Ruby syntax, not Java syntax. Even though
JRuby
works on top of the JVM, it’s still an implementation of the Ruby
language,
and you need to use Ruby notation.

That means: curly braces are for Hashes, square brackets are for Arrays.

array = [1, 2, 3, 4]

Now for a two-dimensional array (or matrix) you still need to use the
Ruby
syntax:

matrix = [ [ 1.1, 1.2, 1.3, 1.4 ], [ 2.1, 2.2, 2.3, 2.4 ], [ 3.1, 3.2,
3.3,
3.4 ] ]

Now, this will give you a Ruby Array, not a Java Array so you have to do
some manipulation to convert this into a Java Array. Since Ruby is
dynamically-typed, you need to tell JRuby what Java type to convert this
Array to, so you need to do is use the to_java(class) method:

matrix = [ [ 1.1, 1.2, 1.3, 1.4 ], [ 2.1, 2.2, 2.3, 2.4 ], [ 3.1, 3.2,
3.3,
3.4 ] ].to_java

The problem with this is that you’lll get an Array of Object and not an
Array of Arrays of doubles. You need to convert each internal Array
separately to an Array of doubles:

matrix = [ [ 1.1, 1.2, 1.3, 1.4 ].to_java(Java::double), [ 2.1, 2.2,
2.3,
2.4 ].to_java(Java::double), [ 3.1, 3.2, 3.3, 3.4
].to_java(Java::double) ].to_java

While that takes care of the internal arrays, the result of this
expression
is STILL an Array of Objects, not an Array of Arrays.

Which brings us to the question (which one of the JRuby gurus will
hopefully
answer), how do we specify an Array as a parameter in to_java?

BTW, the case of String is special. JRuby does some internal magic to
convert Ruby Strings to Java Strings, but that’s just JRuby doing its
thing.
There is no such similar thing for Arrays which is why you need to jump
through the to_java hoops to convert between them.

Hope this helps,
-Mario.

On Wed, Oct 14, 2009 at 10:51 AM, Axel E. [email protected] wrote:

thank you for responding. However, I am not looking for a way of
a Hash (Ruby syntax), and I am searching for a way to prevent that.
Have you tried [[1,2,3],[2,3,4]].to_java ?

Paul S.
http://www.nomadicfun.co.uk

[email protected]

ER…wups…sorry…I thought I was replying on the JRuby list…that’s
why
I said “most of the people on this list have worked with JRuby”. Again,
sorry for the error, my bad.
-Mario.


I want to change the world but they won’t give me the source code.

I’m not sure whether the following will help or not.
I’m not a JRuby or Java expert, but I am using both.

I’m developing something which does numeric calculations in Java for
speed,
but which uses JRuby for easy scripting and interractive (jirb) work,
and I need to set up numeric arrays which “stay” in Java,
but I haven’t got around to testing populating the Java arrays from
JRuby.

Your original question prompted me to try it, and the following seems to
work.
(Ignore the non-array bits!)
Is this the sort of thing you are trying to do?

Colin B.

// Java code, which I compiled to a class, and converted to a jar
package path_to_dir_of_java_file;
import java.io.*;

public class ActCal_value {
public double float_value;
public double[][] arr;
// constructor
public ActCal_value(double float_value_v) {
float_value = float_value_v;
}
public void set_arr_dims(int dim1, int dim2) {
arr = new double[dim1][dim2];
}
public void set_arr_val(int index1, int index2, double vv) {
arr[index1][index2] = vv;
}
public void print_arr() throws IOException {
System.out.println(“* arr==”);
for( int i0 = 0; i0 < arr.length; i0++) {
System.out.print(“* arr[” + i0 + “]”);
for( int i1 = 0; i1 < arr[i0].length; i1++) {
System.out.print( " [" + i1 + “]=” + arr[i0][i1] + “;”);
}
System.out.println( “” );
}
}
}

Ruby code, setting up Java array using above Java method set_arr_dims,

and populating Java array arr in two ways:

(1) using above Java method set_arr_val;

(2) using Ruby array element access;

include Java
require “path_to_jar/jar_file.jar”
include_class “jar_path.ActCal_value”

acv = ActCal_value.new( 42.3 )
puts "** acv = " + acv.inspect
p acv.float_value

aa = [ [0.0, 0.1, 0.2], [1.0, 1.1, 1.2] ]
acv.set_arr_dims(aa.size, aa[0].size)
acv.print_arr()
aa.each_with_index do | ar, idx0 |
ar.each_index do | idx1 |
acv.set_arr_val( idx0, idx1, aa[idx0][idx1] )
end
end
acv.print_arr()
puts acv.arr[1][2]

acv.arr[1][2] = 11.22
acv.print_arr()
puts acv.arr[1][2]

aa << [2.0, 2.1, 2.2]
acv.set_arr_dims(aa.size, aa[0].size)
aa.each_with_index do | ar, idx0 |
ar.each_index do | idx1 |
acv.arr[idx0][idx1] = aa[idx0][idx1]
end
end
acv.print_arr()
puts acv.arr[1][2]

Dear Paul, Walton, Matthew, Mario and Colin,

thank you for your very helpful and detailed responses.
I also posted on the JRuby mailing list, and like you
told me, the line

java_arr = ruby_arr.to_java Java::double[]

can solve my problem.
I am actually trying to use jmatharray for
singular value decompositions of matrices
(Singular value decomposition - Wikipedia).
Mario, your examples were very enlightening for understanding the
communication between JRuby and Java. I had so far managed to use either
one of Ruby and Java, but not both together :slight_smile:
Colin, your code also looks very interesting. So far, I am quite happy
that
I actually can use JRuby and jmatharray together for solving the
immediate
problem at hand.

Thank you very much!

Best regards,

Axel

Axel

I hope this won’t be taken the wrong way:
I’m rather glad you had the problem and posted your question,
because it prompted me to actually try out what I’d intended to do,
and even more because Carl Leiby-2 gave a very elegant way of
converting a whole array which I probably would not have found myself,
and which will save me writing quite a few lines of code
using the way I originally posted.

So, to summarise for my benefit:
in JRuby you can create a two dimension Ruby Array of doubles,
and then convert it in one go to a JRuby Java Array as follows:
rarr = [ [0.0, 0.1], [1.0, 1.1, 1.2, 1.3], [2.0], [3.0, 3.1, 3.2] ]
jarr = rarr.to_java Java::double[]
Note that it works even with different sizes of “sub-arrays”.
(But it won’t work if - for example - you replace the [2.0] by 2.0.)
For access to individual elements of the JRuby Java Array you can do:
puts jarr[2][0] # getter
jarr[2][0] = 2.0002 # setter
puts jarr[2][0] # getter
and - obviously - can write JRuby methods which process multiple
elements
by wrapping the access to individual elements.
So, if, for some reason, the “to_java Java::double[]” way doesn’t work,
we can call a user-written Java method to create a Java Array
with the appropriate dimensions and with values 0.0,
and then populate it from JRuby by accessing the individual elements,
or by passing individual values and their “indexes” to a user-written
Java method which then sets the appropriate element in the Java Array.
(I’m happier when I have more than one way to do things, as a
“back-up”.)

So thanks for the original post, and for posting in the JRuby forums!

Colin

Update to my previous post:
following Paul S.'s suggestion to Axel E.,
to “try posting your question to one of the resource
available from http://jrubyhub.com
Axel did that and got a reply within 2.25 hours
with Carl Leiby-2 giving the following elegant way of doing this:

If I understand your problem correctly, you are in a bit of ruby code
and want to define a 2 dimensional array of doubles to pass into a
jmatharray function. You can just define the 2d array like you
normally would in ruby:

ruby_arr = [[0.25, 0.25, 0.25, 0.25],
[0.25, 0.25, 0.25, 0.25],
[0.25, 0.25, 0.25, 0.25],
[0.25, 0.25, 0.25, 0.25]]

Then to pass it into the jmatharray function you run to_java on it:

ruby_arr.to_java Java::double[]

I tested this in this bit of code: jruby_array_math.rb · GitHub

** Translating Carl’s post into the context of the ruby code
in my previous post, the following also works,
and is more elegant than my ways of dealing with the whole array:

aa << [3.0, 3.1, 3.2]
puts “* elegant way”
acv.arr = aa.to_java Java::double[]
acv.print_arr()
puts acv.arr[1][2]