[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