[scilab-Users] Using functions in Java

Sattiraju Prabhakar maitreyakara at yahoo.com
Tue Jun 16 06:34:22 CEST 2009


Thanks Sylvestre! Your response is very helpful.

Sorry for the delayed reply. 

First, let me explain why I was trying to create Java methods for
Scilab functions, without using Scilab.ExecuteScilabScript(String filename).
I have been developing a complex Java application, and a lot of effort
has gone into structuring the application to make it extensible and
readable. I would like Java to continue to provide that structure while
using other programs like Scilab. For example, I can have variations of 
methods as the classes get extended. 

I agree with you that using Scilab.ExecuteScilabScript(String filename)
saves time. 

I tested your suggestion for "Problem Using Function" below -include "end". 
It is still giving error. When I tried to step through the function
declaration, in debugger, I found something interesting. 
Everytime Scilab.Exec() encountered, it returns "false",
except in the case of "disp". I think Scilab.Exec requires an
executable statements as arguments. Since the function declaration
does not provide statements for immediate execution, it returns false
(error, according to Scialb.Exec()). I think that is also the
reason why it executes disp statement during the function declaration. 
Am I correct? Is there a way around this problem, without entering the function
body as a very long string? 

Thanks for suggesting me to include "end". The "string" type solution which you provided
is working for me too. 

I guess the same problems are applicable to "deff" also. 

Thanks!

Prabhakar
  



> -----Original Message-----
> From: Sylvestre Ledru [mailto:sylvestre.ledru at scilab.org]
> Sent: Wednesday, June 10, 2009 8:47 AM
> To: users at lists.scilab.org
> Cc: Sattiraju Prabhakar
> Subject: Re: [scilab-Users] Using functions in Java
> 
> Hello,
> 
> 
> Le samedi 30 mai 2009 à 01:15 -0700, Sattiraju Prabhakar a écrit :
> > Hi,
> >
> > I am trying to use Scilab (5.1.1) from a Java (jdk 6 update 13)
> > application.
> > I have been experimenting with some Scilab scripts that use
> > function ("function" and "deff") definitions.
> > When I tried to convert these scripts into Java, I have come
> > across a number of problems.
> >
> > Problems using "function"
> > ================
> >
> > I took the "function percentile" declaration from Professor Gilberto
> > Gurroz's
> > Basic Statistics and Probability using Scilab. I reproduce below the
> > script.
> >
> > function [p] = percentile(x,r)
> > //This function calculates the 100*r-th percentile
> > //(0<r<1) for the vector x
> > xx = gsort(x);
> > [n m] = size(xx);
> > if m>n & n == 1
> >    n = m;
> > end
> > if r<0 | r>1 then
> >    disp('Percentile value must be between 0 and 1');
> > else
> >    k = n*r;
> >    if k-floor(k) ~= 0
> >       p = xx(round(n*r));
> >    else
> >       p = (xx(k)+xx(k+1))/2;
> >    end
> > end
> >
> > It is used as follows
> > Q1 = percentile(x,0.25)
> >
> > I tried to put it in Java code in two different ways.
> >
> > A. In the first attempt, I tried to execute each line using
> > Scilab.Exec. The code follows.
> >
> >  public void percentile() {
> >         Scilab.Exec("function [p] = percentile(x,r)");
> > //This function calculates the 100*r-th percentile
> > //(0<r<1) for the vector x
> >         Scilab.Exec("xx = gsort(x);");
> >         Scilab.Exec("[n m] = size(xx);");
> >         Scilab.Exec("if m>n & n == 1");
> >         Scilab.Exec("n = m;");
> >         Scilab.Exec("end");
> >         Scilab.Exec("if r<0 | r>1 then");
> >         Scilab.Exec("disp('Percentile value must be between 0 and
> > 1');");
> >         Scilab.Exec("else");
> >         Scilab.Exec("k = n*r;");
> >         Scilab.Exec(" if k-floor(k) ~= 0");
> >         Scilab.Exec("p = xx(round(n*r)); ");
> >         Scilab.Exec("else");
> >         Scilab.Exec("p = (xx(k)+xx(k+1))/2;");
> >         Scilab.Exec("end");
> >         Scilab.Exec("endfunction");
> >   }
> Why don't you directly store this into a dedicated percentile.sci file
> and call the java method Scilab.ExecuteScilabScript(String filename) ?
> 
> Btw, your error is due to a missing end just before the endfunction.
> 
> 
> > I tried to apply this function as follows.
> > SciDouble Q1P = new SciDouble("Q1");
> >  Scilab.Exec("Q1 = percentile(x,0.25)");
> >         Q1P.Get();
> >         Q1P.disp();
> >
> > I get the following error.
> > double Q1=
> >
> >     0.
> > Error in Java_javasci_Scilab_Exec routine.
> This is normal that it is failling here.
> Scilab.Exec is waiting for a consistent expression.
> 
> If you try:
>         if (!Scilab.Exec("function [p] = percentile(x,r)")){
> 			System.out.println(Scilab.GetLastErrorCode());
> 	}
> you will that that you will get an error (code 272... no endfunction).
> 
> 
> > B. I tried to declare the entire function as a string and pass the
> > string as argument to Scilab.Exec().
> >
> >
> > public void percentile() {
> >      String perc2 = "function [p] = percentile(x,r) \n xx = gsort(x);
> > \n [n m] = size(xx); \n if m>n & n == 1 \n n = m; \n end \n if r<0 |
> > r>1 then \n disp('Percentile value must be between 0 and 1'); \n else
> > \n k = n*r; \n if k-floor(k) ~= 0 \n p = xx(round(n*r)); \n else \n p
> > = (xx(k)+xx(k+1))/2; \n end \n endfunction";
> >     Scilab.Exec(perc2);
> > }
> 
> > I tried it without \n, and later with \n. In both cases, I got the
> > same error as above.
> Same issue, you forgot the end.
> 
> The following code is working for me:
> import javasci.*;
> public class percentile {
> 
> 
> 	public static void main(String args[]){
> 		String aze="function [p] = percentile(x,r); xx = gsort(x);
> [n m] =
> size(xx);        if m>n & n == 1        n = m;        end;        if r<0
> | r>1 then        disp('Percentile value must be between 0 and 1');
> else;        k = n*r;         if k-floor(k) ~= 0;        p =
> xx(round(n*r));         else;        p = (xx(k)+xx(k+1))/2;        end;
> end;      endfunction";
>         if (!Scilab.Exec(aze)){
> 			System.out.println(Scilab.GetLastErrorCode());
> 		}
> 		SciDouble Q1P = new SciDouble("Q1");
> 		Scilab.Exec("x=[23,2323,934,42];");
> 		Scilab.Exec("Q1 = percentile(x,0.25)");
> 		Q1P.Get();
> 		Q1P.disp();
>  	}
> }
> 
> > 2. Using deff
> > =============
> >
> > I was able to successfully write and execute the above example using
> deff
> >
> >  Scilab.Exec("deff('[x,y]=myfct(a,b)', ['x=a+b'; 'y=a-b'])");
> >
> > "deff" requires that we state the "statements" of the function as
> matrix of strings.
> > If you have a String inside the function declaration (of Scilab
> script), as in percentile, then
> > it becomes a problem.
> >
> > I was not able to get a correct result for percentile using deff and
> Java.
> > Here is my code:
> > Scilab.Exec("deff('[p]=percentile(x,r)', ['xx = gsort(x);'; '[n m] =
> size(xx);'; ' if m>n & n == 1  n = m;'; 'end'; 'if r<0 | r>1 then
> disp('Percentile value must be between 0 and 1');' ; 'else  k = n*r;';
> 'if k-floor(k) ~= 0  p = xx(round(n*r));'; 'else  p =
> (xx(k)+xx(k+1))/2;'; 'end' ])");
> Probably the same issue as before.
> 
> > I would like to end with a general question. Each of the above methods
> > takes some effort.
> > If the function definition is long, then the effort needed to convert
> > into Java code can be
> > substantial. Is there a simple method?
> Yep, load the function from a file.
> 
> Sylvestre






More information about the users mailing list