[scilab-Users] Using functions in Java
Sylvestre Ledru
sylvestre.ledru at scilab.org
Wed Jun 10 17:46:51 CEST 2009
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