diff options
author | Shashank | 2017-05-29 12:40:26 +0530 |
---|---|---|
committer | Shashank | 2017-05-29 12:40:26 +0530 |
commit | 0345245e860375a32c9a437c4a9d9cae807134e9 (patch) | |
tree | ad51ecbfa7bcd3cc5f09834f1bb8c08feaa526a4 /modules/optimization/macros | |
download | scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.gz scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.bz2 scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.zip |
CMSCOPE changed
Diffstat (limited to 'modules/optimization/macros')
253 files changed, 10541 insertions, 0 deletions
diff --git a/modules/optimization/macros/%mps_p.bin b/modules/optimization/macros/%mps_p.bin Binary files differnew file mode 100755 index 000000000..c591bb5d8 --- /dev/null +++ b/modules/optimization/macros/%mps_p.bin diff --git a/modules/optimization/macros/%mps_p.sci b/modules/optimization/macros/%mps_p.sci new file mode 100755 index 000000000..77b1b6249 --- /dev/null +++ b/modules/optimization/macros/%mps_p.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %mps_p -- +// Prints the string containing the MPS component. +// +function %mps_p ( this ) + str = string ( this ) + srows = size(str,"r") + for i = 1 : srows + mprintf("%s\n",str(i)) + end +endfunction + + diff --git a/modules/optimization/macros/%mps_string.bin b/modules/optimization/macros/%mps_string.bin Binary files differnew file mode 100755 index 000000000..c8a36f64c --- /dev/null +++ b/modules/optimization/macros/%mps_string.bin diff --git a/modules/optimization/macros/%mps_string.sci b/modules/optimization/macros/%mps_string.sci new file mode 100755 index 000000000..0d3226d1b --- /dev/null +++ b/modules/optimization/macros/%mps_string.sci @@ -0,0 +1,84 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %mps_string -- +// Returns the string containing the MPS component. +// +function str = %mps_string ( this ) + str = [] + k = 1 + str(k) = sprintf("MPS Object:\n") + k = k + 1 + str(k) = sprintf("===========") + k = k + 1 + str(k) = "" + k = k + 1 + str(k) = sprintf("irobj: %s\n", _tostring(this.irobj)); + k = k + 1 + str(k) = sprintf("namec: %s\n", _tostring(this.namec)); + k = k + 1 + str(k) = sprintf("nameb: %s\n", _tostring(this.nameb)); + k = k + 1 + str(k) = sprintf("namran: %s\n", _tostring(this.namran)); + k = k + 1 + str(k) = sprintf("nambnd: %s\n", _tostring(this.nambnd)); + k = k + 1 + str(k) = sprintf("name: %s\n", _tostring(this.name)); + k = k + 1 + str(k) = sprintf("rownames: %s\n", _tostring(this.rownames)); + k = k + 1 + str(k) = sprintf("colnames: %s\n", _tostring(this.colnames)); + k = k + 1 + str(k) = sprintf("rowstat: %s\n", _tostring(this.rowstat)); + k = k + 1 + str(k) = sprintf("rowcode: %s\n", _tostring(this.rowcode)); + k = k + 1 + str(k) = sprintf("colcode: %s\n", _tostring(this.colcode)); + k = k + 1 + str(k) = sprintf("rownmbs: %s\n", _tostring(this.rownmbs)); + k = k + 1 + str(k) = sprintf("colpnts: %s\n", _tostring(this.colpnts)); + k = k + 1 + str(k) = sprintf("acoeff: %s\n", _tostring(this.acoeff)); + k = k + 1 + str(k) = sprintf("rhs: %s\n", _tostring(this.rhs)); + k = k + 1 + str(k) = sprintf("ranges: %s\n", _tostring(this.ranges)); + k = k + 1 + str(k) = sprintf("bounds: %s\n", _tostring(this.bounds)); + k = k + 1 + str(k) = sprintf("stavar: %s\n", _tostring(this.stavar)); + k = k + 1 +endfunction + +// +// _strvec -- +// Returns a string for the given vector. +// +function str = _strvec ( x ) + str = strcat(string(x)," ") +endfunction +function s = _tostring ( x ) + if ( x==[] ) then + s = "[]" + else + n = size ( x , "*" ) + if ( n == 1 ) then + s = string(x) + else + [nr,nc] = size(x) + tx = typeof(x) + s = msprintf("%d-by-%d %s matrix",nr,nc,tx) + end + end +endfunction + + + diff --git a/modules/optimization/macros/NDcost.bin b/modules/optimization/macros/NDcost.bin Binary files differnew file mode 100755 index 000000000..275f7d507 --- /dev/null +++ b/modules/optimization/macros/NDcost.bin diff --git a/modules/optimization/macros/NDcost.sci b/modules/optimization/macros/NDcost.sci new file mode 100755 index 000000000..5d5ba83cc --- /dev/null +++ b/modules/optimization/macros/NDcost.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function [f, g, ind] = NDcost(x, ind, fun, varargin) + // external for optim() + // Computes the gradient of 'fun' at 'x' using code differentiation + if argn(2) < 4 then + f = fun(x); + g = numderivative(fun, x); + else + f = fun(x, varargin(:)); + g = numderivative(list(fun, varargin(:)), x); + end +endfunction diff --git a/modules/optimization/macros/aplat.bin b/modules/optimization/macros/aplat.bin Binary files differnew file mode 100755 index 000000000..8c39e04bc --- /dev/null +++ b/modules/optimization/macros/aplat.bin diff --git a/modules/optimization/macros/aplat.sci b/modules/optimization/macros/aplat.sci new file mode 100755 index 000000000..abcc02542 --- /dev/null +++ b/modules/optimization/macros/aplat.sci @@ -0,0 +1,34 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [r,ind]=aplat(l,r) + //flattens a list. If l is constant it puts it in a list + //ind contains the list structure + if type(l)<>15 then r=list(l);ind=-1;return;end + n=size(l) + [lhs,rhs]=argn(0) + if rhs==1 then r=list(),nr=0,end + ind=list() + i=0 + nind=0 + for li=l + i=i+1 + if type(li)==15 then + [r,ind1]=aplat(li,r) + ni=size(ind1) + for j=1:ni,nind=nind+1;ind(nind)=[i,ind1(j)];end + nr=size(r) + else + nr=nr+1 + r(nr)=li + nind=nind+1 + ind(nind)=i + end + end +endfunction diff --git a/modules/optimization/macros/buildmacros.bat b/modules/optimization/macros/buildmacros.bat new file mode 100755 index 000000000..c4e35ec40 --- /dev/null +++ b/modules/optimization/macros/buildmacros.bat @@ -0,0 +1 @@ +@..\..\..\bin\scilex -nwni -ns -e exec('buildmacros.sce');quit;
\ No newline at end of file diff --git a/modules/optimization/macros/buildmacros.sce b/modules/optimization/macros/buildmacros.sce new file mode 100755 index 000000000..7be4e4180 --- /dev/null +++ b/modules/optimization/macros/buildmacros.sce @@ -0,0 +1,12 @@ +//------------------------------------ +// Allan CORNET INRIA 2005 +//------------------------------------ +if (isdef("genlib") == %f) then + exec(SCI+"/modules/functions/scripts/buildmacros/loadgenlib.sce"); +end +//------------------------------------ +genlib("optimizationlib","SCI/modules/optimization/macros",%f,%t); +genlib("neldermeadlib","SCI/modules/optimization/macros/neldermead",%f,%t); +genlib("optimbaselib","SCI/modules/optimization/macros/optimbase",%f,%t); +genlib("optimsimplexlib","SCI/modules/optimization/macros/optimsimplex",%f,%t); +//------------------------------------ diff --git a/modules/optimization/macros/bvodeS.bin b/modules/optimization/macros/bvodeS.bin Binary files differnew file mode 100755 index 000000000..3dbebc470 --- /dev/null +++ b/modules/optimization/macros/bvodeS.bin diff --git a/modules/optimization/macros/bvodeS.sci b/modules/optimization/macros/bvodeS.sci new file mode 100755 index 000000000..2a3cd2e21 --- /dev/null +++ b/modules/optimization/macros/bvodeS.sci @@ -0,0 +1,170 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) Rainer von Seggern +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function z=bvodeS(x,m,n,a,b,fsub,gsub,zeta,... + ystart,dfsub,dgsub,fixpnt,ndimf,ndimi,ltol,tol,ntol,nonlin,... + collpnt,subint,iprint,ireg,ifail) + // + // PURPOSE + // Simplified call of bvode. (Version 08.05.2005) + // List of arguments: see help bvode in Scilab. + // The arguments from ystart to ifail are optional. + // They may be called by name in the form argument=name + // in any order. + // + + ms=sum(m);ipar=zeros(1,11); + + if n>20 then + error(msprintf(_("%s: More than 20 equations are not allowed"),"bvodeS")); + end + + [lhs,rhs]=argn() + if rhs<8 | rhs>23 then + error(msprintf(gettext("%s: Wrong number of input argument(s).\n"), ... + "bvodeS")); + end + if min(m)<1 | max(m)>4 then + error(msprintf(gettext("%s: The elements of the argument #%d must be in [%d %d].\n"),"bvodeS",2,1,4)); + end + + if exists("guess","local") then ystart=guess,end + if ~exists("ystart","local") then + %ys=%ystart1; iguess=0; + else + if and(type(ystart)<>[13 15 11]) then + error(msprintf(gettext("%s: Wrong type for input argument #%s: external expected.\n"),"bvodeS","guess")); + end + %ys=%ystart;iguess=1; + end + + if ~exists("dfsub","local") then + dfsubA=%dfsub; + else + if and(type(ystart)<>[13 15 11]) then + error(msprintf(gettext("%s: Wrong type for input argument #%s: external expected.\n"),"bvodeS","dfsub")); + end + dfsubA=%dfsub1; + end + if ~exists("dgsub","local") then + dgsubA=%dgsub; + else + if and(type(ystart)<>[13 15 11]) then + error(msprintf(gettext("%s: Wrong type for input argument #%s: external expected.\n"),"bvodeS","dgsub")); + end + dgsubA=%dgsub1; + end + if ~exists("ltol","local") then ltol=1:ms; end + if ~exists("tol","local") then tol=1e-4*ones(1,ms); end + if ~exists("ntol","local") then ntol=length(tol); end + if ~exists("nonlin","local") then nonlin=1; end + if ~exists("collpnt","local") then collpnt=0; end + if ~exists("subint","local") then subint=0; end + if ~exists("iprint","local") then iprint=-1; end + if ~exists("ireg","local") then ireg = 0; end + + if ~exists("ndimf","local") then + ndimf=1000*(4+ms+(5+n*collpnt)*(ms+n*collpnt)+4*ms^2); + end + + if ~exists("ndimi","local") then + ndimi=1000*(3+ms+n*collpnt); + end + + if ~exists("fixpnt","local") then + fixpnt=[]; + else + ipar(11)=length(fixpnt); + end + + if ~exists("ifail","local") then + ifail=0; + else + ifail=1; + end + + ipar(1)=nonlin; + ipar(2)=collpnt; + ipar(3)=subint; + ipar(4)=ntol; + ipar(5)=ndimf; + ipar(6)=ndimi; + ipar(7)=iprint; + ipar(9)=iguess; + ipar(10)=ireg; + + if ifail==1 then + mprintf("%s\n",["ltol = "+sci2exp(ltol,0) + "tol = "+sci2exp(tol,0) + "fixpnt = "+sci2exp(fixpnt,0) + "ipar = "+sci2exp(ipar,0)]) + end + + z=bvode(x,n,m,a,b,zeta,ipar,ltol,tol,fixpnt,%fsub,dfsubA,%gsub,dgsubA,%ys); + +endfunction + +function y=%R(f_,x,z) + if type(f_)==15 then + R_=f_(1); y=R_(x,z,f_(2:$)); + elseif type(f_)==13 then + y=f_(x,z) + end +endfunction + +function y=%fsub(x,z) + y=%R(fsub,x,z); sy=size(y); + if sy(1)==1, y=y', end +endfunction + +function RS=%fsubT(z,x) + RS=%fsub(x,z) +endfunction + +function J=%dfsub(x,z) + sz=size(z);if sz(1)==1, z=z'; end + J=numderivative(list(%fsubT,x),z) +endfunction + +function J=%dfsub1(x,z) + J=%R(dfsub,x,z) +endfunction + +function g=%gsub(i,z) + g=%R(gsub,i,z) +endfunction + +function g=%gsubT(z,i) + g=%gsub(i,z) +endfunction + +function dg=%dgsub(i,z) + sz=size(z);if sz(1)==1, z=z'; end + dg=numderivative(list(%gsubT,i),z) +endfunction + +function dg=%dgsub1(i,z) + dg=%R(dgsub,i,z) +endfunction + +function [z,LhS]=%RR(f_,x) + if type(f_)==15 then + RR_=f_(1); [z,LhS]=RR_(x,f_(2:$)); + elseif type(f_)==13 then + [z,LhS]=f_(x) + end +endfunction + +function [z,LhS]=%ystart(x) + [z,LhS]=%RR(ystart,x) +endfunction + +function [z,LS]=%ystart1(x), + z=0; LS=0; +endfunction diff --git a/modules/optimization/macros/cleanmacros.bat b/modules/optimization/macros/cleanmacros.bat new file mode 100755 index 000000000..66c35f813 --- /dev/null +++ b/modules/optimization/macros/cleanmacros.bat @@ -0,0 +1,3 @@ +@del *.bin /s 2>NUL +@del lib /s 2>NUL +@del names /s 2>NUL
\ No newline at end of file diff --git a/modules/optimization/macros/datafit.bin b/modules/optimization/macros/datafit.bin Binary files differnew file mode 100755 index 000000000..8653bee1d --- /dev/null +++ b/modules/optimization/macros/datafit.bin diff --git a/modules/optimization/macros/datafit.sci b/modules/optimization/macros/datafit.sci new file mode 100755 index 000000000..c1dd616da --- /dev/null +++ b/modules/optimization/macros/datafit.sci @@ -0,0 +1,186 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [p,err]=datafit(imp,G,varargin) + // + // [p,err]=datafit([imp,] G [,DG],Z [,W],...) + // + // Function used for fitting data to a model. + // For a given function G(p,z), this function finds the best vector + // of parameters p for approximating G(p,z_i)=0 for a set of measurement + // vectors z_i. Vector p is found by minimizing + // G(p,z_1)'WG(p,z_1)+G(p,z_2)'WG(p,z_2)+...+G(p,z_n)'WG(p,z_n) + // + // G: Scilab function (e=G(p,z), e: nex1, p: npx1, z: nzx1) + // p0: initial guess (size npx1) + // Z: matrix [z_1,z_2,...z_n] where z_i (nzx1) is the ith measurement + // W: weighting matrix of size nexne (optional) + // DG: partial of G wrt p (optional; S=DG(p,z), S: nexnp) + // + // Examples + // + //deff('y=FF(x)','y=a*(x-b)+c*x.*x') + //X=[];Y=[]; + //a=34;b=12;c=14;for x=0:.1:3, Y=[Y,FF(x)+100*(rand()-.5)];X=[X,x];end + //Z=[Y;X]; + //deff('e=G(p,z)','a=p(1),b=p(2),c=p(3),y=z(1),x=z(2),e=y-FF(x)') + //[p,err]=datafit(G,Z,[3;5;10]) + //xset('window',0) + //clf(); + //plot2d(X',Y',-1) + //plot2d(X',FF(X)',5,'002') + //a=p(1),b=p(2),c=p(3);plot2d(X',FF(X)',12,'002') + // + //a=34;b=12;c=14; + //deff('s=DG(p,z)','y=z(1),x=z(2),s=-[x-p(2),-p(1),x*x]') + //[p,err]=datafit(G,DG,Z,[3;5;10]) + //xset('window',1) + //clf(); + //plot2d(X',Y',-1) + //plot2d(X',FF(X)',5,'002') + //a=p(1),b=p(2),c=p(3);plot2d(X',FF(X)',12,'002') + // + + [lhs,rhs]=argn(0) + + if type(imp)<>1 then + varargin(0)=G + G=imp + imp=0 + end + + if type(G)==15 then + Gparams=G;Gparams(1)=null(); + G=G(1) + else + Gparams=list() + end + + + DG=varargin(1) + if type(DG)==10|type(DG)==11|type(DG)==13 then + GR=%t //Jacobian provided + varargin(1)=null() + elseif type(DG)==15 then + error(msprintf(gettext("%s: Jacobian cannot be a list, parameters must be set in G."),"datafit")); + else + GR=%f + end + + Z=varargin(1); + varargin(1)=null() + if type(Z)<>1 then + error(msprintf(gettext("%s: Wrong measurement matrix."),"datafit")); + end + + nv=size(varargin) + if nv>=1 then + if size(varargin(1),2)==1 then // p0 ou 'b' + W=1 + else + W=varargin(1);varargin(1)=null() + if size(W,1)~=size(W,2) then + if size(W,1)==1 then + error(msprintf(gettext("%s: Initial guess must be a column vector."),"datafit")); + else + error(msprintf(gettext("%s: Weighting matrix must be square."),"datafit")); + end + end + end + end + if type(varargin(1))==1 then // p0 + p0=varargin(1) + else + p0=varargin(4) + end + + [mz,nz]=size(Z);np=size(p0,"*"); + + if type(G)==10 then //form function to call hard coded external + if size(Gparams)==0 then + error(msprintf(gettext("%s: With hard coded function, user must give output size of G."),"datafit")); + end + m=Gparams(1);Gparams(1)=null() + + // foo(m,np,p,mz,nz,Z,pars,f) + deff("f=G(p,Z)","f=call(''"+G+"'',"+.. + "m,1,''i'',np,2,''i'',p,3,''d'',mz,4,''i'',nz,5,''i'',Z,6,''d'',"+.. + "pars,7,''out'',["+string(m)+",1],8,''d'')") + + pars=[]; + for k=1:size(Gparams) + p=Gparams(k) + pars=[pars;p(:)] + end + Gparams=list() + end + + if type(DG)==10 then //form function to call hard coded external + // dfoo(m,np,p,mz,nz,Z,pars,f) + deff("f=DG(p,Z)","f=call(''"+DG+"'',"+.. + "m,1,''i'',np,2,''i'',p,3,''d'',mz,4,''i'',nz,5,''i'',Z,6,''d'',"+.. + "pars,7,''out'',["+string(m)+","+string(np)+"],8,''d'')") + end + + + // form square cost gradient function DGG + + if Gparams==list() then + GP = "G(p,Z(:,i))" + GPPV = "G(p+v,Z(:,i))" + DGP = "DG(p,Z(:,i))" + else + GP = "G(p,Z(:,i),Gparams(:))" + GPPV = "G(p+v,Z(:,i),Gparams(:))" + DGP = "DG(p,Z(:,i),Gparams(:))" + end + + if ~GR then // finite difference + DGG=["g=0*p"; + "pa=sqrt(%eps)*(1+1d-3*abs(p))" + "f=0;" + "for i=1:"+string(nz) + " g1="+GP + " f=f+g1''*W*g1" + "end" + "for j=1:"+string(np) + " v=0*p;v(j)=pa(j)," + " e=0;" + " for i=1:"+string(nz) + " g1="+GPPV + " e=e+g1''*W*g1" + " end" + " g(j)=e-f;" + "end;" + "g=g./pa;"] + else // using Jacobian of G + DGG="g=0;for i=1:nz,g=g+2*"+DGP+"''*W*"+GP+",end" + end + + // form cost function for optim + deff("[f,g,ind]=costf(p,ind)",[ + "if ind==2|ind==4 then " + " f=0;" + " for i=1:"+string(nz) + " g1="+GP + " f=f+g1''*W*g1" + " end" + "else " + " f=0;" + "end"; + "if ind==3|ind==4 then" + DGG + "else" + " g=0*p;" + "end"]) + + [err,p]=optim(costf,varargin(:),imp=imp) + + +endfunction diff --git a/modules/optimization/macros/derivative.bin b/modules/optimization/macros/derivative.bin Binary files differnew file mode 100755 index 000000000..e680681b9 --- /dev/null +++ b/modules/optimization/macros/derivative.bin diff --git a/modules/optimization/macros/derivative.sci b/modules/optimization/macros/derivative.sci new file mode 100755 index 000000000..e6e574d23 --- /dev/null +++ b/modules/optimization/macros/derivative.sci @@ -0,0 +1,186 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - Rainer von Seggern +// Copyright (C) 2008 - Bruno Pincon +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// PURPOSE +// First and second order numerical derivatives of a function F: R^n --> R^m +// by finite differences. +// J=J(x) is the m x n Jacobian (the gradient for m=1), and H=H(x) the Hessian +// of the m components of F at x. The default form of H is a mxn^2 matrix; +// in this form the Taylor series of F up to second order terms is given by: +// +// F(x+dx) = F(x) + J(x)*dx + 1/2*H(x)*(dx.*.dx) +... +// +// NOTES +// 1/ See derivative.cat for details of the parameters +// +// 2/ This function uses the 3 "internal" functions (following +// this one in this file) : +// +// %DF_ => used to compute the Hessian by "differentiating +// the derivative" +// %deriv1_ => contains the various finite difference formulae +// %R_ => to deal with F as this arg may be a scilab +// function or a list embedding a function with +// its parameters +// +function [J,H] = derivative(F, x, h, order, H_form, Q , verbose ) + warnobsolete("numderivative","6.0") + [lhs,rhs]=argn(); + if rhs<2 | rhs>6 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"derivative",2,6)); + end + if type(x) ~= 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: N-dimensional array expected.\n"),"derivative",2)); + end + [n,p] = size(x) + if p ~= 1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A column vector expected.\n"),"derivative",2)); + end + if ~exists("order","local") then + order = 2 + elseif (order ~= 1 & order ~= 2 & order ~= 4) then + error(msprintf(gettext("%s: Order must be 1, 2 or 4.\n"),"derivative")); + end + + if ~exists("H_form","local") then + H_form = "default" + end + + if ~exists("Q","local") then + Q = eye(n,n); + else + if norm(clean(Q*Q'-eye(n,n)))>0 then + error(msprintf(gettext("%s: Q must be orthogonal.\n"),"derivative")); + end + end + if ~exists("h","local") then + h_not_given = %t + // stepsizes for approximation of first derivatives + select order + case 1 + h = sqrt(%eps) + case 2 + h = %eps^(1/3) + case 4 + // TODO : check this, i found 1/5 instead ! + h = %eps^(1/4) + end + else + h_not_given = %f + end + + if ~exists("verbose","local") then + verbose = 0 + end + + if verbose == 1 then + mprintf("h = %s\n", string(h)) + mprintf("order = %d\n", order) + mprintf("H_form = %s\n", H_form) + mprintf("Q = \n") + for i = 1:n + mprintf("%s\n", strcat(string(Q(i,:)), " ")) + end + end + + J = %deriv1_(F, x, h, order, Q) + m = size(J,1); + + if lhs == 1 then + return + end + + if h_not_given then + // stepsizes for approximation of second derivatives + select order + case 1 + h = %eps^(1/3) + case 2 + h = %eps^(1/4) + case 4 + h = %eps^(1/6) + end + end + // H is a mxn^2 block matrix + H = %deriv1_(%DF_, x, h, order, Q) + if H_form == "default" then + // H has the old scilab form + H = matrix(H',n*n,m)' + end + if H_form == "hypermat" then + if m>1 then + // H is a hypermatrix if m>1 + H=H'; + H=hypermat([n n m],H(:)); + end + end + if (H_form ~= "blockmat")&(H_form ~= "default")&(H_form ~= "hypermat") then + error(msprintf(gettext("%s: H_form must be ""default"",""blockmat"" or ""hypermat"", but current H_form=%s\n"),"derivative",H_form)); + end +endfunction + +function z=%DF_(x) + // Transpose ! + z = %deriv1_(F, x, h, order, Q)'; + z = z(:); +endfunction + +function g=%deriv1_(F_, x, h, order, Q) + n=size(x,"*") + Dy=[]; + select order + case 1 + D = h*Q; + y=%R_(F_,x); + for d=D + Dy=[Dy %R_(F_,x+d)-y] + end + g=Dy*Q'/h + case 2 + D = h*Q; + for d=D + Dy=[Dy %R_(F_,x+d)-%R_(F_,x-d)] + end + g=Dy*Q'/(2*h) + case 4 + D = h*Q; + for d=D + dFh = (%R_(F_,x+d)-%R_(F_,x-d))/(2*h) + dF2h = (%R_(F_,x+2*d)-%R_(F_,x-2*d))/(4*h) + Dy=[Dy (4*dFh - dF2h)/3] + end + g = Dy*Q' + end +endfunction + +function y=%R_(F_,x) + if type(F_)==15 then + if ( length(F_) < 2 ) then + error(msprintf(gettext("%s: Wrong number of elements in input argument #%d: At least %d elements expected, but current number is %d.\n"),"derivative",1,2,length(F_))); + end + R=F_(1); + if ( and(typeof(R) <> ["function" "funptr"]) ) then + error(msprintf(gettext("%s: Wrong type for element #%d in input argument #%d: A function is expected, but current type is %s.\n"),"derivative",1,1,typeof(R))); + end + y=R(x,F_(2:$)); + // See extraction, list or tlist case: ... + // But if the extraction syntax is used within a function + // input calling sequence each returned list component is + // added to the function calling sequence. + elseif type(F_)==13 | type(F_)==11 then + y=F_(x); + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: A function expected.\n"),"derivative",1)); + end +endfunction + diff --git a/modules/optimization/macros/karmarkar.bin b/modules/optimization/macros/karmarkar.bin Binary files differnew file mode 100755 index 000000000..399bf5074 --- /dev/null +++ b/modules/optimization/macros/karmarkar.bin diff --git a/modules/optimization/macros/karmarkar.sci b/modules/optimization/macros/karmarkar.sci new file mode 100755 index 000000000..abacfde62 --- /dev/null +++ b/modules/optimization/macros/karmarkar.sci @@ -0,0 +1,736 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// + +// xopt=karmarkar(Aeq,beq,c) +// xopt=karmarkar(Aeq,beq,c,x0) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam,maxiter) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam,maxiter,outfun) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam,maxiter,outfun,A,b) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam,maxiter,outfun,A,b,lb) +// xopt=karmarkar(Aeq,beq,c,x0,rtolf,gam,maxiter,outfun,A,b,lb,ub) +// [xopt,fopt] = karmarkar(...) +// [xopt,fopt,exitflag] = karmarkar(...) +// [xopt,fopt,exitflag,iter] = karmarkar(...) +// [xopt,fopt,exitflag,iter,yopt] = karmarkar(...) +// +// exitflag = 1 if algorithm converged. +// exitflag = 0 if maximum number of iterations was reached. +// exitflag = -1 if no feasible point was found +// exitflag = -2 if problem is unbounded. +// exitflag = -3 if search direction became zero. +// exitflag = -4 if algorithm stopped on user's request. +// exitflag = -5 if duality gap became too large +// exitflag = -%inf on internal error. + +function [xopt,fopt,exitflag,iter,yopt]=karmarkar(varargin) + function argin = argindefault ( rhs , vararglist , ivar , default ) + // Returns the value of the input argument #ivar. + // If this argument was not provided, or was equal to the + // empty matrix, returns the default value. + if ( rhs < ivar ) then + argin = default + else + if ( vararglist(ivar) <> [] ) then + argin = vararglist(ivar) + else + argin = default + end + end + endfunction + + // + [lhs,rhs]=argn(0) + if ( rhs<3 | rhs>12 | rhs==9 ) then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"karmarkar",3,12)); + end + // + Aeq = varargin(1) + beq = varargin(2) + c = varargin(3) + x0 = argindefault ( rhs , varargin , 4 , [] ) + rtolf = argindefault ( rhs , varargin , 5 , 1.d-5 ) + gam = argindefault ( rhs , varargin , 6 , 1/2 ) + maxiter = argindefault ( rhs , varargin , 7 , 200 ) + __karmarkar_outfun__ = argindefault ( rhs , varargin , 8 , [] ) + A = argindefault ( rhs , varargin , 9 , [] ) + b = argindefault ( rhs , varargin , 10 , [] ) + lb = argindefault ( rhs , varargin , 11 , [] ) + ub = argindefault ( rhs , varargin , 12 , [] ) + // + // Check input arguments + // + // + // Check type + // + if ( typeof(Aeq) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",1)); + end + if ( typeof(beq) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",2)); + end + if ( typeof(c) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",3)); + end + if ( typeof(x0) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",4)); + end + if ( typeof(rtolf) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",5)); + end + if ( typeof(gam) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",6)); + end + if ( typeof(maxiter) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",7)); + end + if ( __karmarkar_outfun__ <> [] ) then + if ( and(typeof(__karmarkar_outfun__) <> ["function" "list" "fptr"] ) ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: %s expected.\n"),"karmarkar",8,"function or list")); + end + if ( typeof(__karmarkar_outfun__)=="list" ) then + if ( and(typeof(__karmarkar_outfun__(1))<>["function" "fptr"] ) ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: %s expected.\n"),"karmarkar",8,"function")); + end + end + end + if ( typeof(A) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",9)); + end + if ( typeof(b) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",10)); + end + if ( typeof(lb) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",11)); + end + if ( typeof(ub) <> "constant" ) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"),"karmarkar",12)); + end + // + // Check size + // + [ne,pe]=size(Aeq) + [ni,pi]=size(A) + plb=size(lb,"*") + pub=size(ub,"*") + if ( Aeq <> [] ) then + p = pe + elseif ( A <> [] ) then + p = pi + elseif ( lb <> [] ) then + p = plb + elseif ( ub <> [] ) then + p = pub + else + error(msprintf(gettext("%s: Either one of Aeq, A, lb or ub must be non-empty."),"karmarkar")); + end + // The case where Aeq==[] and A==[] is treated below. + if ( ( Aeq <> [] & beq == [] ) | ( Aeq == [] & beq <> [] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",2)); + end + if ( Aeq <> [] ) then + if ( or ( size(beq) <> [ne 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",2)); + end + end + if ( or ( size(c) <> [p 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",3)); + end + if ( x0 <> [] ) then + if ( or ( size(x0) <> [p 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",4)); + end + end + if ( or ( size(rtolf) <> [1 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",5)); + end + if ( or ( size(gam) <> [1 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",6)); + end + if ( or ( size(maxiter) <> [1 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",7)); + end + if ( A <> [] ) then + if ( Aeq <> [] ) then + if ( pi <> pe ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",9)); + end + end + end + if ( ( A <> [] & b == [] ) | ( A == [] & b <> [] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",10)); + end + if ( b <> [] ) then + if ( size(b) <> [ni 1] ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",10)); + end + end + if ( lb <> [] ) then + if ( or ( size(lb) <> [p 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",11)); + end + end + if ( ub <> [] ) then + if ( or ( size(ub) <> [p 1] ) ) then + error(msprintf(gettext("%s: Wrong size for input argument #%d."),"karmarkar",12)); + end + end + // + // Check content + // + if ( rtolf < 0 | rtolf > 1 ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. rtolf must be in [0,1]."),"karmarkar",5)); + end + if ( gam < 0 | gam > 1 ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. gam must be in [0,1]."),"karmarkar",6)); + end + if ( maxiter < 1 ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. maxiter must be greater than 1."),"karmarkar",7)); + end + if ( floor(maxiter) <> maxiter ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. maxiter must be a floating point integer."),"karmarkar",7)); + end + if ( lb == [] & ub == [] ) then + if ( x0 <> [] ) then + if ( min(x0)<0 ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. x0 is not positive."),"karmarkar",4)); + end + end + end + if ( lb <> [] & ub <> [] ) then + if ( or ( ub < lb ) ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. One entry of the upper bound ub is lower than the lower bound lb."),"karmarkar",12)); + end + end + if ( lb <> [] & x0 <> [] ) then + if ( or ( lb > x0 ) ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. x0 lower than lower bound lb."),"karmarkar",12)); + end + end + if ( ub <> [] & x0 <> [] ) then + if ( or ( ub < x0 ) ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. x0 greater than upper bound ub."),"karmarkar",12)); + end + end + // + // Proceed + // + // Transform the general LP into standard form + [AAeq,bbeq,cc,xx0,pinit,newposvars] = karmarkar_preprocess ( Aeq , beq , c , A , b , lb , ub , x0 ) + // + // Solve the standard form LP + outfun = list(__karmarkar_outfun__ , pinit , newposvars ) + [xxopt,fopt,exitflag,iter,yyopt] = karmarkar_findStandardLP ( AAeq , bbeq , cc , xx0 , rtolf , gam , maxiter , outfun ) + // + // Extract the solution from the initial problem + [xopt,fopt,yopt] = karmarkar_postprocess ( Aeq , beq , c , A , b , lb , ub , pinit , xxopt , yyopt , exitflag ) + + if lhs < 3 & exitflag~= 1 then + warning(msprintf(gettext("%s: The algorithm did not converge (exitflag= %d).\n"),"karmarkar",exitflag)); + end + +endfunction + +function [AAeq,bbeq,cc,xx0,pinit,newposvars] = karmarkar_preprocess ( Aeq , beq , c , A , b , lb , ub , x0 ) + // Transform the general LP into a standard LP. + // + // Parameters + // Aeq : a ne-by-p matrix of doubles, the matrix of linear equality constraints + // beq : a ne-by-1 matrix of doubles, the right hand side of linear equality constraints + // A : a ni-by-p matrix of doubles, the matrix of linear inequality constraints + // b : a ni-by-1 matrix of doubles, the right hand side of linear inequality constraints + // c : a p-by-1 matrix of doubles, the linear objective + // x0 : a p-by-1 matrix of doubles, the initial guess. If x0=[], this means that no initial guess is provided. + // AAeq : a m-by-q matrix of doubles, the matrix of linear equality constraints. We have m = ne + ni and q = p + ni. + // bbeq : a m-by-1 matrix of doubles, the right hand side of linear equality constraints + // cc : a p-by-1 matrix of doubles, the linear objective + // xx0 : a q-by-1 matrix of doubles, the initial guess. If xx0=[], this means that no initial guess is provided. + // pinit : the initial value of p. The solution of the original general LP is xs(1:pinit), where xs is the solution of the modified standard LP. + // newposvars : a 1-by-1 matrix of booleans, %f if no positive variables have been introduced, %t if positive variables have been introduced. + // + // Description + // Transform the general linear program into a standard linear program. + // + // More precisely, if A <> [] transform the general linear program (L.P.): + // + // min c'*x + // A * x <= b + // Aeq * x = beq + // + // into the standard LP: + // + // min cc'*z + // AAeq * z = bbeq + // z >= 0 + // + // where z is the new unknown, positive, which may contain slack variables. + // + // An unrestricted variable xi is transformed into x = xp - xn, where xp,xn >= 0. + // This turns the inequality constraint Ax <= b into [A -A][xp;xn] <= b. + // The inequality constraint is turned into an equality constraint by introducing + // slack variables si. + // This transforms the inequality into: [A -A][xp;xn] + s = b which can be written : + // + // [A -A I][xp;xn;s] = b + // + // Therefore, the number of variables increases from pinit to 2*pinit + ni. + // The initial variable is x(1:pinit)-x(pinit+1:2*pinit). + // The same happens for the equality constraints which is turned from + // Aeq*x=b to [Aeq -Aeq 0][xp;xn;s]=b. + // The cost function is turned from c'*x into [c;-c;0]'[xp;xn]. + // + newposvars = %f + // + [ne,pe]=size(Aeq) + [ni,pi]=size(A) + plb=size(lb,"*") + pub=size(ub,"*") + if ( Aeq <> [] ) then + pinit = pe + elseif ( A <> [] ) then + pinit = pi + elseif ( lb <> [] ) then + pinit = plb + elseif ( ub <> [] ) then + pinit = pub + end + // + if ( A == [] & lb == [] & ub == [] ) then + AAeq = Aeq + bbeq = beq + cc = c + xx0 = x0 + return + end + // + // Process the lower bound : x >= lb. + // Move it as an inequality constraint: -I * x <= -lb. + // TODO : process the case lb <> [] by shifting x (instead of introducing positive variables). + if ( lb <> [] ) then + if ( A == [] ) then + A = -eye(plb,plb) + b = -lb + else + A = [A;-eye(plb,plb)] + b = [b;-lb] + end + end + // + // Process the upper bound : x <= ub. + // Move it as an inequality constraint : I * x <= ub. + if ( ub <> [] ) then + if ( A == [] ) then + A = eye(pub,pub) + b = ub + else + A = [A;eye(pub,pub)] + b = [b;ub] + end + end + // + // Remove constraints where b(i) = %inf. + // Such an A(i,:)*x <= %inf = b(i) will be satisfied anyway, but + // may cause failures in the algorithm. + iinf = find(b == %inf) + b(iinf) = [] + A(iinf,:) = [] + // + // Create the map from the initial constraints to the final constraints. + // + // Update the number of inequalities, + // given that the bounds have been updated. + [ni,pi]=size(A) + // + // Initialize AAeq, bbeq, cc and xx0. + // + // If ni inequality constraints are given, transform the problem by + // adding pinit positive variables and ni slack variables. + // The inequality is Ax <= b. + if ( A <> [] ) then + // + // Create the matrix + // AAeq = [ + // Aeq -Aeq 0 + // A -A I + // ] + AAeq (1:ne+ni,1:2*pinit+ni) = zeros(ne+ni,2*pinit+ni) + if ( Aeq <> [] ) then + AAeq (1:ne,1:pinit) = Aeq + AAeq (1:ne,pinit+1:2*pinit) = -Aeq + end + AAeq (ne+1:ne+ni,1:pinit) = A + AAeq (ne+1:ne+ni,pinit+1:2*pinit) = -A + AAeq (ne+1:ne+ni,2*pinit+1:2*pinit+ni) = eye(ni,ni) + bbeq = [beq;b] + cc = [c;-c;zeros(ni,1)] + newposvars = %t + if ( x0 == [] ) then + xx0 = [] + else + xx0 = zeros(2*pinit+ni,1) + xx0(1:pinit) = max(x0,0) + xx0(pinit+1:2*pinit) = -min(x0,0) + s = b - A*x0 + if ( min(s)<0 ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. x0 does not satisfy the inequality constraints."),"karmarkar",4)); + end + xx0(2*pinit+1:2*pinit+ni) = s + end + end +endfunction + +function [xopt,fopt,yopt] = karmarkar_postprocess ( Aeq , beq , c , A , b , lb , ub , pinit , xxopt , yyopt , exitflag ) + // Transform the solution of the standard LP into the solution of the original general LP. + // + // Extract the solution from the initial problem + if ( pinit < size(xxopt,"*") ) then + xopt = xxopt(1:pinit) - xxopt(pinit+1:2*pinit) + else + xopt = xxopt + end + // + // Extract the dual solution. + [ne,pe]=size(Aeq) + [ni,pi]=size(A) + plb=size(lb,"*") + pub=size(ub,"*") + // + // Initialize + if ( yyopt == [] ) then + yopt.ineqlin = [] + yopt.eqlin = [] + yopt.lower = [] + yopt.upper = [] + else + yopt.ineqlin = [] + yopt.eqlin = [] + yopt.lower = zeros(pinit,1) + yopt.upper = zeros(pinit,1) + end + // + // Update depending on the presence of the options. + kstart = 1 + if ( ne > 0 ) then + kstop = kstart + ne - 1 + yopt.eqlin = -yyopt(kstart:kstop) + kstart = kstop + 1 + end + if ( ni > 0 ) then + noninf = find(b<>%inf) + kinf = find(b==%inf) + kstop = kstart + ni - 1 - size(kinf,"*") + yopt.ineqlin(noninf) = -yyopt(kstart:kstop) + kstart = kstop + 1 + end + if ( ni == 0 & plb == 0 & pub == 0 ) then + yopt.lower = c - Aeq'*yyopt + elseif ( plb > 0 ) then + noninf = find(lb<>%inf) + kinf = find(lb==%inf) + kstop = kstart + plb - 1 - size(kinf,"*") + yopt.lower(noninf) = -yyopt(kstart:kstop) + kstart = kstop + 1 + end + if ( pub > 0 ) then + noninf = find(ub<>%inf) + kinf = find(ub==%inf) + kstop = kstart + pub - 1 - size(kinf,"*") + yopt.upper(noninf) = -yyopt(kstart:kstop) + kstart = kstop + 1 + end +endfunction + +function [xopt,fopt,exitflag,iter,yopt] = karmarkar_findStandardLP ( Aeq , beq , c , x0 , rtolf , gam , maxiter , outfun ) + // Solves a linear problem in standard form (searches for x0 if necessary). + // + // Parameters + // pinit : a 1-by-1 matrix of floating point integers, the number of parameters before the introduction of slack variables. + // + // Given x0, uses a primal affine scaling (P.A.S.) algorithm to iteratively + // find the solution of a linear program in standard form: + // + // min c'*x + // Aeq*x = beq + // x >= 0 + // + // If x0 is the empty matrix, compute a strictly feasible point. + // + [ne,p]=size(Aeq) + if ( x0 == [] ) then + // + // Compute a strictly feasible point. + // + // Add an extra variable x(p+1) and solve : + // + // min z(p+1) + // AAeq*z = beq + // z >= 0 + // + // where z=[x(1) x(2) ... x(p) x(p+1)]. + // AAeq has the same number of rows, but one column more than Aeq. + // The initial guess for the modified problem is z0=[1 1 ... 1]=e(n+1). + // The last column of AAeq is beq-Aeq*e(n) so that the initial guess z0 satisfies AAeq*z0=beq. + // + // References + // "A Primal-Dual Exterior Point Algorithm For Linear Programming Problems" + // Nikolaos Samaras, Angelo Sifaleras, Charalampos Triantafyllidis + // Yugoslav Journal of Operations Research + // Vol 19 (2009), Number 1, 123-132 + // + // "A modification of karmarkar's linear programming algorithm", + // Robert J. Vanderbei, Marc S. Meketon and Barry A. Freedman, + // Algorithmica, Volume 1, Numbers 1-4, 395-407, 1986. + // + s = beq - Aeq*ones(p,1) + AAeq = [Aeq,s] + cc = [zeros(p,1);1] + xx0 = ones(p+1,1) + step = 1 + xfeasmax = %eps + iterstart = 0 + [xopt1,fopt1,exitflag1,iter1,yopt1] = karmarkar_findxopt ( AAeq , beq , cc , xx0 , rtolf , gam , maxiter , outfun , step , xfeasmax , iterstart ) + if ( exitflag1 <> 1 ) then + // The algorithm did not converge. + xopt = [] + fopt = [] + exitflag = -1 + iter = iter1 + yopt = [] + return + end + x0 = xopt1(1:p) + else + iter1 = 0 + end + // + // Check that the initial guess is feasible. + if ( x0 <> [] ) then + if ( norm(Aeq*x0-beq)>sqrt(%eps)*norm(beq) ) then + error(msprintf(gettext("%s: Wrong value for input argument #%d. x0 does not satisfy the equality constraints."),"karmarkar",4)); + end + end + // + // Find the optimum x + step = 2 + xfeasmax = %nan + iterstart = iter1 + [xopt,fopt,exitflag,iter,yopt] = karmarkar_findxopt ( Aeq , beq , c , x0 , rtolf , gam , maxiter , outfun , step , xfeasmax , iterstart ) +endfunction + +function [xopt,fopt,exitflag,iter,yopt] = karmarkar_findxopt ( Aeq , beq , c , x0 , rtolf , gam , maxiter , outfun , step , xfeasmax , iterstart ) + // Solves a linear problem in standard form, given x0. + // + // Parameters + // step : a 1-by-1 matrix of floating point integers, the kind of algorithm performed. We have step=1 during the search for a feasible point x0, and step=2 during the search for x*. + // xfeasmax : a 1-by-1 matrix of double, the maximum value of the feasibility variable, during the search for a feasible point x0. + // pinit : a 1-by-1 matrix of floating point integers, the number of parameters before the introduction of slack variables. + // iterstart : the initial number of iterations, including the iterations of the previous steps + // + // Description + // Given x0, uses a primal affine scaling (P.A.S.) algorithm to iteratively + // find the solution of a linear program in standard form: + // + // min c'*x + // Aeq*x = beq + // x >= 0 + // + // We assume that x0 is strictly feasible, i.e. || Aeq*x0-beq || is small and x0 > 0. + // + // If step = 1, we stop when xopt($) is below the feasibility threshold xfeasmax. + // If step = 2, we stop when the objective function does not vary anymore, or the maximum number + // of iterations exceeds the maximum, or the users asks to. + // + // exitflag = 1 if algorithm converged. + // exitflag = 0 if maximum number of iterations was reached. + // exitflag = -2 if problem is unbounded. + // exitflag = -3 if search direction became zero. + // exitflag = -4 if step=2 and algorithm stopped on user's request. + // exitflag = -%inf on internal error. + // + // References + // "A variation on Karmarkar’s algorithm for solving linear programming problems, + // Earl R. Barnes, Mathematical Programming, Volume 36, Number 2, 174-182, 1986. + // + // "A modification of karmarkar's linear programming algorithm", + // Robert J. Vanderbei, Marc S. Meketon and Barry A. Freedman, + // Algorithmica, Volume 1, Numbers 1-4, 395-407, 1986. + // + // "Practical Optimization: Algorithms and Engineering Applications", + // Andreas Antoniou, Wu-Sheng Lu, Springer, 2007, + // Chapter 12, "Linear Programming Part II: Interior Point Methods". + // + [ne,p]=size(Aeq) + xopt=x0 + yopt = [] + tc=c' + fopt=tc*xopt + dualgapmin = %inf + dualgap = %inf + funccount = 1 + fprev = fopt+1 + iter=iterstart + s = zeros(p,1) + stop = %f + exitflag = -%inf + firstloop = %t + // + state = "init" + if ( step == 1 ) then + procedure = "x0" + else + procedure = "x*" + end + optimValues = struct(... + "funccount" , funccount , ... + "fval" , fopt , ... + "iteration" , iter , ... + "procedure" , procedure, ... + "dualgap" , dualgap ... + ); + stop = karmarkar_outfunDriver ( xopt , optimValues , state , outfun ) + // + while ( %t ) + if ( iter >= maxiter ) then + exitflag = 0 + break + end + if ( step == 1 ) then + if ( xopt($) <= xfeasmax ) then + exitflag = 1 + break + end + end + if ( step == 2 ) then + if ( abs(fprev-fopt)<=rtolf*abs(fprev) ) then + exitflag = 1 + break + end + end + // + // Compute the duality gap + if ( dualgap > 1.e5 * dualgapmin ) then + // Unbounded problem. + exitflag = -2 + break + end + // + // Calls back the output function + if ( step == 1 ) then + state = "init" + else + state = "iter" + end + if ( step == 1 ) then + procedure = "x0" + else + procedure = "x*" + end + optimValues = struct(... + "funccount" , funccount , ... + "fval" , fopt , ... + "iteration" , iter , ... + "procedure" , procedure, ... + "dualgap" , dualgap ... + ); + stop = karmarkar_outfunDriver ( xopt , optimValues , state , outfun ) + if ( stop ) then + exitflag = -4 + break + end + iter=iter+1 + // Compute B as B = Aeq*X where X = diag(xopt). + // The following method is equivalent, but faster. + xt = xopt' + B = Aeq.*xt(ones(ne,1),:) + v = xopt.*c + // y = inv(B*B') * (B*v) i.e. y is the solution of (B*B') y = B*v. + // This implies that y is the solution of (B')*y = v, i.e. + yopt = B'\v + p = -v+B'*yopt + if ( min(p)==0 ) then + exitflag = -3 + break + end + d = xopt.*p + if ( min(d)>0 ) then + // Unbounded problem. + exitflag = -2 + break + end + alpha = -gam / min(p) + s = alpha*d + xopt=xopt+s + fprev = fopt + fopt=tc*xopt + funccount = funccount + 1 + // + // Compute the duality gap + dualgap = abs(yopt'*beq - fopt) + if ( firstloop ) then + dualgapmin = dualgap + else + if ( dualgapmin > dualgap ) then + dualgapmin = dualgap + end + end + firstloop = %f + end + // + if ( step == 1 ) then + state = "init" + else + state = "done" + end + if ( step == 1 ) then + procedure = "x0" + else + procedure = "x*" + end + optimValues = struct(... + "funccount" , funccount , ... + "fval" , fopt , ... + "iteration" , iter , ... + "procedure" , procedure, ... + "dualgap" , dualgap ... + ); + stop = karmarkar_outfunDriver ( xopt , optimValues , state , outfun ) +endfunction + +function stop = karmarkar_outfunDriver ( xopt , optimValues , state , outfun ) + // + // The driver for the output function. + // outfun : a list where the first item is the output function. + __karmarkar_outfun__ = outfun (1) + pinit = outfun (2) + newposvars = outfun (3) + // + // Calls back the user's output function, if required. + // Reduce the size of the vectors, to take into account for potential slack variables. + if ( __karmarkar_outfun__ <> [] ) then + if ( newposvars ) then + xopt = xopt(1:pinit) - xopt(pinit+1:2*pinit) + else + xopt = xopt(1:pinit) + end + cbktype = typeof( __karmarkar_outfun__ ) + if ( cbktype == "list" ) then + __karmarkar_outfun__f_ = __karmarkar_outfun__ (1) + stop = __karmarkar_outfun__f_ ( xopt , optimValues , state , __karmarkar_outfun__ (2:$)) + elseif ( or(cbktype == ["function" "fptr"] ) ) then + stop = __karmarkar_outfun__ ( xopt , optimValues , state ) + end + else + stop = %f + end +endfunction + + diff --git a/modules/optimization/macros/leastsq.bin b/modules/optimization/macros/leastsq.bin Binary files differnew file mode 100755 index 000000000..43384ee30 --- /dev/null +++ b/modules/optimization/macros/leastsq.bin diff --git a/modules/optimization/macros/leastsq.sci b/modules/optimization/macros/leastsq.sci new file mode 100755 index 000000000..418ebdf4c --- /dev/null +++ b/modules/optimization/macros/leastsq.sci @@ -0,0 +1,103 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function [f,x,g]=leastsq(imp,fun,varargin) + + // n p + // min sum (fun(x).^2) where fun is a function from R to R + // x + // + // [f]=fun(x) computes the value f of the function at the point x + // and the gradient g of f at x g(i,j)=Dfi/dxj + if type(imp)<>1 then + varargin(0)=fun + fun=imp + imp=0 + end + + if type(fun)==15 then + fn=fun(1);params=fun;params(1)=null() + else + fn=fun;params=list() + end + + Dfun=varargin(1),kr=1; + if type(Dfun)==10 then //the 'b' keyword or the jacobian entry point name + if Dfun=="b" & size(varargin) >= 3 then + if type(varargin(2))==1 & type(varargin(3))==1 then + J=%f //bounds specification + else + J=%t //jacobian + end + else + J=%t //jacobian + end + elseif type(Dfun)==11|type(Dfun)==13 then + J=%t //Jacobian provided + elseif type(Dfun)==15 then + error(msprintf(gettext("%s: Jacobian cannot be a list, parameters must be set in fun."),"leastsq")); + else + J=%f; + end + if J then, varargin(1)=null(), end // to correct bug 1219 (bruno, 22 feb 2005) + kr=1 + + if varargin(kr)=="b" then kr=kr+3,end + x0=varargin(kr) + + if type(fn)==10 then //hard coded function given by its name + if size(params)==0 then + error(msprintf(gettext("%s: With hard coded function, user must give output size of fun."),"leastsq")); + end + m=params(1);params(1)=null() + n=size(x0,"*") + // foo(m,nx,x,params,f) + deff("f=fn(x)","f=call(''"+fn+"'',"+.. + "m,1,''i'',n,2,''i'',x,3,''d'',"+.. + "pars,4,''d'',''out'',["+string(m)+",1],5,''d'')") + + pars=[]; + for k=1:size(params) + p=params(k) + pars=[pars;p(:)] + end + params=list() + + end + + if J then //jacobian given + if type(Dfun)==10 then //form function to call hard coded external + // dfoo(m,nx,x,params,g) + deff("g=Dfun(x)","g=call(''"+Dfun+"'',"+.. + "m,1,''i'',n,2,''i'',x,3,''d'',"+.. + "pars,4,''d'',''out'',["+string(m)+","+string(n)+"],5,''d'')") + end + else + if params==list() then + deff("g=Dfun(x)","g=numderivative(fn,x)") + else + deff("g=Dfun(x,varargin)","g=numderivative(list(fn,varargin(:)),x)") + end + end + + if params==list() then + deff("[f,g,ind]=%opt(x,ind)",[ + "ff=fn(x);gf=Dfun(x)" + "f=sum(ff.^2)" + "g=2*(gf''*ff(:))"]) + else + deff("[f,g,ind]=%opt(x,ind)",[ + "ff=fn(x,params(:));gf=Dfun(x,params(:))" + "f=sum(ff.^2)" + "g=2*(gf''*ff(:))"]) + end + + [f,x,g]=optim(%opt,varargin(:),imp=imp) +endfunction + diff --git a/modules/optimization/macros/lib b/modules/optimization/macros/lib Binary files differnew file mode 100755 index 000000000..1aa14478d --- /dev/null +++ b/modules/optimization/macros/lib diff --git a/modules/optimization/macros/list2vec.bin b/modules/optimization/macros/list2vec.bin Binary files differnew file mode 100755 index 000000000..7c6a74fc6 --- /dev/null +++ b/modules/optimization/macros/list2vec.bin diff --git a/modules/optimization/macros/list2vec.sci b/modules/optimization/macros/list2vec.sci new file mode 100755 index 000000000..f2ae4cfd2 --- /dev/null +++ b/modules/optimization/macros/list2vec.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [bigVector,varsizes]=list2vec(li) + //li=list(X1,...Xk) is a list of matrices + //bigVector: big vector [X1(:);...;Xk(:)] (stacking of matrices in li) + //varsizes: k x 2 matrix, with varsiz(i,:)=size(Xi) + bigVector=[];varsizes=[]; + li=aplat(li) + for mati=li + sm=size(mati); + varsizes=[varsizes;sm]; + bigVector=[bigVector;matrix(mati,-1,1)]; + + end +endfunction diff --git a/modules/optimization/macros/lmisolver.bin b/modules/optimization/macros/lmisolver.bin Binary files differnew file mode 100755 index 000000000..9831ad689 --- /dev/null +++ b/modules/optimization/macros/lmisolver.bin diff --git a/modules/optimization/macros/lmisolver.sci b/modules/optimization/macros/lmisolver.sci new file mode 100755 index 000000000..208b7a0ec --- /dev/null +++ b/modules/optimization/macros/lmisolver.sci @@ -0,0 +1,456 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [%Xlist,%OPT]=lmisolver(%Xinit,%evalfunc,%options) + %OPT=[];%Xlist=list(); + [LHS,RHS]=argn(0); + + if RHS < 2 then + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),"lmisolver",2,3)) + end + + if RHS==2 then + %Mb = 1e3;%ato = 1e-10;%nu = 10;%mite = 100;%rto = 1e-10; + else + %Mb=%options(1);%ato=%options(2);%nu=%options(3);%mite=%options(4);%rto=%options(5); + end + + %to=1e-5 + %tol=1e-10 + + [%Xinit,%ind_X]=aplat(%Xinit); + + %dim_X=[] + for %ia=1:size(%Xinit) + %dim_X=[%dim_X;size(%Xinit(%ia))] + end + + %x0=list2vec(%Xinit); + %nvars=size(%x0,"*") + + //Testing feasibility of initial guess + [%E,%I,%O]=%evalfunc(vec2list(%x0,%dim_X,%ind_X)); + if size(%O,"*")==0 then //only feasible point is searched + if lmicheck(aplat(%E),aplat(%I)) then + %Xlist=vec2list(%x0,%dim_X,%ind_X); + lmisolvertrace(msprintf(_("%s: initial guess is feasible."),"lmisolver")); + // only feasibility claimed and given initial value is feasible, so + // there in nothoting to do! + return; + end + end + + + //Construction of canonical representation: + //A first transformation is applied to form explicit linear equations: + // LMIs Hj(X1,X2,...,XN) > 0 gives I0 + I1*x1+...+In*xn >0 + // LMEs Gi(X1,X2,...,XN)=0 gives E0 + E1*x1+...+En*xn =0 + // Obj O(X1,X2,...,XN) gives O0 + O1*x1+...+On*xn + // where Fi, Ci are matrices and fi scalars this is done using the + // cannonical basis for the vector space of {X1,X2,...,XN}. The xi i=1..n are + // the unknown components for this cannonical basis + + // A second transformation I0v=I0(:); Iiv=Fi(:) ; + // E0v=V0(:); Eiv=Ei(:) ; + // allows to rewrite the LMIs as I0v+I*X, the LMEs as E0v+E*X; + // and the Objective as O0+O*X + // where + // X is a column vector of all undknowns + // I=[I1v, ..., Inv] + // E=[E1v, ..., Env] + // O=[O1, ..., On] + // allows to rewrite + + //compute affine parts of LME LMI and OBJ + [%E0,%I0,%O0]=%evalfunc(vec2list(zeros(%nvars,1),%dim_X,%ind_X)); + + %E0v=list2vec(aplat(%E0)); + %I0=aplat(%I0); + %O0v=list2vec(aplat(%O0)); + + %blck_szs=[]; + for %lmii=%I0 + [%mk,%mk]=size(%lmii);%blck_szs=[%blck_szs,%mk] + end + %blck_szs=%blck_szs(find(%blck_szs~=0)); + [%I0v,%dim_I]=list2vec(%I0); + + + %E=[];%I=[];%O=[]; + + lmisolvertrace(msprintf(_("%s: Construction of canonical representation."),"lmisolver")); + %spI0=sparse(%I0v); //the sparse representation of F0 + %spE0=sparse(%E0v); //the sparse representation of C0 + %lX=size(%Xinit) + + %XZER=%Xinit + for %ka=1:%lX + %XZER(%ka)=sparse(0*%Xinit(%ka)); + end + //construct a generators for LMI, LME and Obj ranges using a cannonical + //basis for {X1, ..., Xn} + for %ja=1:%lX //loop on matrices Xi + %row=%dim_X(%ja,1) + %coll=%dim_X(%ja,2) + for %ca=1:%coll //loop on columns of Xi + for %ra=1:%row //loop on rows of Xi + //set the cannonical basis vector + %XZER(%ja)(%ra,%ca)=1; + + //compute LME LMI and OBJ component for this base vector + [%Ei,%Ii,%Oi]=%evalfunc(recons(%XZER,%ind_X)); + //transform into sparse column vectors + %Eiv=splist2vec(%Ei)-%spE0; + %Iiv=splist2vec(%Ii)-%spI0; + //assemble the matrices + %E=[%E,%Eiv]; + %I=[%I,%Iiv]; + %O=[%O,%Oi-%O0]; + + //reset XZER to zero + %XZER(%ja)(%ra,%ca)=0; + end + end + end + clear %spI0 %spE0 + // all the LMIs may be generated by %I*X + %I0v + // the LMEs may be generated by %E*X + %E0v + // the OBJs may be generated by %O*X + %O0 + // for any column vector X + + + + if size(%E,"*")==0 then + %kerE=speye(%nvars,%nvars); + else + lmisolvertrace(msprintf(_("%s: Basis Construction."),"lmisolver")); + //reduce the LMEs: all X solution of %E*X + %E0v can be written + // X=X0+ker(%E)*W + //where + // X0 is a X such that %E*X + %E0v=0 + //and + // W is arbitrary (the new unknown) + + [%x0,%kerE]=linsolve(%E,%E0v,%x0); + clear %E + //now %kerE contains the kernel + end + // all the LMIs may then be generated by %I*(X0+ker(%E)*W) + %I0v + // the LMEs by %E*(X0+ker(%E)*W) + %E0v + // the OBJs by %O*(X0+ker(%E)*W) + %O0 + %I0v=%I0v+%I*%x0; + %I=%I*%kerE; + %O0=%O0+%O*%x0; + %O=%O*%kerE; + clear %E + //with this updated notations + // all the LMIs may then be generated by %I*W + %I0v + // the OBJs by %O*W + %O0 + // The initial unknown may be obtained by X=%x0+%kerE*W + + if %blck_szs == [] then + // is objective constant on LME constraint set, Xinit is feasible + if max(abs(%O+0)) < %to then + lmisolvertrace(msprintf(_("%s: Objective constant."),"lmisolver")); + %Xlist=vec2list(%x0,%dim_X,%ind_X); + %Xopt=%O0; + return + else + error(msprintf(_("%s: solution unbounded."),"lmisolver")); + end + end + + [%fm,%m]=size(%I); + //Testing well-posedness + if %fm<%m then + error(msprintf(_("%s: Ill-posed problem. Number of unknowns (%s) > number of constraints (%s)"),"lmisolver",%m,%fm)); + end + + + //Testing rank deficiency + if size(%I,"*")<>0 then + + [%ptr,%rk]=lufact([%I spzeros(%fm,%fm-%m)]',[%tol,0.001]); + if %rk<%m then + [%P,%L,%U,%Q]=luget(%ptr);%L=[];%U=[];%Q=[]; + %P=%P';%P=%P(1:%rk,1:%m)'; + warning(msprintf(_("%s: rank deficient problem"),"lmisolver")); + ludel(%ptr); + //Testing to see if linobj is in the range of F_is + if size(%O,"*") <> 0 then + [%ptr,%rk2]=lufact([[%I;%O] spzeros(%fm+1,%fm+1-%m)]',[%tol,0.001]); + ludel(%ptr); + if %rk<%rk2 then + error(msprintf(_("%s: solution unbounded."),"lmisolver")); + end + end + %O=%O*%P + %I=%I*%P; + %kerE=%kerE*%P; + %m=%rk; + %P=[]; + + end + end + + //Testing to see if solution or the LMI value is unique + if size(%I,"*")==0 then //the LMI reduces to %I0 >0 + //checking positiveness of %I0 + if ~lmicheck(list(),vec2list(%I0v,%dim_I)) + error(msprintf(_("%s: not feasible or badly defined problem."),"lmisolver")); + else + %Xlist=vec2list(%x0,%dim_X,%ind_X); + return; + end + end + + //Testing feasibility of initial guess + //are LMIs positive? + [ok,%sm]=lmicheck(list(),vec2list(%I0v,%dim_I)) + + if ok&size(%O,"*")==0 then + //LMIs are positive, problem is feasible, return + %Xlist=vec2list(%x0,%dim_X,%ind_X); + return; + end + + %M=%Mb*norm([%I0v,%I],1) + + + if ~(%sm>%to) then + //given initial point is not feasible. Look for a feasible initial point. + lmisolvertrace(msprintf(_("%s: FEASIBILITY PHASE."),"lmisolver")); + + // mineigI is the smallest eigenvalue of I0 + %mineigI=min(real(flat_block_matrix_eigs(%I0v,%blck_szs))) + + // Id is the identity + %Id = build_flat_identity(%blck_szs) + if (%M < %Id'*%I0v+1e-5), + error(msprintf(_("%s: Mbound too small."),"lmisolver")); + end; + + // initial x0 + %x00 = [zeros(%m,1); max(-1.1*%mineigI, 1e-5)]; + + //Compute Z0 the projection of Id on the space Tr Ii*Z = 0 + + %Z0=%Id-%I*(%I\%Id); + if %f then + //check: trace(Ii*Z0) = 0 <=> %Id'*%Z0= 0 + %I'*%Z0 + end + //compute mineigZ is the smallest eigenvalue of Z0 + %mineigZ=min(real(flat_block_matrix_eigs(%Z0,%blck_szs))); + %ka=sum(%blck_szs.^2); + %Z0(%ka+1) = max( -1.1 *%mineigZ, 1e-5 ); // z + %Z0(1:%ka) = %Z0(1:%ka) + %Z0(%ka+1)*%Id; + %Z0 = %Z0 / (%Id'*%Z0(1:%ka)); // make Tr Z0 = 1 + + if %f then //for checking semidef + Z=sysdiag(matrix(%Z0(1:16),4,-1),%Z0(17)) + F0=full(sysdiag(matrix(%I0v,4,-1), %M-%Id'*%I0v)); + for i=1:10, + Fi=full(sysdiag(matrix(%I(:,i),4,-1),-%Id'*%I(:,i))); + mprintf("i=%d %e\n",i,abs(trace(Fi*Z)-%c(i))); + end + F11=sysdiag(matrix(%Id,4,-1),0); + mprintf("i=%d %e\n",11,abs(trace(F11*Z)-%c(11))) + + end + + //Pack Z0 and I + %Z0=pack(%Z0,[%blck_szs,1]); + + %temp=full(pack([%I0v, %I, %Id; + %M-%Id'*%I0v, -%Id'*%I, 0 ],[%blck_szs,1])); + %c=[zeros(%m,1); 1]; + + [%xi,%Z0,%ul,%info]=semidef(%x00,%Z0,%temp,[%blck_szs,1],%c,[%nu,%ato,-1,0,%mite]); + %temp=[]; + %xi=%xi(1:%m); + + select %info(1) + case 1 + error(msprintf(_("%s: Max. iters. exceeded."),"lmisolver")) + case 2 then + lmisolvertrace(msprintf(_("%s: Absolute accuracy reached."),"lmisolver")) + case 3 then + lmisolvertrace(msprintf(_("%s: Relative accuracy reached."),"lmisolver")) + case 4 then + lmisolvertrace(msprintf(_("%s: Target value reached."),"lmisolver")) + case 5 then + error(msprintf(_("%s: Target value not achievable."),"lmisolver")) + else + warning(msprintf(_("%s: No feasible solution found."),"lmisolver")) + end + + + if %info(2) == %mite then + error(msprintf(_("%s: max number of iterations exceeded."),"lmisolver")); + end + if (%ul(1) > %ato) then + error(msprintf(_("%s: No feasible solution exists."),"lmisolver")); + end + // if (%ul(1) > 0) then %I0v=%I0v+%ato*%Id;end + + lmisolvertrace(msprintf(_("%s: feasible solution found."),"lmisolver")); + + else + + lmisolvertrace(msprintf(_("%s: Initial guess feasible."),"lmisolver")); + %xi=zeros(%m,1); + end + + + if size(%O,"*")<>0 then + + lmisolvertrace(msprintf(_("%s: OPTIMIZATION PHASE.") ,"lmisolver")); + + %M = max(%M, %Mb*sum(abs([%I0v,%I]*[1; %xi]))); + + // Id is the identity + %Id = build_flat_identity(%blck_szs) + // M must be greater than trace(F(x0)) for bigM.sci + [%ptr,%rkA]=lufact(%I'*%I,[%tol,0.001]); + %Z0=lusolve(%ptr,full(%I'*%Id-%O')); + %Z0=%Id-%I*%Z0; + ludel(%ptr) + + //check: trace(Ii*Z0) = c <=> %I(:,k)'*%Z0= %O(k) (k = 1:m) + // mineigZ is the smallest eigenvalue of Z0 + %mineigZ=min(real(flat_block_matrix_eigs(%Z0,%blck_szs))) + %ka=sum(%blck_szs.^2); + %Z0(%ka+1) = max(1e-5, -1.1*%mineigZ); + %Z0(1:%ka) = %Z0(1:%ka) + %Z0(%ka+1)*%Id; + + if (%M < %Id'*[%I0v,%I]*[1;%xi] + 1e-5), + error(msprintf(_("%s: M must be strictly greater than trace of F(x0)."),"lmisolver")); + end; + + + // add scalar block Tr F(x) <= M + + %blck_szs = [%blck_szs,1]; + + temp=full(pack([%I0v, %I; + %M-%Id'*%I0v, -%Id'*%I],%blck_szs)); + + [%xopt,%z,%ul,%info]=semidef(%xi,pack(%Z0,%blck_szs),temp,%blck_szs,full(%O),[%nu,%ato,%rto,0.0,%mite]); + clear temp + if %info(2) == %mite then + warning(msprintf(_("%s: max number of iterations exceeded, solution may not be optimal"),"lmisolver")); + end; + if sum(abs([%I0v,%I]*[1; %xopt])) > 0.9*%M then + lmisolvertrace(msprintf(_("%s: may be unbounded below"),"lmisolver")); + end; + if %xopt<>[]&~(%info(2) == %mite) then + lmisolvertrace(msprintf(_("%s: optimal solution found"),"lmisolver")); + else %xopt=%xi; + end + else + %xopt=%xi; + end + + %Xlist=vec2list((%x0+%kerE*%xopt),%dim_X,%ind_X); + %OPT=%O0+%O*%xopt; +endfunction + + +function [bigVector]=splist2vec(li) + //li=list(X1,...Xk) is a list of matrices + //bigVector: sparse vector [X1(:);...;Xk(:)] (stacking of matrices in li) + bigVector=[]; + li=aplat(li) + for mati=li + sm=size(mati); + bigVector=[bigVector;sparse(matrix(mati,prod(sm),1))]; + end + +endfunction + +function [A,b]=spaff2Ab(lme,dimX,D,ind) + //Y,X,D are lists of matrices. + //Y=lme(X,D)= affine fct of Xi's; + //[A,b]=matrix representation of lme in canonical basis. + [LHS,RHS]=argn(0) + select RHS + case 3 then + nvars=0; + for k=dimX' + nvars=nvars+prod(k); + end + x0=zeros(nvars,1); + b=list2vec(lme(vec2list(x0,dimX),D)); + A=[]; + for k=1:nvars + xi=x0;xi(k)=1; + A=[A,sparse(list2vec(lme(vec2list(xi,dimX),D))-b)]; + end + + case 4 then + nvars=0; + for k=dimX' + nvars=nvars+prod(k); + end + x0=zeros(nvars,1); + b=list2vec(lme(vec2list(x0,dimX,ind),D)); + A=[]; + for k=1:nvars + xi=x0;xi(k)=1; + A=[A,sparse(list2vec(lme(vec2list(xi,dimX,ind),D))-b)]; + end + end +endfunction + +function lmisolvertrace(txt) + mprintf("%s\n",txt) +endfunction + + +function [ok,%sm,%nor]=lmicheck(E,I) + + //checking positiveness of the LMI + %sm=100; + for %w=I + if %w~=[] then + s=min(real(spec(%w))) + %sm=min(%sm,s) + end + end + ok=%sm>=-%tol + + //Checking norm of the LME + %nor=0 + for %w=E + if %w~=[] then + n=norm(%w,1) + %nor=max(%nor,n) + end + end + + ok=%sm>=-%tol & %nor<%tol +endfunction +function e=flat_block_matrix_eigs(V,blck_szs) + // Computes the eigenvalues of each block of a flatten block matrix + ka=0; e=[]; + for n=matrix(blck_szs,1,-1) + e=[e;spec(matrix(V(ka+[1:n^2]),n,n))] + ka=ka+n^2; + end; +endfunction + +function Id = build_flat_identity(blck_szs) + //build a flat representation of a block identity matrix + ka=0; + for n=matrix(blck_szs,1,-1) + Id(ka+[1:n^2]) = matrix(eye(n,n),-1,1); // identity + ka=ka+n^2; + end; +endfunction diff --git a/modules/optimization/macros/lmitool.bin b/modules/optimization/macros/lmitool.bin Binary files differnew file mode 100755 index 000000000..5ebafffe6 --- /dev/null +++ b/modules/optimization/macros/lmitool.bin diff --git a/modules/optimization/macros/lmitool.sci b/modules/optimization/macros/lmitool.sci new file mode 100755 index 000000000..09dfea957 --- /dev/null +++ b/modules/optimization/macros/lmitool.sci @@ -0,0 +1,206 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [txtdo]=lmitool(PROBNAME,XNAME,DNAME) + [LHS,RHS]=argn(0); + txtdo=[] + + if or(RHS == [0 2]) then + error(msprintf(_("%s: Wrong number of input arguments: %d or %d expected.\n"),"lmitool",1,3)) + end + + if RHS == 1 then + messagebox([gettext("Welcome to LMITOOL");" ";" "; + gettext("LMITOOL is a Scilab package for LMI optimization"); + " "; + " "; + gettext("It can solve the following problem"); + " "; + gettext(" minimize f(X1,...,XM) "); + gettext("subject to the LME constraints: "); + gettext(" Gi(X1,...,XM)=0, i=1,2,...,p,"); + gettext("and the LMI constraints: "); + gettext(" Hj(X1,...,XM)>=0, j=1,2,...,q."); + " "; + gettext("where"); + gettext("X1,...,XM are unknown real matrices, referred to as the unknown matrices,"); + gettext("f is the objective function, a linear scalar function of the entries of the X''s,"); + gettext("Gi''s are affine matrix functions of the entries of the X''s,"); + gettext("Hj''s are affine symmetric matrix functions of the entries of the X''s."); + " "; + gettext("These functions are parameterized by the entries of known data matrices D1,...,DN."); + " "; + gettext("For a detailed description and examples consult: "); + gettext(" ''LMITOOL: a Package for LMI Optimization in Scilab, User''s Guide'' "); + " "; + gettext("LMITOOL uses Semidefinite Programming package SP developed by L. Vandenberghe and S. Boyd.")],"modal","scilab"); + + tt=read(PROBNAME,-1,1,"(a)"); + tt=stripblanks(tt); + mat=str2vec(tt); + [q1,p1]=find(mat'=="["); + [q2,p2]=find(mat'=="]"); + XNAME1=mat(p1(1),q1(1)+1:q2(1)-1); + XNAME1=strcat(XNAME1); + [q1,p1]=find(mat'=="("); + [q2,p2]=find(mat'==")"); + DNAME1=mat(p1(1),q1(1)+1:q2(1)-1); + DNAME1=strcat(DNAME1); + [q2,p2]=find(mat'=="="); + PROBNAME1=mat(p2(1),q2(1)+1:q1(1)-1); + PROBNAME1=strcat(PROBNAME1); + + labels=[gettext("LMI problem name: ");gettext("Names of unknown matrices: "); ... + gettext("Names of data matrices: ")]; + [ok,PROBNAME,XNAME,DNAME]=getvalue([gettext("Problem definition"); + gettext("LMITOOL will generate a skeleton of the functions needed"); + gettext(" (see User''s Guide for details). For that, you need to specify:"); + gettext("1- Name of your problem which will be given to the solver function,"); + gettext("2- Names of unknown matrices or list of unknown matrices,"); + gettext("3- Names of data matrices or list of data matrices.")], labels', ... + list("str",1,"str",1,"str",1), ... + [PROBNAME1, XNAME1, DNAME1]); + if ok==%f then + txtdo=gettext("Try again"); + return; + end + end + + PROBNAME=stripblanks(PROBNAME); + XNAME=stripblanks(XNAME); + DNAME=stripblanks(DNAME); + + pathname=pwd(); + + fname = pathname+filesep()+PROBNAME+".sci"; + + txt0="function ["+XNAME+"]="+PROBNAME+"("+DNAME+")" + txt0=[txt0;"/"+"/ Generated by lmitool on ";" "]; + + txt0=[txt0; + " Mbound = 1e3;"; + " abstol = 1e-10;"; + " nu = 10;"; + " maxiters = 100;"; + " reltol = 1e-10;"; + " options=[Mbound,abstol,nu,maxiters,reltol];" + " "] + + nv=length(XNAME); + index_commas=[]; + for k=1:nv + if part(XNAME,k)=="," then index_commas=[index_commas,k],end + end + vnum = length(index_commas)+1; + index_commas = [0 index_commas length(XNAME)+1]; + + txt1=[];txt2=[]; + for i = 1:vnum, + vname = part(XNAME,index_commas(i)+1:index_commas(i+1)-1); + if RHS<>1 then + txt1 = [txt1; + vname+"_init=..."] + end + txt2=[txt2,vname+"_init"]; + end + + txts1=["function [LME,LMI,OBJ]="+PROBNAME+"_eval(XLIST)"; + "["+XNAME+"]=XLIST(:)"] + if RHS ~= 1 then + txts2=["LME=...";"LMI=...";"OBJ=..."] + else + [p,q]=size(mat); + ind=[] + for i=1:p + if mat(i,2:7)==["/","/","/","/","/","/"] then + ind=[ind i]; + end + end + if size(ind,"*")<>4 then + error(gettext("File not generated by lmitool or badly modified.")); + end + txt1=[]; + for i=ind(1)+1:ind(2)-1 + txt1=[txt1;strcat(mat(i,:))]; + end + txts2=[]; + for i=ind(4)+1:p + txts2=[txts2;strcat(mat(i,:))]; + end + end + + sep11="///////////DEFINE INITIAL GUESS AND PRELIMINARY CALCULATIONS BELOW" + sep12="/////////// " + sep13="/////////////////DEFINE LME, LMI and OBJ BELOW" + sep2="/////////////////EVALUATION FUNCTION////////////////////////////" + + txt2=[ + "XLIST0=list("+strcat(txt2,",")+")"; + "XLIST=lmisolver(XLIST0,"+PROBNAME+"_eval,options)"; + "["+XNAME+"]=XLIST(:)"]; + + txt4=[txt0;sep11;txt1;sep12;" ";txt2;" ";" ";" ";... + sep2;" ";txts1;" ";sep13;txts2]; + + if RHS==0|RHS==1 then + [txt4]=x_dialog([gettext("Function definitions: "); + gettext("Here is a skeleton of the functions you should edit."); + gettext("You can edit in this window or click on ''ok''."); + gettext("Save and edit the skeleton later through your favorite editor.")],[txt4]); + end + if txt4==[] then txtdo="Try again";return;end + txt=[txt4]; + n=1; + if RHS<>3 then + + fname=x_dialog([gettext("Name of the file where to save the solver function"); + gettext("and the evaluation function"); + gettext("(Will overwrite if a file with the same name already exists).")],[fname+" "]) + fname=stripblanks(fname); + else + messagebox(gettext("functions saved in ")+fname',"modal","info"); + end + if fname<>[] then + deletefile(fname) + write(fname,txt) + else + return + end + + // Tell the user what to do: + if RHS==0|RHS==1 then + txtdo = [" To solve your problem, you need to "; + "1- load your functions using the command:"; + " exec(''"+fname'+"'')"; + "2- Define "+DNAME+" and call function "+PROBNAME+" as follows:"; + " "+"["+XNAME+"]="+PROBNAME+"("+DNAME+")"; + " Good luck! "; + "To check the result, use [LME,LMI,OBJ]="+PROBNAME+"_eval(list("+XNAME+"))"] + + messagebox(txtdo,"modal","info");return + end + if RHS==3 then + txtdo = [gettext(" To solve your problem, you need to "); + gettext("1- edit file ")+fname + gettext("2- load (and compile) your functions:"); + " exec(''"+fname'+"'')"; + gettext("3- Define ")+DNAME+gettext(" and call ")+PROBNAME+gettext(" function:"); + " "+"["+XNAME+"]="+PROBNAME+"("+DNAME+")"; + gettext("To check the result, use [LME,LMI,OBJ]=")+PROBNAME+"_eval(list("+XNAME+"))"] + end + +endfunction +function [vec]=str2vec(str) + w=length(str); + [p,q]=size(w);ma=max(w); + vec=[]; + for i=1:ma + vec=[vec part(str,i)] + end +endfunction diff --git a/modules/optimization/macros/names b/modules/optimization/macros/names new file mode 100755 index 000000000..a01147900 --- /dev/null +++ b/modules/optimization/macros/names @@ -0,0 +1,20 @@ +%mps_p +%mps_string +NDcost +aplat +bvodeS +datafit +derivative +karmarkar +leastsq +list2vec +lmisolver +lmitool +numderivative +numdiff +pack +pencost +qpsolve +recons +unpack +vec2list diff --git a/modules/optimization/macros/neldermead/%TNELDER_p.bin b/modules/optimization/macros/neldermead/%TNELDER_p.bin Binary files differnew file mode 100755 index 000000000..8202074ff --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNELDER_p.bin diff --git a/modules/optimization/macros/neldermead/%TNELDER_p.sci b/modules/optimization/macros/neldermead/%TNELDER_p.sci new file mode 100755 index 000000000..a17001fe2 --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNELDER_p.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TNELDER_p -- +// Prints the string containing the nelder mead component. +// +function %TNELDER_p ( this ) + str = string ( this ) + srows = size(str,"r") + for i = 1 : srows + mprintf("%s\n",str(i)) + end +endfunction + + diff --git a/modules/optimization/macros/neldermead/%TNELDER_string.bin b/modules/optimization/macros/neldermead/%TNELDER_string.bin Binary files differnew file mode 100755 index 000000000..c81b4b2f6 --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNELDER_string.bin diff --git a/modules/optimization/macros/neldermead/%TNELDER_string.sci b/modules/optimization/macros/neldermead/%TNELDER_string.sci new file mode 100755 index 000000000..f80856a6d --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNELDER_string.sci @@ -0,0 +1,167 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TNELDER_string -- +// Returns the string containing the Nelder-Mead component. +// +function str = %TNELDER_string ( this ) + str = [] + k = 1 + str(k) = sprintf("Nelder-Mead Object:\n") + k = k + 1 + str(k) = sprintf("======================") + k = k + 1 + str(k) = "" + k = k + 1 + str(k) = sprintf("Simplex0 Method : %s\n", string(this.simplex0method)); + k = k + 1 + str(k) = sprintf("Simplex0 Length : %s\n", string(this.simplex0length)); + k = k + 1 + str(k) = sprintf("Simplex0, Pfeffer, Delta Usual : %s\n", string(this.simplex0deltausual)); + k = k + 1 + str(k) = sprintf("Simplex0, Pfeffer, Delta Zero : %s\n", string(this.simplex0deltazero)); + k = k + 1 + str(k) = sprintf("Simplex0, Given, Coords :\n"); + if ( this.coords0 == [] ) then + k = k + 1 + str(k) = sprintf("[]\n"); + else + nbve = size(this.coords0,"r") + for i = 1 : nbve + k = k + 1 + str(k) = sprintf("%s\n" , _tostring(this.coords0(i,:))); + end + end + ///////////////////////////////////////////////////// + // Termination + k = k + 1 + str(k) = sprintf("\n"); + k = k + 1 + str(k) = sprintf("Termination parameters\n"); + k = k + 1 + str(k) = sprintf("Termination on simplex size : %s\n", string(this.tolsimplexizemethod)); + k = k + 1 + str(k) = sprintf("Termination on simplex size, Absolute Tolerance : %s\n", string(this.tolsimplexizeabsolute)); + k = k + 1 + str(k) = sprintf("Termination on simplex size, Relative Tolerance : %s\n", string(this.tolsimplexizerelative)); + k = k + 1 + str(k) = sprintf("Termination on simplex size, Initial Simplex Size : %s\n", string(this.simplexsize0)); + k = k + 1 + str(k) = sprintf("Termination on simplex size + Delta of function value : %s\n", string(this.tolssizedeltafvmethod)); + k = k + 1 + str(k) = sprintf("Termination on simplex size + Delta of function value, Absolute Tolerance on Delta F : %s\n", string(this.toldeltafv)); + k = k + 1 + str(k) = sprintf("Termination on Kelley''s Stagnation : %s\n", string(this.kelleystagnationflag)); + k = k + 1 + str(k) = sprintf("Termination on Kelley''s Stagnation, Normalization : %s\n", string(this.kelleynormalizationflag)); + k = k + 1 + str(k) = sprintf("Termination on Kelley''s Stagnation, Alpha0 : %s\n", string(this.kelleystagnationalpha0)); + k = k + 1 + str(k) = sprintf("Termination on Kelley''s Stagnation, Alpha : %s\n", string(this.kelleyalpha)); + k = k + 1 + str(k) = sprintf("Termination by Box : %s\n", string(this.boxtermination)); + k = k + 1 + str(k) = sprintf("Termination by Box, Absolute Tolerance on Function: %s\n", string(this.boxtolf)); + k = k + 1 + str(k) = sprintf("Termination by Box, Maximum Number of Consecutive Match : %s\n", string(this.boxnbmatch)); + k = k + 1 + str(k) = sprintf("Termination by Box, Current Number of Consecutive Match : %s\n", string(this.boxkount)); + k = k + 1 + str(k) = sprintf("Termination on Variance : %s\n", string(this.tolvarianceflag)); + k = k + 1 + str(k) = sprintf("Termination on Variance, Absolute Tolerance : %s\n", string(this.tolabsolutevariance)); + k = k + 1 + str(k) = sprintf("Termination on Variance, Relative Tolerance : %s\n", string(this.tolrelativevariance)); + k = k + 1 + str(k) = sprintf("Termination on Variance, Variance of Initial Simplex : %s\n", string(this.variancesimplex0)); + ///////////////////////////////////////////////////// + // Algorithm parameters + k = k + 1 + str(k) = sprintf("\n"); + k = k + 1 + str(k) = sprintf("Algorithms parameters\n"); + k = k + 1 + str(k) = sprintf("Method : %s\n", string(this.method)); + k = k + 1 + str(k) = sprintf("Reflection Factor (rho) : %s\n", string(this.rho)); + k = k + 1 + str(k) = sprintf("Expansion Factor (chi) : %s\n", string(this.chi)); + k = k + 1 + str(k) = sprintf("Contraction Factor (gamma) : %s\n", string(this.gamma)); + k = k + 1 + str(k) = sprintf("Shrinkage Factor (sigma) : %s\n", string(this.sigma)); + k = k + 1 + str(k) = sprintf("Kelley Stagnation : %s\n", string(this.kelleystagnationflag)); + k = k + 1 + str(k) = sprintf("Restart Epsilon : %s\n", string(this.restarteps)); + k = k + 1 + str(k) = sprintf("Restart Step : %s\n", _strvec(this.restartstep)); + k = k + 1 + str(k) = sprintf("Restart Maximum : %d\n", this.restartmax); + k = k + 1 + str(k) = sprintf("Restart Simplex Method : %s\n", string(this.restartsimplexmethod)); + k = k + 1 + str(k) = sprintf("Restart Flag : %s\n", string(this.restartflag)); + k = k + 1 + str(k) = sprintf("Restart Number : %s\n", string(this.restartnb)); + k = k + 1 + str(k) = sprintf("Restart Detection Method : %s\n", string(this.restartdetection)); + k = k + 1 + str(k) = sprintf("Startup Flag : %s\n", string(this.startupflag)); + k = k + 1 + str(k) = sprintf("Automatic Checking of Cost Function : %s\n", string(this.checkcostfunction)); + k = k + 1 + str(k) = sprintf("Box, Number of Points : %s\n", string(this.boxnbpoints)); + k = k + 1 + str(k) = sprintf("Box, Current Number of Points : %s\n", string(this.boxnbpointseff)); + k = k + 1 + str(k) = sprintf("Box, Scaling, Factor : %s\n", string(this.boxineqscaling)); + k = k + 1 + str(k) = sprintf("Box, Scaling, Method : %s\n", string(this.scalingsimplex0)); + k = k + 1 + str(k) = sprintf("Box, Scaling, Minimum : %s\n", string(this.guinalphamin)); + k = k + 1 + str(k) = sprintf("Box, Bounds Parameter: %s\n", string(this.boxboundsalpha)); + k = k + 1 + str(k) = sprintf("Box, Reflection Coefficient : %s\n", string(this.boxreflect)); + ///////////////////////////////////////////////////// + // Sub-objects + k = k + 1 + str(k) = ""; + k = k + 1 + str(k) = sprintf("optbase: <%s Object>\n", typeof(this.optbase)); + k = k + 1 + str(k) = sprintf("simplex0: <%s Object>\n", typeof(this.simplex0)); + k = k + 1 + str(k) = sprintf("simplexopt: <%s Object>\n", typeof(this.simplexopt)); +endfunction + +// +// _strvec -- +// Returns a string for the given vector. +// +function str = _strvec ( x ) + str = strcat(string(x)," ") +endfunction +function s = _tostring ( x ) + if ( x==[] ) then + s = "[]" + else + n = size ( x , "*" ) + if ( n == 1 ) then + s = string(x) + else + s = "["+strcat(string(x)," ")+"]" + end + end +endfunction + + + diff --git a/modules/optimization/macros/neldermead/%TNMPLOT_p.bin b/modules/optimization/macros/neldermead/%TNMPLOT_p.bin Binary files differnew file mode 100755 index 000000000..0b71feaa5 --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNMPLOT_p.bin diff --git a/modules/optimization/macros/neldermead/%TNMPLOT_p.sci b/modules/optimization/macros/neldermead/%TNMPLOT_p.sci new file mode 100755 index 000000000..4e2c006ae --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNMPLOT_p.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TNMPLOT_p -- +// Prints the string containing the nelder mead plot component. +// +function %TNMPLOT_p ( this ) + str = string ( this ) + srows = size(str,"r") + for i = 1 : srows + mprintf("%s\n",str(i)) + end +endfunction + + diff --git a/modules/optimization/macros/neldermead/%TNMPLOT_string.bin b/modules/optimization/macros/neldermead/%TNMPLOT_string.bin Binary files differnew file mode 100755 index 000000000..9f38f41b5 --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNMPLOT_string.bin diff --git a/modules/optimization/macros/neldermead/%TNMPLOT_string.sci b/modules/optimization/macros/neldermead/%TNMPLOT_string.sci new file mode 100755 index 000000000..8054bd094 --- /dev/null +++ b/modules/optimization/macros/neldermead/%TNMPLOT_string.sci @@ -0,0 +1,59 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TNMPLOT_string -- +// Returns the string containing the Nelder-Mead plot component. +// +function str = %TNMPLOT_string ( this ) + str = [] + k = 1 + str(k) = sprintf("Nelder-Mead Plot Object:\n") + k = k + 1 + str(k) = sprintf("======================") + k = k + 1 + str(k) = "" + k = k + 1 + str(k) = sprintf("Simplex data file : %s\n", this.simplexfn); + k = k + 1 + str(k) = sprintf("Fbar data file : %s\n", this.fbarfn); + k = k + 1 + str(k) = sprintf("Fopt data file : %s\n", this.foptfn); + k = k + 1 + str(k) = sprintf("Sigma data file : %s\n", this.sigmafn); + ///////////////////////////////////////////////////// + // Nelder Mead Object + k = k + 1 + str(k) = ""; + k = k + 1 + str(k) = sprintf("nmbase: <%s Object>\n", typeof(this.nmbase)); +endfunction + +// +// _strvec -- +// Returns a string for the given vector. +// +function str = _strvec ( x ) + str = strcat(string(x)," ") +endfunction +function s = _tostring ( x ) + if ( x==[] ) then + s = "[]" + else + n = size ( x , "*" ) + if ( n == 1 ) then + s = string(x) + else + s = "["+strcat(string(x)," ")+"]" + end + end +endfunction + + + diff --git a/modules/optimization/macros/neldermead/fminsearch.bin b/modules/optimization/macros/neldermead/fminsearch.bin Binary files differnew file mode 100755 index 000000000..9b7522a90 --- /dev/null +++ b/modules/optimization/macros/neldermead/fminsearch.bin diff --git a/modules/optimization/macros/neldermead/fminsearch.sci b/modules/optimization/macros/neldermead/fminsearch.sci new file mode 100755 index 000000000..2b74e8837 --- /dev/null +++ b/modules/optimization/macros/neldermead/fminsearch.sci @@ -0,0 +1,329 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// fminsearch -- +// Emulate the fminsearch command of Matlab. +// Search the minimum with Nelder-Mead algorithm. +// [x,fval,exitflag,output] = fminsearch(fun,x0,options) +// Arguments, input +// fun : the function to minimize +// x0 : a row vector with dimension n where n is the number of parameters +// to optimize. +// Initial guess for optimization algorithm. +// options : an optional struct, as provided by optimset +// +function [x,fval,exitflag,output] = fminsearch ( varargin ) + [lhs,rhs]=argn(); + if rhs<>2 & rhs<>3 then + errmsg = msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"), "fminsearch", 2,3); + error(errmsg) + end + fun = varargin(1); + x0 = varargin(2); + // Get x0 and change it into a column vector + x0t = size(x0,"*"); + x0 = matrix(x0,x0t,1); + defaultoptions = optimset ("fminsearch"); + msg=""; + if rhs==2 then + // No options on the command line + // Set default values + options = defaultoptions; + elseif rhs==3 then + // One options struc on the command line : use it ! + options = varargin(3); + end + // Compute options from the options struct + numberofvariables = size(x0,"*"); + MaxFunEvals = optimget ( options , "MaxFunEvals" , defaultoptions.MaxFunEvals ); + MaxIter = optimget ( options , "MaxIter" , defaultoptions.MaxIter ); + TolFun = optimget ( options , "TolFun" , defaultoptions.TolFun ); + TolX = optimget ( options , "TolX" , defaultoptions.TolX ); + Display = optimget ( options , "Display" , defaultoptions.Display ); + OutputFcn = optimget ( options , "OutputFcn" , defaultoptions.OutputFcn ); + PlotFcns = optimget ( options , "PlotFcns" , defaultoptions.PlotFcns ); + // If the MaxIter option is a string, we make the assumption that it is the default 200 value. + // If not, this is the actual value. + if ( type ( MaxIter ) == 10 ) then + if ( MaxIter == "200*numberofvariables" ) then + MaxIter = 200 * numberofvariables; + else + errmsg = msprintf(gettext("%s: Unexpected maximum number of iterations %s."), "fminsearch", MaxIter ); + error(errmsg) + end + end + // If the MaxFunEvals option is a string, this is the default 200 value + // If not, this is the actual value. + if ( type ( MaxFunEvals ) == 10 ) then + if ( MaxFunEvals == "200*numberofvariables" ) then + MaxFunEvals = 200 * numberofvariables; + else + errmsg = msprintf(gettext("%s: Unexpected maximum number of function evaluations %s."), "fminsearch", MaxFunEvals ); + error(errmsg) + end + end + if ( Display == "iter" ) then + mprintf ( "%10s %10s %10s %17s\n" , "Iteration", "Func-count" , "min f(x)" , "Procedure" ); + end + // + // Check input arguments + assert_typecallable ( fun , "costf" , 1) + assert_typereal ( x0 , "x0" , 2 ); + // + // Prepare the data structure to pass to the output function + fmsdata = tlist(["T_FMINSEARCH" + "Display" + "OutputFcn" + "PlotFcns" + ]); + fmsdata.Display = Display + fmsdata.OutputFcn = OutputFcn + fmsdata.PlotFcns = PlotFcns + // Prepare the data structure to pass to the cost function + fmsfundata = tlist(["T_FMINSEARCH" + "Fun" + ]); + fmsfundata.Fun = fun + // Perform Optimization + nm = neldermead_new (); + nm = neldermead_configure(nm,"-x0",x0); + nm = neldermead_configure(nm,"-numberofvariables",numberofvariables); + nm = neldermead_configure(nm,"-simplex0method","pfeffer"); + nm = neldermead_configure(nm,"-simplex0deltausual",0.05); + nm = neldermead_configure(nm,"-simplex0deltazero",0.0075); + nm = neldermead_configure(nm,"-method","variable"); + nm = neldermead_configure(nm,"-function",list(fminsearch_function,fmsfundata)); + nm = neldermead_configure(nm,"-maxiter",MaxIter); + nm = neldermead_configure(nm,"-maxfunevals",MaxFunEvals); + nm = neldermead_configure(nm,"-tolxmethod",%f); + nm = neldermead_configure(nm,"-tolfunmethod",%f); + nm = neldermead_configure(nm,"-tolssizedeltafvmethod",%t); + nm = neldermead_configure(nm,"-tolsimplexizemethod",%f); + nm = neldermead_configure(nm,"-toldeltafv",TolFun); + nm = neldermead_configure(nm,"-tolsimplexizeabsolute",TolX); + nm = neldermead_configure(nm,"-checkcostfunction",%f); + nm = neldermead_configure(nm,"-outputcommand",list(fminsearch_outputfun,fmsdata)); + //nm = neldermead_configure(nm,"-verbose",1); + //nm = neldermead_configure(nm,"-verbosetermination",1); + nm = neldermead_search(nm, "off"); + x = neldermead_get(nm,"-xopt").'; + fval = neldermead_get(nm,"-fopt"); + status = neldermead_get(nm,"-status"); + select status + case "maxiter" then + if ( ( Display == "notify" ) | ( Display == "iter" ) | ( Display == "final" ) ) then + msg = "%s: Exiting: Maximum number of iterations has been exceeded\n" + ... + " - increase MaxIter option.\n" + ... + " Current function value: %s\n" + mprintf(gettext(msg) , "fminsearch" , string(fval) ) + end + exitflag = 0; + case "maxfuneval" then + if ( ( Display == "notify" ) | ( Display == "iter" ) | ( Display == "final" ) ) then + msg = "%s: Exiting: Maximum number of function evaluations has been exceeded\n" + ... + " - increase MaxFunEvals option.\n" + ... + " Current function value: %s\n" + mprintf(gettext(msg) , "fminsearch" , string(fval) ) + end + exitflag = 0; + case "tolsizedeltafv" then + exitflag = 1; + msg = sprintf("%s\n%s %s\n%s %s", "Optimization terminated:",... + " the current x satisfies the termination criteria using OPTIONS.TolX of",... + string(TolX),... + " and F(X) satisfies the convergence criteria using OPTIONS.TolFun of",... + string(TolFun)); + case "userstop" then + msg = sprintf("%s\n%s\n%s", "Optimization terminated:",... + " ",... + " User Stop"); + exitflag = -1; + else + errmsg = msprintf(gettext("%s: Unknown status %s"), "fminsearch", status) + error(errmsg) + end + output = struct(... + "algorithm" ,[],... + "funcCount" ,[],... + "iterations" ,[],... + "message" , []); + output.algorithm = "Nelder-Mead simplex direct search"; + output.funcCount = neldermead_get(nm,"-funevals"); + output.iterations = neldermead_get(nm,"-iterations"); + output.message = msg; + if ( ( Display == "final" ) | ( Display == "iter" ) ) then + if ( ( exitflag == 1 ) ) then + mprintf( "%s\n" , output.message(1) ); + mprintf( "%s\n" , output.message(2) ); + mprintf( "%s\n" , output.message(3) ); + end + end + nm = neldermead_destroy(nm); +endfunction +// +// The output function called back by fminsearch +// +// Arguments +// state : the current state of the algorithm +// "init", "iter", "done" +// data : the data at the current state +// This is a tlist with the following entries: +// * x : the optimal vector of parameters +// * fval : the minimum function value +// * simplex : the simplex, as a simplex object +// * iteration : the number of iterations performed +// * funccount : the number of function evaluations +// * step : the type of step in the previous iteration +// fmsdata : this is a tlist which contains specific data of the +// fminsearch algorithm +// * Display : what to display +// * OutputFcn : the array of output functions +// +function stop = fminsearch_outputfun ( state , data , fmsdata ) + // + // Compute procedure + // + select data.step + case "init" then + if ( data.iteration == 0 ) then + procedure = ""; + else + procedure = "initial simplex"; + end + case "done" then + procedure = "" + case "reflection" then + procedure = "reflect" + case "expansion" then + procedure = "expand" + case "insidecontraction" then + procedure = "contract inside" + case "outsidecontraction" then + procedure = "contract outside" + case "shrink" then + procedure = "shrink" + else + errmsg = msprintf(gettext("%s: Unknown step %s"), "fminsearch", data.step) + error(errmsg) + end + // + // Display a message + // + if ( fmsdata.Display == "iter" ) then + if ( data.step <> "done" ) then + mprintf ( "%6s %5s %12s %-20s\n", ... + string(data.iteration) , string(data.funccount) , string(data.fval) , procedure ) + else + mprintf ( "\n" ) + end + end + // + // Process output functions + // + stop = %f + optimValues = struct(... + "funccount" ,data.funccount , ... + "fval" ,data.fval , ... + "iteration" , data.iteration , ... + "procedure" , procedure ... + ); + if ( fmsdata.OutputFcn <> [] ) then + if ( type ( fmsdata.OutputFcn ) == 13 ) then + // The output function is a macro + stop = fmsdata.OutputFcn ( data.x , optimValues , state ); + // + // Backward-compatibility: define the stop variable + // + if ( exists("stop")==0 ) then + fms_warnheaderobsolete ( "outputfun(x,optimValues , state )" , "stop=outputfun(x,optimValues , state )", "5.4.1" ) + stop = %f + end + elseif ( type ( fmsdata.OutputFcn ) == 15 ) then + // The output function is a list of macros + for i = 1:length(fmsdata.OutputFcn) + stop = fmsdata.OutputFcn(i) ( data.x , optimValues , state ); + end + // + // Backward-compatibility: define the stop variable + // + if ( exists("stop")==0 ) then + fms_warnheaderobsolete ( "outputfun(x,optimValues , state )" , "stop=outputfun(x,optimValues , state )", "5.4.1" ) + stop = %f + end + else + // The user did something wrong... + errmsg = msprintf(gettext("%s: The value of the ''OutputFcn'' option is neither a function nor a list."), "fminsearch") + error(errmsg) + end + end + // Process plot functions + if ( fmsdata.PlotFcns <> [] ) then + if ( type ( fmsdata.PlotFcns ) == 13 ) then + // The output function is a macro + fmsdata.PlotFcns ( data.x , optimValues , state ); + elseif ( type ( fmsdata.PlotFcns ) == 15 ) then + // The output function is a list of macros + for i = 1:length(fmsdata.PlotFcns) + fmsdata.PlotFcns(i) ( data.x , optimValues , state ); + end + else + // The user did something wrong... + errmsg = msprintf(gettext("%s: The value of the ''PlotFcns'' option is neither a function nor a list."), "fminsearch") + error(errmsg) + end + end +endfunction +// +// fminsearch_function -- +// Calls the cost function and make it match +// neldermead requirements. +// +function [ f , index , fmsfundata ] = fminsearch_function ( x , index , fmsfundata ) + funtype = typeof(fmsfundata.Fun) + if ( funtype == "function" ) then + __fminsearch_f__ = fmsfundata.Fun + __fminsearch_args__ = list() + else + __fminsearch_f__ = fmsfundata.Fun(1) + __fminsearch_args__ = list(fmsfundata.Fun(2:$)) + end + f = __fminsearch_f__ ( x , __fminsearch_args__(:)) +endfunction + +function fms_warnheaderobsolete ( oldheader , newheader , removedVersion ) + warnMessage = msprintf(_("Calling sequence %s is obsolete."),oldheader) + warnMessage = [warnMessage, msprintf(_("Please use %s instead."),newheader)] + warnMessage = [warnMessage, msprintf(_("This feature will be permanently removed in Scilab %s"), removedVersion)] + warning(warnMessage); +endfunction + + +function assert_typecallable ( var , varname , ivar ) + // Check that var is a function or a list + if ( and ( type ( var ) <> [11 13 15] ) ) then + errmsg = msprintf(gettext("%s: Expected function or list for variable %s at input #%d, but got %s instead."),"assert_typecallable", varname , ivar , typeof(var) ); + error(errmsg); + end + if ( type ( var ) == 15 ) then + // Check that var(1) is a function + if ( and ( type ( var(1) ) <> [11 13] ) ) then + errmsg = msprintf(gettext("%s: Expected function for variable %s(1) at input #%d, but got %s instead."),"assert_typecallable", varname , ivar , typeof(var) ); + error(errmsg); + end + end +endfunction +// Generates an error if the given variable is not of type real +function assert_typereal ( var , varname , ivar ) + if ( type ( var ) <> 1 ) then + errmsg = msprintf(gettext("%s: Expected real variable for variable %s at input #%d, but got %s instead."),"assert_typereal", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction diff --git a/modules/optimization/macros/neldermead/lib b/modules/optimization/macros/neldermead/lib Binary files differnew file mode 100755 index 000000000..0cab3f3a4 --- /dev/null +++ b/modules/optimization/macros/neldermead/lib diff --git a/modules/optimization/macros/neldermead/names b/modules/optimization/macros/neldermead/names new file mode 100755 index 000000000..dbaa66016 --- /dev/null +++ b/modules/optimization/macros/neldermead/names @@ -0,0 +1,35 @@ +%TNELDER_p +%TNELDER_string +%TNMPLOT_p +%TNMPLOT_string +fminsearch +neldermead_cget +neldermead_configure +neldermead_costf +neldermead_defaultoutput +neldermead_destroy +neldermead_function +neldermead_get +neldermead_log +neldermead_new +neldermead_restart +neldermead_search +neldermead_updatesimp +nmplot_cget +nmplot_configure +nmplot_contour +nmplot_destroy +nmplot_function +nmplot_get +nmplot_historyplot +nmplot_log +nmplot_new +nmplot_outputcmd +nmplot_restart +nmplot_search +nmplot_simplexhistory +optimget +optimplotfunccount +optimplotfval +optimplotx +optimset diff --git a/modules/optimization/macros/neldermead/neldermead_cget.bin b/modules/optimization/macros/neldermead/neldermead_cget.bin Binary files differnew file mode 100755 index 000000000..441788f69 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_cget.bin diff --git a/modules/optimization/macros/neldermead/neldermead_cget.sci b/modules/optimization/macros/neldermead/neldermead_cget.sci new file mode 100755 index 000000000..5e5b70823 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_cget.sci @@ -0,0 +1,111 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// neldermead_cget -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// +function value = neldermead_cget (this,key) + select key + case "-method" then + value = this.method; + case "-coords0" then + value = this.coords0; + case "-simplex0method" then + value = this.simplex0method; + case "-simplex0length" then + value = this.simplex0length; + case "-simplex0deltausual" then + value = this.simplex0deltausual; + case "-simplex0deltazero" then + value = this.simplex0deltazero; + case "-rho" then + value= this.rho; + case "-chi" then + value = this.chi; + case "-gamma" then + value = this.gamma; + case "-sigma" then + value = this.sigma; + case "-tolsimplexizemethod" then + value = this.tolsimplexizemethod; + case "-tolsimplexizeabsolute" then + value = this.tolsimplexizeabsolute; + case "-tolsimplexizerelative" then + value = this.tolsimplexizerelative; + case "-toldeltafv" then + value = this.toldeltafv; + case "-tolssizedeltafvmethod" then + value = this.tolssizedeltafvmethod; + case "-restartmax" then + value = this.restartmax; + case "-restarteps" then + value = this.restarteps; + case "-restartstep" then + value = this.restartstep; + case "-kelleystagnationflag" then + value = this.kelleystagnationflag; + case "-kelleynormalizationflag" then + value = this.kelleynormalizationflag; + case "-kelleystagnationalpha0" then + value = this.kelleystagnationalpha0; + case "-restartflag" then + value = this.restartflag; + case "-restartdetection" then + value = this.restartdetection; + case "-restartsimplexmethod" then + value = this.restartsimplexmethod; + case "-boxnbpoints" then + value = this.boxnbpoints; + case "-checkcostfunction" then + value = this.checkcostfunction; + case "-scalingsimplex0" then + value = this.scalingsimplex0; + case "-guinalphamin" then + value = this.guinalphamin; + case "-boxtermination" then + value = this.boxtermination + case "-boxtolf" then + value = this.boxtolf + case "-boxnbmatch" then + value = this.boxnbmatch + case "-boxreflect" then + value = this.boxreflect + case "-boxineqscaling" then + value = this.boxineqscaling; + case "-mymethod" then + value = this.mymethod + case "-greedy" then + value = this.greedy; + // + // Obsolete options. + // + case "-tolvarianceflag" then + value = this.tolvarianceflag + case "-tolabsolutevariance" then + value = this.tolabsolutevariance; + case "-tolrelativevariance" then + value = this.tolrelativevariance; + case "-greedy" then + value = this.greedy; + // + // Obsolete options. + // + case "-myterminate" then + value = this.myterminate + case "-myterminateflag" then + value = this.myterminateflag + else + // Delegate to the optimization object + value = optimbase_cget ( this.optbase , key ); + end +endfunction diff --git a/modules/optimization/macros/neldermead/neldermead_configure.bin b/modules/optimization/macros/neldermead/neldermead_configure.bin Binary files differnew file mode 100755 index 000000000..7bbea8459 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_configure.bin diff --git a/modules/optimization/macros/neldermead/neldermead_configure.sci b/modules/optimization/macros/neldermead/neldermead_configure.sci new file mode 100755 index 000000000..8a614b414 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_configure.sci @@ -0,0 +1,312 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_configure -- +// Configure neldermead and returns the modified object. +// +function this = neldermead_configure (this,key,value) + UN=number_properties("tiny") + [lhs,rhs]=argn(); + if ( rhs <> 3 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "neldermead_configure", 3); + error(errmsg) + end + select key + case "-method" then + nelmead_typestring ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkoption ( "neldermead_configure" , value , "value" , 3 , ["fixed" "variable" "box" "mine"]) + this.method = value + case "-coords0" then + nelmead_typereal ( value , "value" , 3 ); + this.coords0 = value; + case "-simplex0method" then + nelmead_typestring ( value , "value" , 3 ); + nelmead_checkoption ( "neldermead_configure" , value , "value" , 3 , ["given" "axes" "spendley" "pfeffer" "randbounds"]) + this.simplex0method = value + case "-simplex0length" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.simplex0length = value; + case "-simplex0deltausual" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.simplex0deltausual = value; + case "-simplex0deltazero" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.simplex0deltazero = value; + case "-rho" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.rho = value; + case "-chi" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.chi = value; + case "-gamma" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkrange ( "neldermead_configure" , var , "value" , 3 , UN , 1-%eps ) + this.gamma = value; + case "-sigma" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkrange ( "neldermead_configure" , var , "value" , 3 , UN , 1-%eps ) + this.sigma = value; + case "-tolsimplexizeabsolute" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.tolsimplexizeabsolute = value; + case "-tolsimplexizerelative" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.tolsimplexizerelative = value; + case "-tolsimplexizemethod" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.tolsimplexizemethod = value; + case "-toldeltafv" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.toldeltafv = value; + case "-tolssizedeltafvmethod" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.tolssizedeltafvmethod = value; + case "-restartmax" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + nelmead_checkflint ( "neldermead_configure" , value , "value" , 3 ) + this.restartmax = value; + case "-restarteps" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.restarteps = value; + case "-restartstep" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + n = optimbase_cget ( this.optbase , "-numberofvariables" ); + steprows = size ( value , "r" ); + stepcols = size ( value , "c" ); + if ( steprows * stepcols <> 1 ) then + if ( ( steprows <> n ) | ( stepcols <> 1 ) ) then + errmsg = msprintf(gettext("%s: The restartstep vector is expected to have %d x %d shape, but current shape is %d x %d"),"neldermead_configure",n,1,steprows,stepcols); + error(errmsg); + end + end + this.restartstep = value; + case "-kelleystagnationflag" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.kelleystagnationflag = value; + case "-kelleynormalizationflag" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.kelleynormalizationflag = value; + case "-kelleystagnationalpha0" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.kelleystagnationalpha0 = value; + case "-restartflag" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.restartflag = value; + case "-restartdetection" then + nelmead_typestring ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkoption ( "neldermead_configure" , value , "value" , 3 , ["oneill" "kelley"]) + this.restartdetection = value; + case "-restartsimplexmethod" then + nelmead_typestring ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkoption ( "neldermead_configure" , value , "value" , 3 , ["oriented" "axes" "spendley" "pfeffer" "randbounds"]) + this.restartsimplexmethod = value; + case "-checkcostfunction" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.checkcostfunction = value; + case "-boxnbpoints" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + nelmead_checkflint ( "neldermead_configure" , value , "value" , 3 ) + this.boxnbpoints = value; + case "-boxineqscaling" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkrange ( "neldermead_configure" , value , "value" , 3 , 0 , 1 ) + this.boxineqscaling = value; + case "-scalingsimplex0" then + nelmead_typestring ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkoption ( "neldermead_configure" , value , "value" , 3 , ["tox0" "tocenter"]) + this.scalingsimplex0 = value; + case "-guinalphamin" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + this.guinalphamin = value; + case "-boxboundsalpha" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.boxboundsalpha = value + case "-boxtermination" then + nelmead_typeboolean ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.boxtermination = value + case "-boxtolf" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.boxtolf = value + case "-boxnbmatch" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , UN ) + nelmead_checkflint ( "neldermead_configure" , value , "value" , 3 ) + this.boxnbmatch = value + case "-boxreflect" then + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 1+%eps ) + this.boxreflect = value + case "-mymethod" then + nelmead_typefunction ( value , "value" , 3 ); + this.mymethod = value + case "-greedy" then + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.greedy = value + // + // Obsolete options. + // + case "-myterminate" then + nelmead_warnoptobs ( "-myterminate" , "-outputcommand" , "5.4.1" ) + nelmead_typefunction ( value , "value" , 3 ); + this.myterminate = value + case "-myterminateflag" then + nelmead_warnoptobs ( "-myterminateflag" , "-outputcommand" , "5.4.1" ) + nelmead_typeboolean ( value , "value" , 3 ); + this.myterminateflag = value; + case "-tolvarianceflag" then + nelmead_warnoptobs ( "-tolvarianceflag" , "-outputcommand" , "5.4.1" ) + nelmead_typeboolean ( value , "value" , 3 ) + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + this.tolvarianceflag = value + case "-tolabsolutevariance" then + nelmead_warnoptobs ( "-tolabsolutevariance" , "-outputcommand" , "5.4.1" ) + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.tolabsolutevariance = value + case "-tolrelativevariance" then + nelmead_warnoptobs ( "-tolrelativevariance" , "-outputcommand" , "5.4.1" ) + nelmead_typereal ( value , "value" , 3 ); + nelmead_checkscalar ( "neldermead_configure" , value , "value" , 3 ) + nelmead_checkgreq ( "neldermead_configure" , value , "value" , 3 , 0 ) + this.tolrelativevariance = value + else + // Delegate to the optimization object + this.optbase = optimbase_configure ( this.optbase , key , value ); + end +endfunction +// Generates an error if the given variable is not of type real +function nelmead_typereal ( var , varname , ivar ) + if ( type ( var ) <> 1 ) then + errmsg = msprintf(gettext("%s: Expected real variable for variable %s at input #%d, but got %s instead."),"nelmead_typereal", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type string +function nelmead_typestring ( var , varname , ivar ) + if ( type ( var ) <> 10 ) then + errmsg = msprintf(gettext("%s: Expected string variable for variable %s at input #%d, but got %s instead."),"nelmead_typestring", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type function (macro) +function nelmead_typefunction ( var , varname , ivar ) + if ( type ( var ) <> 13 ) then + errmsg = msprintf(gettext("%s: Expected function but for variable %s at input #%d, got %s instead."),"nelmead_typefunction", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type boolean +function nelmead_typeboolean ( var , varname , ivar ) + if ( type ( var ) <> 4 ) then + errmsg = msprintf(gettext("%s: Expected boolean but for variable %s at input #%d, got %s instead."),"nelmead_typeboolean", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction + +function nelmead_warnoptobs ( oldoption , newoption , removedVersion ) + warnMessage = msprintf(_("Option %s is obsolete."),oldoption) + warnMessage = [warnMessage, msprintf(_("Please use %s instead."),newoption)] + warnMessage = [warnMessage, msprintf(_("This feature will be permanently removed in Scilab %s"), removedVersion)] + warning(warnMessage); +endfunction + +function nelmead_checkrange ( funname , var , varname , ivar , vmin , vmax ) + if ( ~and ( vmin <= var & var <= vmax ) ) then + k = find ( vmin > var | var > vmax ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected that all entries of input argument %s at input #%d are in the range [%s,%s], but entry #%d is equal to %s."),funname,varname,ivar,string(vmin),string(vmax),k,string(var(k))); + error(errmsg); + end +endfunction + +function nelmead_checkgreq ( funname , var , varname , ivar , thr ) + if ( or ( var < thr ) ) then + k = find ( var < thr ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected that all entries of input argument %s at input #%d are greater or equal than %s, but entry #%d is equal to %s."),funname,varname,ivar,string(thr),k,string(var(k))); + error(errmsg); + end +endfunction + +function nelmead_checkflint ( funname , var , varname , ivar ) + if ( or ( round(var)<>var ) ) then + k = find ( round(var)<>var ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected floating point integer for input argument %s at input #%d, but entry #%d is equal to %s."),funname,varname,ivar,k,string(var(k))); + error(errmsg); + end +endfunction + +function nelmead_checkscalar ( funname , var , varname , ivar ) + if ( or(size(var) <> [1 1]) ) then + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), funname, ivar , 1, 1 ); + error(errmsg) + end +endfunction + +function nelmead_checkoption ( funname , var , varname , ivar , expectedopt ) + if ( and ( var <> expectedopt ) ) then + stradd = """ or """ + strexp = """" + strcat(string(expectedopt),stradd) + """" + errmsg = msprintf(gettext("%s: Expected value [%s] for input argument %s at input #%d, but got ""%s"" instead."),funname,strexp,varname,ivar,string(var)); + error(errmsg); + end +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_costf.bin b/modules/optimization/macros/neldermead/neldermead_costf.bin Binary files differnew file mode 100755 index 000000000..358b56e46 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_costf.bin diff --git a/modules/optimization/macros/neldermead/neldermead_costf.sci b/modules/optimization/macros/neldermead/neldermead_costf.sci new file mode 100755 index 000000000..5c954241b --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_costf.sci @@ -0,0 +1,29 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_costf -- +// Call the cost function and return the value. +// Note +// This function is given to the simplex class as +// a callback. +// Input/Output arguments are swapped w.r.t. +// optimbase_function, so that it matches +// the requirements of simplex methods. +// +function [ f , this ] = neldermead_costf ( x , this ) + [ this.optbase , hascons ] = optimbase_hasnlcons ( this.optbase ); + if ( hascons ) then + [ this.optbase , f , c , index ] = optimbase_function ( this.optbase , x , 2 ); + else + [ this.optbase , f , index ] = optimbase_function ( this.optbase , x , 2 ); + end +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_defaultoutput.bin b/modules/optimization/macros/neldermead/neldermead_defaultoutput.bin Binary files differnew file mode 100755 index 000000000..e3a62252f --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_defaultoutput.bin diff --git a/modules/optimization/macros/neldermead/neldermead_defaultoutput.sci b/modules/optimization/macros/neldermead/neldermead_defaultoutput.sci new file mode 100755 index 000000000..46641109b --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_defaultoutput.sci @@ -0,0 +1,24 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// neldermead_defaultoutput -- +// The default output function. +// +function stop = neldermead_defaultoutput(state, data) + if ( state == "init" ) then + mprintf ( "Initialization\n"); + elseif ( state == "done" ) then + mprintf ( "End of Optimization\n"); + end + mprintf ( "Iter. #%s, Feval #%s, Fval = %s -- %s\n", .. + string(data.iteration), string(data.funccount), string(data.fval), data.step); + stop = %f +endfunction diff --git a/modules/optimization/macros/neldermead/neldermead_destroy.bin b/modules/optimization/macros/neldermead/neldermead_destroy.bin Binary files differnew file mode 100755 index 000000000..c6f77584d --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_destroy.bin diff --git a/modules/optimization/macros/neldermead/neldermead_destroy.sci b/modules/optimization/macros/neldermead/neldermead_destroy.sci new file mode 100755 index 000000000..17afea2b3 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_destroy.sci @@ -0,0 +1,19 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_destroy -- +// Destroy a Nelder-Mead object. +// +function this = neldermead_destroy (this) + this.optbase = optimbase_destroy ( this.optbase ); + this.simplex0 = optimsimplex_destroy ( this.simplex0 ); +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_function.bin b/modules/optimization/macros/neldermead/neldermead_function.bin Binary files differnew file mode 100755 index 000000000..6df5ebf15 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_function.bin diff --git a/modules/optimization/macros/neldermead/neldermead_function.sci b/modules/optimization/macros/neldermead/neldermead_function.sci new file mode 100755 index 000000000..eb1b70aad --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_function.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_function -- +// Call the cost function and return the value of f. +// This is a simple way to get the value of the cost function +// from outside. +// Arguments +// x : the point where the function is to be evaluated. +// index : a flag to pass to the cost function (default = 1) +// f : the cost function +// +function [ this , f ] = neldermead_function ( this , x ) + index = 2; + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + if ( hasnlcons ) then + [ this.optbase , f , c , index ] = optimbase_function ( this.optbase , x , index ); + else + [ this.optbase , f , index ] = optimbase_function ( this.optbase , x , index ); + end + // Ignores the value of index at output. +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_get.bin b/modules/optimization/macros/neldermead/neldermead_get.bin Binary files differnew file mode 100755 index 000000000..8917078f9 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_get.bin diff --git a/modules/optimization/macros/neldermead/neldermead_get.sci b/modules/optimization/macros/neldermead/neldermead_get.sci new file mode 100755 index 000000000..c89b0c954 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_get.sci @@ -0,0 +1,38 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// neldermead_get -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// +function value = neldermead_get ( this , key ) + select key + case "-historysimplex" then + storehistory = optimbase_cget ( this.optbase , "-storehistory" ); + if ( ~storehistory ) then + errmsg = msprintf(gettext("%s: History disabled ; turn on -storehistory option."), "neldermead_get") + error(errmsg) + else + value = this.historysimplex; + end + case "-simplexopt" then + value = this.simplexopt; + case "-simplex0" then + value = this.simplex0; + case "-restartnb" then + value = this.restartnb; + else + // Delegate to optbase + value = optimbase_get ( this.optbase , key ); + end +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_log.bin b/modules/optimization/macros/neldermead/neldermead_log.bin Binary files differnew file mode 100755 index 000000000..332aea4e3 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_log.bin diff --git a/modules/optimization/macros/neldermead/neldermead_log.sci b/modules/optimization/macros/neldermead/neldermead_log.sci new file mode 100755 index 000000000..a45e7c156 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_log.sci @@ -0,0 +1,19 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_log -- +// Prints the given message. +// +function this = neldermead_log ( this , msg ) + // Delegate to optimbase + this.optbase = optimbase_log ( this.optbase , msg ) +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_new.bin b/modules/optimization/macros/neldermead/neldermead_new.bin Binary files differnew file mode 100755 index 000000000..86f8de52d --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_new.bin diff --git a/modules/optimization/macros/neldermead/neldermead_new.sci b/modules/optimization/macros/neldermead/neldermead_new.sci new file mode 100755 index 000000000..53cfd3103 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_new.sci @@ -0,0 +1,201 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_new -- +// Creates a new Nelder-Mead object. +// +function newobj = neldermead_new () + newobj = tlist(["TNELDER" + "optbase" + "method" + "simplex0" + "simplex0method" + "simplex0length" + "rho" + "chi" + "gamma" + "sigma" + "tolfstdeviation" + "tolfstdeviationmethod" + "tolsimplexizeabsolute" + "tolsimplexizerelative" + "tolsimplexizemethod" + "simplexsize0" + "toldeltafv" + "tolssizedeltafvmethod" + "historysimplex" + "coords0" + "simplex0deltausual" + "simplex0deltazero" + "restartsimplexmethod" + "simplexopt" + "restartmax" + "restarteps" + "restartstep" + "kelleystagnationflag" + "kelleynormalizationflag" + "kelleystagnationalpha0" + "kelleyalpha" + "restartnb" + "restartflag" + "restartdetection" + "startupflag" + "boxnbpoints" + "boxnbpointseff" + "boxineqscaling" + "checkcostfunction" + "scalingsimplex0" + "guinalphamin" + "boxboundsalpha" + "boxtermination" + "boxtolf" + "boxnbmatch" + "boxkount" + "boxreflect" + "tolvarianceflag" + "tolabsolutevariance" + "tolrelativevariance" + "variancesimplex0" + "mymethod" + "greedy" + // + // Obsolete options + // + "myterminate" + "myterminateflag" + ]); + + newobj.optbase = optimbase_new(); + // Possible values "variable", "fixed". + newobj.method = "variable"; + newobj.simplex0 = optimsimplex_new ( ); + // Possible values : "axes", "spendley", "pfeffer" + newobj.simplex0method = "axes"; + newobj.simplex0length = 1.0; + // Reflection factor : rho + newobj.rho = 1.0; + // Expansion factor : chi + newobj.chi = 2.0; + // Contraction factor : gamma + newobj.gamma = .5; + // Shrinkage factor : sigma + newobj.sigma = .5; + // The tolerance for the standard deviation + newobj.tolfstdeviation = 0.0; + // Possible values : %t, %f + newobj.tolfstdeviationmethod = %f; + // The absolute tolerance for the simplex size + newobj.tolsimplexizeabsolute = 0.0; + // The relative tolerance for the simplex size + newobj.tolsimplexizerelative = %eps; + // Possible values : %t, %f + // Note : + // If the simplex method converges, the simplex size is near zero. + newobj.tolsimplexizemethod = %t; + // The tolerance for the function value delta + newobj.toldeltafv = %eps; + // Possible values : %t, %f + newobj.tolssizedeltafvmethod = %f; + // The value used in Pfeffer method initial simplex computation for non-zero parameters + newobj.simplex0deltausual = 0.05; + // The value used in Pfeffer method initial simplex computation for zero parameters + newobj.simplex0deltazero = 0.0075; + // The coordinates of the initial simplex, given by the user + newobj.coords0 = []; + // Initialize the simplex history + newobj.historysimplex = []; + // The Kelley stagnation detection in termination criteria : 0/1 + // (i.e. sufficient decrease of function value) + newobj.kelleystagnationflag = %f + // The Kelley stagnation detection parameter + newobj.kelleystagnationalpha0 = 1.e-4 + // The Kelley stagnation detection can be normalized or not. + // Note: + // * in the 1997 paper "Detection and Remediation of Stagnation in Nelder-Mead + // algorithm", Kelley uses the constant value of 1.e-4. + // * in the 1999 book "Iterative Methods for Optimization", Kelley uses normalization. + // Results are slightly changed, as indicated in the book/paper (the modification is + // not mentioned, but the iteration number when the restart is performed + // is modified). + newobj.kelleynormalizationflag = %t + // The current value of Kelley's alpha, after normalization, if required + newobj.kelleyalpha = 1.e-4; + // The optimum simplex, after one optimization process + newobj.simplexopt = []; + // The maximum number of restarts + newobj.restartmax = 3; + // The epsilon value for O'Neill restart detection + newobj.restarteps = %eps; + // The step length for O'Neill restart detection + newobj.restartstep = 1.0; + // Possible values : "oriented", "axes", "spendley", "pfeffer" + newobj.restartsimplexmethod = "oriented"; + // Possible values : %t, %f + newobj.restartflag = %f; + // Number of restarts performed + newobj.restartnb = 0; + // Type of restart detection method : "kelley", "oneill" + newobj.restartdetection = "oneill"; + // Set to %t when the startup has been performed + newobj.startupflag = %f; + // Initial size of the simplex, for the tolerance on the simplex size + newobj.simplexsize0 = 0.0 + // Number of points required in the simplex (for Box method) + newobj.boxnbpoints = "2n" + // Effective number of points required in the simplex (for Box method) + newobj.boxnbpointseff = 0 + // The scaling coefficient in nonlinear inequality constraints + // in Box method, in (0,1) range + newobj.boxineqscaling = 0.5 + // Set to %f to disable the checking of the connection of the cost function + newobj.checkcostfunction = %t; + // The scaling algorithm : "tox0", "tocentroid" + newobj.scalingsimplex0 = "tox0"; + // Minimum alpha for constraints scaling + newobj.guinalphamin = 1.e-5; + // Box's alpha coefficient for bounds constraints. + // The value used in Box's paper was 1.e-6 (delta in + // Richardson and Kuester's algorithm 454) + newobj.boxboundsalpha = 1.e-6 + // Set to 1 to enable Box termination criteria + newobj.boxtermination = %f + // The absolute tolerance on function value in Box termination criteria (beta in + // Richardson and Kuester's algorithm 454) + newobj.boxtolf = 1.e-5 + // The number of consecutive match in Box termination criteria (gamma in + // Richardson and Kuester's algorithm 454) + newobj.boxnbmatch = 5 + // Current number of consecutive match + newobj.boxkount = 0 + // Box reflection/expansion factor + newobj.boxreflect = 1.3 + // Set to %t to enable tolerance on variance + newobj.tolvarianceflag = %f; + // Absolute tolerance on variance + newobj.tolabsolutevariance = 0.0; + // Relative tolerance on variance + newobj.tolrelativevariance = %eps; + // The variance of the initial simplex + newobj.variancesimplex0 = 0.0; + // User-defined algorithm + newobj.mymethod = [] + // Set to %t to enable greedy Nelder-Mead + newobj.greedy = %f; + // + // Obsolete options + // + // User-defined terimination criteria + newobj.myterminate = [] + // Flag to enable the user-defined terimination criteria + newobj.myterminateflag = %f + +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_restart.bin b/modules/optimization/macros/neldermead/neldermead_restart.bin Binary files differnew file mode 100755 index 000000000..fd84e9d02 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_restart.bin diff --git a/modules/optimization/macros/neldermead/neldermead_restart.sci b/modules/optimization/macros/neldermead/neldermead_restart.sci new file mode 100755 index 000000000..713151d03 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_restart.sci @@ -0,0 +1,19 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_restart -- +// Update the simplex and restart the search. +// +function this = neldermead_restart ( this ) + this = neldermead_updatesimp ( this ); + this = neldermead_search (this); +endfunction + diff --git a/modules/optimization/macros/neldermead/neldermead_search.bin b/modules/optimization/macros/neldermead/neldermead_search.bin Binary files differnew file mode 100755 index 000000000..bf18c2f4a --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_search.bin diff --git a/modules/optimization/macros/neldermead/neldermead_search.sci b/modules/optimization/macros/neldermead/neldermead_search.sci new file mode 100755 index 000000000..8ff765941 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_search.sci @@ -0,0 +1,1512 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// References +// Sequential Application of Simplex Designs in Optimisation and Evolutionary Operation +// Spendley, W. and Hext, G. R. and Himsworth, F. R. +// 1962 +// +// Convergence Properties of the Nelder-Mead Simplex Method in Low Dimensions +// Jeffrey C. Lagarias and James A. Reeds nd Margaret H. Wright and Paul E. Wright +// SIAM Journal of Optimization, 1998, volume 9, pp. 112--147 +// +// A Simplex Method for Function Minimization +// Nelder, J. A. and Mead, R. +// 1965 +// +// Iterative Methods for Optimization +// C. T. Kelley, +// SIAM Frontiers in Applied Mathematics +// 1999 +// +// Detection and Remediation of Stagnation in the Nelder--Mead Algorithm Using a Sufficient Decrease Condition +// Kelley C. T. +// SIAM J. on Optimization}, +// 1999 +// + +// +// neldermead_search -- +// Search the minimum with Nelder-Mead algorithm. +// +function this = neldermead_search ( this , warn) + + rhs = argn(2); + + warn_mode = warning("query"); // Saving current warning mode to revert to it at the end + if rhs == 2 then + if warn == 0 | warn == "off" then + warning("off"); // Turn off warnings + elseif warn == 1 | warn == "on" then + warning("on"); // Turn on warnings + else + msg = _("%s: Wrong value for input argument #%d: ""%s"", ""%s"", %d or %d expected.\n"); + error(msprintf(msg, "neldermead_search", 2, "off", "on", 0, 1)) + end + end + + withderivatives = optimbase_cget ( this.optbase , "-withderivatives" ); + if ( withderivatives ) then + errmsg = msprintf(gettext("%s: The -withderivatives option is true but all algorithms in neldermead are derivative-free."), "neldermead_search") + error(errmsg) + end + if ( ~this.startupflag ) then + this = neldermead_startup ( this ); + this.startupflag = %t; + end + stop = neldermead_outputcmd ( this, "init" , this.simplex0 , "init" ) + if ( stop ) then + this.optbase = optimbase_set ( this.optbase , "-status" , "userstop" ); + verbose = optimbase_cget ( this.optbase , "-verbose" ) + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate by user''s request")); + end + return + end + + if ( this.restartflag ) then + this = neldermead_autorestart ( this ) + else + this = neldermead_algo ( this ); + end + stop = neldermead_outputcmd ( this, "done" , this.simplexopt , "done" ) + if ( stop ) then + this.optbase = optimbase_set ( this.optbase , "-status" , "userstop" ); + verbose = optimbase_cget ( this.optbase , "-verbose" ) + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate by user''s request")); + end + end + + warning(warn_mode); // Revert to the warning mode that was active before the call + +endfunction +// +// neldermead_algo -- +// Performs an optimization without restart +// +function this = neldermead_algo ( this ) + select this.method + case "fixed" then + this = neldermead_fixed (this); + case "variable" then + this = neldermead_variable (this); + case "box" then + this = neldermead_box (this); + case "mine" then + this = this.mymethod ( this ); + else + errmsg = msprintf(gettext("%s: Unknown -method %s"), "neldermead_algo", this.method) + error(errmsg) + end +endfunction +// +// neldermead_autorestart -- +// Performs an optimization with automatic restart +// NOTE +// The loop processes for i = 1 to restartmax PLUS 1 +// This is because a RE-start is performed after one simulation +// has been performed, hence the "RE". +// Hence, +// * if restartmax = 0, the number of performed loops is 1. +// * if restartmax = 1, the number of performed loops is 2. +// * etc... +// Example #1 +// Sample session with restart max = 3 (the default) and process pass. +// restartnb = 0 +// Try #1/4 +// Run +// "Must restart" +// restartnb = 1 +// Try #2/4 +// Run +// "Must restart" +// restartnb = 2 +// Try #3/4 +// Run +// "Must not restart" +// "Convergence reached after 2 restarts." +// reached = %t +// status = depending on the triggered termination criteria +// restartnb = 2 (restarts are Tries #2 and #3) +// Example #2 +// Sample session with restart max = 3 (the default) and process fails. +// restartnb = 0 +// Try #1/4 +// Run +// "Must restart" +// restartnb = 1 +// Try #2/4 +// Run +// "Must restart" +// restartnb = 2 +// Try #3/4 +// Run +// "Must restart" +// restartnb = 3 +// Try #4/4 +// Run +// Must restart +// "Convergence not reached after maximum 3 restarts." +// reached = %f +// status = "maxrestart" +// restartnb = 3 (restarts are Tries #2, #3 and #4) +// +function this = neldermead_autorestart ( this ) + restartmax = this.restartmax; + reached = %f; + for iloop = 1: restartmax + 1 + this = neldermead_log (this,sprintf("*****************************************************************")); + this = neldermead_log (this,sprintf("Try #%d/%d.", iloop , restartmax + 1 )); + // + // Run algorithm + this = neldermead_algo ( this ); + // + // Must we restart ? + [ this , istorestart ] = neldermead_istorestart ( this ); + if ( istorestart ) then + this = neldermead_log (this,"Must restart."); + else + this = neldermead_log (this,"Must not restart."); + end + if ( ~istorestart ) then + reached = %t; + break + end + if ( iloop < restartmax + 1 ) then + // We are going to perform a restart + this.restartnb = this.restartnb + 1; + this = neldermead_log (this,"Updating simplex."); + this = neldermead_updatesimp ( this ); + end + end + if ( reached ) then + this = neldermead_log (this, sprintf ( "Convergence reached after %d restarts." , this.restartnb ) ); + else + this = neldermead_log (this, sprintf ( "Convergence not reached after maximum %d restarts." , this.restartnb ) ); + this.optbase = optimbase_set ( this.optbase , "-status" , "maxrestart" ); + end +endfunction + + +// +// neldermead_variable -- +// The original Nelder-Mead algorithm, with variable-size simplex. +// +function this = neldermead_variable ( this ) + // Check settings correspond to algo + [ this.optbase , hascons ] = optimbase_hasconstraints ( this.optbase ); + if ( hascons ) then + errmsg = msprintf(gettext("%s: Problem has constraints, but variable algorithm ignores them."), "neldermead_variable") + error(errmsg) + end + verbose = optimbase_cget ( this.optbase , "-verbose" ) + // + // Order the vertices for the first time + // + simplex = this.simplex0; + n = optimbase_cget ( this.optbase , "-numberofvariables" ); + if (n==0) then + errmsg = msprintf(gettext("%s: The number of variable is zero."), "neldermead_variable") + error(errmsg) + end + fvinitial = optimbase_get ( this.optbase , "-fx0" ); + // Sort function values and x points by increasing function value order + this = neldermead_log (this,"Step #1 : order"); + simplex = optimsimplex_sort ( simplex ); + // Transpose, because optimsimplex returns row vectors + currentcenter = optimsimplex_center ( simplex ).'; + currentxopt = optimbase_cget ( this.optbase , "-x0" ); + newfvmean = optimsimplex_fvmean ( simplex ); + greedy = this.greedy; + // + // Initialize + // + terminate = %f; + iter = 0; + step = "init"; + // + // Nelder-Mead Loop + // + while ( ~terminate ) + this.optbase = optimbase_incriter ( this.optbase ); + iter = iter + 1; + // Transpose, because optimsimplex returns row vectors + xlow = optimsimplex_getx ( simplex , 1 ).' + flow = optimsimplex_getfv ( simplex , 1 ) + xhigh = optimsimplex_getx ( simplex , n+1 ).' + fhigh = optimsimplex_getfv ( simplex , n+1 ) + xn = optimsimplex_getx ( simplex , n ).' + fn = optimsimplex_getfv ( simplex , n ) + // + // Store history + + + + + + // + xcoords = optimsimplex_getallx ( simplex ) + this = neldermead_storehistory ( this , n , flow , xlow , xcoords ); + currentfopt = flow; + previousxopt = currentxopt; + currentxopt = xlow; + previouscenter = currentcenter; + currentcenter = optimsimplex_center ( simplex ).'; + oldfvmean = newfvmean; + newfvmean = optimsimplex_fvmean ( simplex ); + if ( verbose == 1 ) then + this = neldermead_logsummary ( this, iter,xlow,flow,currentcenter,simplex ) + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + stop = neldermead_outputcmd ( this, "iter" , simplex , step ) + if ( stop ) then + status = "userstop" + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate by user''s request")); + end + break + end + + // + // Update termination flag + // + if ( iter > 1 ) then + [ this , terminate , status ] = neldermead_termination (this , ... + fvinitial , oldfvmean , newfvmean , previouscenter , currentcenter , simplex ); + if ( terminate ) then + this = neldermead_log (this,sprintf("Terminate with status : %s",status)); + break + end + end + // + // Compute xbar, center of better vertices + // + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Reflect")); + end + // Transpose, because optimsimplex returns row vectors + xbar = optimsimplex_xbar ( simplex ).'; + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xbar="+_strvec(xbar)+"")); + end + // + // Reflect the worst point with respect to center + // + xr = neldermead_interpolate ( xbar , xhigh , this.rho ); + [ this.optbase , fr , index ] = optimbase_function ( this.optbase , xr , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xr=["+_strvec(xr)+"], f(xr)=%f",fr)); + end + if ( fr >= flow & fr < fn ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform reflection")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fr , xr.' ) + step = "reflection"; + elseif ( fr < flow ) then + // Expand + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Expand")); + end + xe = neldermead_interpolate ( xbar , xhigh , this.rho*this.chi ); + [ this.optbase , fe , index ] = optimbase_function ( this.optbase , xe , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xe="+_strvec(xe)+", f(xe)=%f",fe)); + end + if ( greedy ) then + if ( fe < flow ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Greedy Expansion")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fe , xe.' ) + step = "expansion"; + else + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Greedy Reflection")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fr , xr.' ) + step = "reflection"; + end + else + if ( fe < fr ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Expansion")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fe , xe.' ) + step = "expansion"; + else + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Reflection")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fr , xr.' ) + step = "reflection"; + end + end + elseif ( fr >= fn & fr < fhigh ) then + // Outside contraction + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Contract - outside")); + end + xc = neldermead_interpolate ( xbar , xhigh , this.rho*this.gamma ); + [ this.optbase , fc , index ] = optimbase_function ( this.optbase , xc , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xc="+_strvec(xc)+", f(xc)=%f",fc)); + end + if ( fc <= fr ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Outside Contraction")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fc , xc.' ) + step = "outsidecontraction"; + else + // Shrink + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Shrink")); + end + [ simplex , this ] = optimsimplex_shrink ( simplex , costf_transposex , this.sigma , this ); + step = "shrink"; + end + else + // ( fr >= fn & fr >= fhigh ) + // Inside contraction + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Contract - inside")); + end + xc = neldermead_interpolate ( xbar , xhigh , -this.gamma ); + [ this.optbase , fc , index ] = optimbase_function ( this.optbase , xc , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xc="+_strvec(xc)+", f(xc)=%f",fc)); + end + if ( fc < fhigh ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Inside Contraction")); + end + simplex = optimsimplex_setve ( simplex , n+1 , fc , xc.' ) + step = "insidecontraction"; + else + // Shrink + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Shrink")); + end + [ simplex , this ] = optimsimplex_shrink ( simplex , costf_transposex , this.sigma , this ) + step = "shrink"; + end + end + // + // Sort simplex + // + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Sort")); + end + simplex = optimsimplex_sort ( simplex ); + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + this.optbase = optimbase_set ( this.optbase , "-status" , status ); + this.simplexopt = simplex; +endfunction + +// +// neldermead_fixed -- +// The simplex algorithm with fixed size simplex. +// Implementation note: +// We implement the following "rules" of the Spendley et al. +// method. +// Rule 1 is strictly applied, but the reflection is done +// by reflection the high point, since we minimize a function +// instead of maximizing it, like Spendley. +// The Rule 2 is NOT implemented, as we expect that the +// function evaluation is not subject to errors. +// The Rule 3 is applied, ie reflection with respect +// to next to high point. +// A shrink step is included, with shrinkage factor sigma. +// +// "Rule 1. Ascertain the lowest reading y, of yi ... Yk+1 +// Complete a new simplex Sp by excluding the point Vp corresponding to +// y, and replacing it by V* defined as above." +// "Rule 2. If a result has occurred in (k + 1) successive simplexes, and is not +// then eliminated by application of Rule 1, do not move in the direction +// indicated by Rule 1, or at all, but discard the result and replace it by a new +// observation at the same point." +// "Rule 3. If y is the lowest reading in So , and if the next observation made, +// y* , is the lowest reading in the new simplex S , do not apply Rule 1 and +// return to So from Sp . Move out of S, by rejecting the second lowest reading +// (which is also the second lowest reading in So)." +// +function this = neldermead_fixed (this) + // Check settings correspond to algo + [ this.optbase , hascons ] = optimbase_hasnlcons ( this.optbase ); + if ( hascons ) then + errmsg = msprintf(gettext("%s: Problem has constraints, but fixed algorithm ignores them."), "neldermead_fixed") + error(errmsg) + end + verbose = optimbase_cget ( this.optbase , "-verbose" ) + // + // Order the vertices for the first time + // + simplex = this.simplex0; + n = optimbase_cget ( this.optbase , "-numberofvariables" ); + fvinitial = optimbase_get ( this.optbase , "-fx0" ); + // Sort function values and x points by increasing function value order + this = neldermead_log (this,sprintf("Sort")); + simplex = optimsimplex_sort ( simplex ); + // + // Compute center of simplex + // + // Transpose, because optimsimplex returns row vectors + currentcenter = optimsimplex_center ( simplex ).'; + newfvmean = optimsimplex_fvmean ( simplex ); + currentxopt = optimbase_cget ( this.optbase , "-x0" ); + // + // Set indices for "clarity" + // + ilow = 1 + ihigh = n + 1 + inext = n + // + // Initialize + // + terminate = %f; + iter = 0; + step = "init"; + // + // main N-M loop + // + while ( ~terminate ) + this.optbase = optimbase_incriter ( this.optbase ); + iter = iter + 1; + xlow = optimsimplex_getx ( simplex , ilow ).' + flow = optimsimplex_getfv ( simplex , ilow ) + xhigh = optimsimplex_getx ( simplex , ihigh ).' + fhigh = optimsimplex_getfv ( simplex , ihigh ) + // + // Store history + // + xcoords = optimsimplex_getallx ( simplex ) + this = neldermead_storehistory ( this , n , flow , xlow , xcoords ); + currentfopt = flow; + previousxopt = currentxopt; + currentxopt = xlow; + previouscenter = currentcenter; + currentcenter = optimsimplex_center ( simplex ).'; + oldfvmean = newfvmean; + newfvmean = optimsimplex_fvmean ( simplex ); + if ( verbose == 1 ) then + this = neldermead_logsummary ( this, iter,xlow,flow,currentcenter,simplex ) + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + stop = neldermead_outputcmd ( this, "iter" , simplex , step ) + if ( stop ) then + status = "userstop" + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate by user''s request")); + end + break + end + // + // Update termination flag + // + if ( iter > 1 ) then + [ this , terminate , status] = neldermead_termination (this , ... + fvinitial , oldfvmean , newfvmean , previouscenter , currentcenter , simplex ); + if ( terminate ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate with status : %s",status)); + end + break; + end + end + // + // Compute xbar, center of better vertices + // + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Reflect")); + end + xbar = optimsimplex_xbar ( simplex ).'; + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xbar="+_strvec(xbar)+"")); + end + // + // Reflect the worst point with respect to center + // + xr = neldermead_interpolate ( xbar , xhigh , this.rho ); + [ this.optbase , fr , index ] = optimbase_function ( this.optbase , xr , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xr="+_strvec(xr)+", f(xr)=%f",fr)); + end + // + // Replace worst point by xr if it is better + // + if ( fr < fhigh ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform reflect")); + end + simplex = optimsimplex_setve ( simplex , ihigh , fr , xr.' ) + step = "reflection"; + else + // Reflect / xnext + xnext = optimsimplex_getx ( simplex , inext ).'; + fnext = optimsimplex_getfv ( simplex , inext ); + xbar2 = optimsimplex_xbar ( simplex , inext ).'; + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xbar2="+_strvec(xbar2)+"")); + end + xr2 = neldermead_interpolate ( xbar2 , xnext , this.rho ); + [ this.optbase , fr2 , index ] = optimbase_function ( this.optbase , xr2 , 2 ); + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xr2="+_strvec(xr2)+", f(xr2)=%f",fr2)); + end + if ( fr2 < fnext ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform reflect / next")); + end + simplex = optimsimplex_setve ( simplex , inext , fr2 , xr2.' ) + step = "reflectionnext"; + else + // Shrink + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf(" > Perform Shrink")); + end + [ simplex , this ] = optimsimplex_shrink ( simplex , costf_transposex , this.sigma , this ) + step = "shrink"; + end + end + // + // Sort simplex + // + simplex = optimsimplex_sort ( simplex ); + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + this.optbase = optimbase_set ( this.optbase , "-status" , status ); + this.simplexopt = simplex; +endfunction +// +// neldermead_interpolate -- +// Computes xi as an interpolation between x1 and x2, with factor as : +// xi = (1+fac)x1 - fac x2 +// +function xi = neldermead_interpolate ( x1 , x2 , fac ) + xi = (1 + fac)*x1 - fac*x2; +endfunction + +// +// neldermead_termination -- +// Returns 1 if the algorithm terminates. +// Returns 0 if the algorithm must continue. +// Arguments +// this : the current object +// fvinitial : initial function value +// newfvmean, oldfvmean : the old and new function value average on the simplex +// previousxopt : the previous value of x +// currentxopt : the current value of x +// simplex : the simplex +// The best point in the simplex is expected to be stored at 1 +// The worst point in the simplex is expected to be stored at n+1 +// terminate : %t if the algorithm terminates, %f if the algorithm must continue. +// this.status : termination status +// "continue" +// "maxiter" +// "maxfuneval" +// "tolf" +// "tolx" +// "tolsize" +// "tolsizedeltafv" +// "kelleystagnation" +// "tolboxf" +// "tolvariance" +// Notes +// Use the function average on the simplex instead of the best function value. +// This is because the function average changes at each iteration. +// Instead, the best function value as a step-by-step evolution and may not +// change in 2 iterations, leading to astop of the algorithm. +// TODO : set the fvinitial, oldfvmean, newfvmean. +// +function [ this , terminate , status ] = neldermead_termination (this , ... + fvinitial , oldfvmean , newfvmean , previousxopt , currentxopt , ... + simplex ) + terminate = %f; + status = "continue"; + verbose = optimbase_cget ( this.optbase , "-verbose" ) + // + // Termination Criteria from parent optimization class + // + [ this.optbase , terminate , status ] = optimbase_terminate ( this.optbase , ... + fvinitial , newfvmean , previousxopt , currentxopt ); + // + // Criteria #6 : simplex absolute + relative size + // + if ( ~terminate ) then + if ( this.tolsimplexizemethod ) then + ssize = optimsimplex_size ( simplex , "sigmaplus" ); + tolsa = this.tolsimplexizeabsolute; + tolsr = this.tolsimplexizerelative; + ssize0 = this.simplexsize0; + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase,sprintf(" > simplex size=%s < %s + %s * %s",... + string(ssize), string(tolsa) , string(tolsr) , string(ssize0) )); + end + if ( ssize < tolsa + tolsr * ssize0 ) then + terminate = %t; + status = "tolsize"; + end + end + end + // + // Criteria #7 : simplex absolute size + difference in function values (Matlab-like) + // + if ( ~terminate ) then + if ( this.tolssizedeltafvmethod ) then + ssize = optimsimplex_size ( simplex , "sigmaplus" ); + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase,sprintf(" > simplex size=%s < %s",... + string(ssize), string(this.tolsimplexizeabsolute))); + end + shiftfv = abs(optimsimplex_deltafvmax( simplex )) + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase,sprintf(" > abs(fv(n+1) - fv(1))=%s < toldeltafv=%s",... + string(shiftfv), string(this.toldeltafv))); + end + if ( ( ssize < this.tolsimplexizeabsolute ) & ( shiftfv < this.toldeltafv ) ) then + terminate = %t; + status = "tolsizedeltafv"; + end + end + end + // + // Criteria #8 : Kelley stagnation, based on + // a sufficient decrease condition + // + if ( ~terminate ) then + if ( this.kelleystagnationflag ) then + [ sg , this ] = optimsimplex_gradientfv ( simplex , neldermead_costf , "forward" , this ); + nsg = sg.' * sg; + if ( verbose == 1 ) then + sgstr = _strvec(sg); + this.optbase = optimbase_stoplog ( this.optbase , sprintf ( "Test Stagnation : nsg = %s, sg = [%s]", ... + string(nsg) , sgstr ) ); + this.optbase = optimbase_stoplog ( this.optbase , ... + sprintf ( "Test Stagnation : newfvmean=%s >= oldfvmean=%s - %s * %s" , .... + string(newfvmean), string(oldfvmean) , string(this.kelleyalpha) , string(nsg) ) ); + end + if ( newfvmean >= oldfvmean - this.kelleyalpha * nsg ) then + terminate = %t; + status = "kelleystagnation"; + end + end + end + // + // Criteria #9 : Box termination criteria + // The number of consecutive time that an absolute tolerance on + // function value is met. + // From Algorithm 454, the tolerance is the difference between the + // max and the min function values in the simplex. + // + if ( ~terminate ) then + if ( this.boxtermination ) then + shiftfv = abs(optimsimplex_deltafvmax( simplex )) + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase , ... + sprintf ( "Test Box : shiftfv=%s < boxtolf=%s" , ... + string(shiftfv) , string(this.boxtolf) ) ); + end + if ( shiftfv < this.boxtolf ) then + this.boxkount = this.boxkount + 1 + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase , ... + sprintf ( "Test Box : boxkount=%d == boxnbmatch=%d" , ... + this.boxkount , this.boxnbmatch ) ); + end + if ( this.boxkount == this.boxnbmatch ) then + terminate = %t + status = "tolboxf" + end + else + this.boxkount = 0 + end + end + end + // + // Obsolete option: maintain for backward compatibility + // Criteria #10 : variance of function values + // + if ( ~terminate ) then + if ( this.tolvarianceflag ) then + var = optimsimplex_fvvariance ( simplex ) + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog ( this.optbase , ... + sprintf ( "Test tolvariance : %s < %s" , ... + string(var) , string(this.tolabsolutevariance) ) ); + end + if ( var < this.tolrelativevariance * this.variancesimplex0 + this.tolabsolutevariance ) then + terminate = %t + status = "tolvariance" + end + end + end + // + // Obsolete option: maintain for backward compatibility + // Criteria #11 : user-defined criteria + // + if ( ~terminate ) then + if ( this.myterminateflag ) then + [ this , term , stat ] = this.myterminate ( this , simplex ) + if ( term ) then + terminate = term + status = stat + end + end + end + // + // A verbose message + // + if ( verbose == 1 ) then + this.optbase = optimbase_stoplog (this.optbase,sprintf(" > Terminate = %s, status = %s",... + string(terminate) , status )); + end +endfunction + + +// +// neldermead_outputcmd -- +// Calls back user's output command +// Arguments +// this : the current object +// state : the state of the algorithm, +// "init", "done", "iter" +// simplex : the current simplex +// step : the type of step performed during the iteration +// "init", "done", "reflection", "expansion", "insidecontraction", "outsidecontraction" +// "reflectionnext", "shrink" +// stop : set to true to stop algorithm +// +function stop = neldermead_outputcmd ( this, ... + state , simplex , step ) + outputcmd = optimbase_cget ( this.optbase , "-outputcommand" ); + if typeof(outputcmd) <> "string" then + brutedata = optimbase_outstruct ( this.optbase ); + data = tlist(["T_NMDATA",... + "x","fval","iteration","funccount",... + "simplex" , "step" ]); + data.x = brutedata.x; + data.fval = brutedata.fval; + data.iteration = brutedata.iteration; + data.funccount = brutedata.funccount; + data.simplex = simplex; + data.step = step; + stop = optimbase_outputcmd ( this.optbase , state , data ); + else + stop = %f + end +endfunction +// +// neldermead_storehistory -- +// Stores the history into the data structure. +// Arguments, input +// this : current object +// n : the number of unknown parameters +// fopt : the current value of the function at optimum +// xopt : arrary with size n, current optimum +// xcoords : array with size n x n+1, coordinates of the n+1 vertices +// +function this = neldermead_storehistory ( this , n , fopt , xopt , xcoords ) + storehistory = optimbase_cget ( this.optbase , "-storehistory" ); + iterations = optimbase_get ( this.optbase , "-iterations" ); + if ( storehistory ) then + this.optbase = optimbase_histset ( this.optbase , iterations , "-fopt" , fopt ); + this.optbase = optimbase_histset ( this.optbase , iterations , "-xopt" , xopt(1:n) ); + this.historysimplex ( iterations , 1:n+1,1:n) = xcoords(1:n+1,1:n); + end +endfunction + +// +// neldermead_istorestart -- +// Returns 1 if the optimization is to restart. +// Arguments +// istorestart : %t of the optimization is to restart. +// +function [ this , istorestart ] = neldermead_istorestart ( this ) + status = optimbase_get ( this.optbase , "-status" ); + if ( status =="maxfuneval" ) then + istorestart = %f + return + end + select this.restartdetection + case "oneill" + [ this , istorestart ] = neldermead_isroneill ( this ) + case "kelley" + [ this , istorestart ] = neldermead_isrkelley ( this ) + else + errmsg = msprintf(gettext("%s: Unknown restart detection %s"),"neldermead_istorestart", this.restartdetection) + error(errmsg) + end +endfunction +// +// neldermead_isrkelley-- +// Returns 1 if the optimization is to restart. +// Use kelleystagnation as a criteria for restart. +// Arguments +// istorestart : %t of the optimization is to restart. +// +function [ this , istorestart ] = neldermead_isrkelley ( this ) + istorestart = %f + if ( this.kelleystagnationflag ) then + status = optimbase_get ( this.optbase , "-status" ); + if ( status =="kelleystagnation" ) then + istorestart = %t + end + end +endfunction +// +// neldermead_isroneill -- +// Returns 1 if the optimization is to restart. +// Use O'Neill method as a criteria for restart. +// It is an axis by axis search for optimality. +// Arguments +// xopt : the optimum, as a st of n values +// fopt : function value at optimum +// eps : a small value +// step : a list of n values, representing +// the "size" of each parameter +// istorestart : %t if the optimization is to restart. +// +function [ this , istorestart ] = neldermead_isroneill ( this ) + n = optimbase_cget ( this.optbase , "-numberofvariables" ); + // + // If required, make a vector step from the scalar step + // + defaultstep = this.restartstep; + steprows = size ( defaultstep , "r" ); + if ( steprows == 1 ) then + step = defaultstep * ones(n,1); + else + step = defaultstep; + end + restarteps = this.restarteps; + + x = optimbase_get ( this.optbase , "-xopt" ); + fopt = optimbase_get ( this.optbase , "-fopt" ); + verbose = optimbase_cget ( this.optbase , "-verbose" ) + + if ( verbose ) then + this = neldermead_log (this,sprintf("=================================================================")); + this = neldermead_log (this, sprintf ( "O''Neill Restart\n") ); + this = neldermead_log (this, sprintf ( "Using step [%s]" , _strvec(step) ) ); + end + + istorestart = %f + for ix = 1:n + stepix = step ( ix ) + del = stepix * restarteps + xix = x ( ix ) + x ( ix ) = xix + del + [ this.optbase , fv , index ] = optimbase_function ( this.optbase , x , 2 ) + if ( fv < fopt ) then + istorestart = %t + if ( verbose ) then + this = neldermead_log (this, sprintf ( "Must restart because fv=%s at [%s] is lower than fopt=%s" , ... + string(fv) , _strvec(x) , string(fopt)) ); + end + break + end + x ( ix ) = xix - del + [ this.optbase , fv , index ] = optimbase_function ( this.optbase , x , 2 ) + if ( fv < fopt ) then + istorestart = %t + if ( verbose ) then + this = neldermead_log (this, sprintf( "Must restart because fv=%s at [%s] is lower than fopt=%s" , ... + string(fv) , _strvec(x) , string(fopt)) ); + end + break + end + x ( ix ) = xix + end +endfunction + +// +// neldermead_startup -- +// Startup the algorithm. +// Computes the initial simplex, depending on the -simplex0method. +// +function this = neldermead_startup (this) + // + // 0. Check that the cost function is correctly connected + // Note: this call to the cost function is not used, but helps the + // user while he is tuning his object. + if ( this.checkcostfunction ) then + this.optbase = optimbase_checkcostfun ( this.optbase ); + end + // + // 1. If the problem has bounds, check that they are consistent + [ this.optbase , hasbounds ] = optimbase_hasbounds ( this.optbase ); + if ( hasbounds ) then + this.optbase = optimbase_checkbounds ( this.optbase ); + end + // + // 2. Get the initial guess and compute the initial simplex + x0 = optimbase_cget ( this.optbase , "-x0" ); + select this.simplex0method + case "given" then + [ simplex0 , this ] = optimsimplex_new ( this.coords0 , [] , this ); + case "axes" then + [ simplex0 , this ] = optimsimplex_new ( "axes" , ... + x0.' , [] , this.simplex0length , this ); + case "spendley" then + [ simplex0 , this ] = optimsimplex_new ( "spendley" , ... + x0.' , [] , this.simplex0length , this ); + case "pfeffer" then + [ simplex0 , this ] = optimsimplex_new ( "pfeffer" , ... + x0.' , [] , this.simplex0deltausual , ... + this.simplex0deltazero , this ); + case "randbounds" then + if ( this.boxnbpoints == "2n" ) then + this.boxnbpointseff = 2 * this.optbase.numberofvariables; + else + this.boxnbpointseff = this.boxnbpoints; + end + if ( ~hasbounds ) then + error ( msprintf(gettext("%s: Randomized bounds initial simplex is not available without bounds." ), "neldermead_startup")) + end + [ simplex0 , this ] = optimsimplex_new ( "randbounds" , x0.' , ... + [] , this.optbase.boundsmin , this.optbase.boundsmax , ... + this.boxnbpointseff , this ); + else + errmsg = msprintf(gettext("%s: Unknown value %s for -simplex0method option"), "neldermead_startup", this.simplex0method); + error(errmsg); + end + // + // 3. Scale the initial simplex into the bounds and the nonlinear inequality constraints, if any + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + if ( hasbounds | hasnlcons ) then + // Check that initial guess is feasible + [ this.optbase , isfeasible ] = optimbase_isfeasible ( this.optbase , x0 ); + if ( isfeasible <> 1 ) then + error ( msprintf ( gettext ( "%s: Initial guess [%s] is not feasible." ) , "neldermead_startup" , _strvec ( x0 ) ) ) + end + this = neldermead_log (this,sprintf("Scaling initial simplex into nonlinear inequality constraints...")); + select this.scalingsimplex0 + case "tox0" then + [ this , simplex0 ] = neldermead_scaletox0 ( this , simplex0 ); + case "tocenter" then + [ this , simplex0 ] = neldermead_scaletocenter ( this , simplex0 ); + else + errmsg = msprintf(gettext("%s: Unknown value %s for -scalingsimplex0 option"),"neldermead_startup", this.scalingsimplex0 ); + error(errmsg); + end + end + // + // 4. Compute the function values + nbve = optimsimplex_getnbve ( simplex0 ); + for ive = 1 : nbve + // Transpose, because optimsimplex returns row vectors + x = optimsimplex_getx ( simplex0 , ive ).'; + if ( hasnlcons ) then + [ this.optbase , fv , c , index ] = optimbase_function ( this.optbase , x , 2 ); + else + [ this.optbase , fv , index ] = optimbase_function ( this.optbase , x , 2 ); + end + // Transpose xp, which is a column vector + simplex0 = optimsimplex_setve ( simplex0 , ive , fv , x.' ); + end + // + // 5. Store the simplex + this.simplex0 = optimsimplex_destroy ( this.simplex0 ); + this.simplex0 = simplex0; + this.simplexsize0 = optimsimplex_size ( simplex0 ); + // + // 6. Store initial data into the base optimization component + fx0 = optimsimplex_getfv ( this.simplex0 , 1 ); + this.optbase = optimbase_set ( this.optbase , "-fx0" , fx0 ); + this.optbase = optimbase_set ( this.optbase , "-xopt" , x0 ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , fx0 ); + this.optbase = optimbase_set ( this.optbase , "-iterations" , 0 ); + // + // 7. Initialize the termination criteria + this = neldermead_termstartup ( this ); +endfunction +// +// neldermead_scaletox0 -- +// Scale the simplex into the +// nonlinear inequality constraints, if any. +// Scale toward x0, which is feasible. +// Do not update the function values. +// Arguments +// simplex0 : the initial simplex +// +function [ this , simplex0 ] = neldermead_scaletox0 ( this , simplex0 ) + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + nbve = optimsimplex_getnbve ( simplex0 ); + x0 = optimbase_cget ( this.optbase , "-x0" ); + for ive = 2 : nbve + // Transpose, because optimsimplex returns row vectors + x = optimsimplex_getx ( simplex0 , ive ).'; + this = neldermead_log (this,sprintf("Scaling vertex #%d/%d at ["+... + _strvec(x)+"]... " , ive , nbve )); + // Transpose x into a row vector + [ this , status , xp ] = _scaleinconstraints ( this , x , x0 ); + if ( ~status ) then + lclmsg = gettext("%s: Impossible to scale the vertex #%d/%d at [%s] into inequality constraints") + errmsg = msprintf(lclmsg, ... + "neldermead_startup", ive , nbve , _strvec(x)); + error(errmsg); + end + if ( or ( x <> xp ) ) then + // Transpose xp, which is a column vector + simplex0 = optimsimplex_setx ( simplex0 , ive , xp.' ); + end + end +endfunction +// +// neldermead_scaletocenter -- +// Scale the simplex into the +// nonlinear inequality constraints, if any. +// Scale to the centroid of the points +// which satisfy the constraints. +// Do not update the function values. +// Notes +// This is Box's method for scaling. +// It is unsure, since the centroid of the points +// which satisfy the constraints may not be feasible. +// Arguments +// +// +function [ this , simplex0 ] = neldermead_scaletocenter ( this , simplex0 , x0 ) + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + nbve = optimsimplex_getnbve ( simplex0 ); + for ive = 2 : nbve + xref = optimsimplex_xbar ( simplex0 , ive:nbve ).'; + // Transpose, because optimsimplex returns row vectors + x = optimsimplex_getx ( simplex0 , ive ).'; + this = neldermead_log (this,sprintf("Scaling vertex #%d/%d at ["+... + _strvec(x)+"]... " , ive , nbve )); + // Transpose x into a row vector + [ this , status , xp ] = _scaleinconstraints ( this , x , xref ); + if ( ~status ) then + errmsg = msprintf(gettext("%s: Impossible to scale the vertex #%d/%d at [%s] into inequality constraints"), ... + "neldermead_startup", ive , nbve , _strvec(x)); + error(errmsg); + end + if ( or ( x <> xp ) ) then + // Transpose xp, which is a column vector + simplex0 = optimsimplex_setx ( simplex0 , ive , xp.' ); + end + end +endfunction +// +// neldermead_termstartup -- +// Initialize Kelley's stagnation detection system when normalization is required, +// by computing kelleyalpha. +// If the simplex gradient is zero, then +// use alpha0 as alpha. +// Arguments +// status : the status after the failing +// optimization process +// simplex : the simplex computed at the end of the failing +// optimization process +// +function this = neldermead_termstartup ( this ) + // + // Criteria #8 : Kelley stagnation, based on + // a sufficient decrease condition + // + if ( this.kelleystagnationflag ) then + if ( ~this.kelleynormalizationflag ) then + this.kelleyalpha = this.kelleystagnationalpha0 + else + [sg,this] = optimsimplex_gradientfv ( this.simplex0 , neldermead_costf , "forward" , this ) + nsg = sg.' * sg + sigma0 = optimsimplex_size ( this.simplex0 , "sigmaplus" ) + if nsg==0.0 then + this.kelleyalpha = this.kelleystagnationalpha0 + else + this.kelleyalpha = this.kelleystagnationalpha0 * sigma0 / nsg + end + end + this = neldermead_log (this,sprintf("Test Stagnation Kelley : alpha0 = %s", string(this.kelleyalpha))); + end + // + // Criteria #10 : variance of function values + // + if ( this.tolvarianceflag ) then + this.variancesimplex0 = optimsimplex_fvvariance ( this.simplex0 ) + end +endfunction +// +// _scaleinconstraints -- +// Given a point to scale and a reference point which satisfies the constraints, +// scale the point towards the reference point until it satisfies all the constraints. +// Returns isscaled = %T if the procedure has succeded before -boxnbnlloops +// Returns isscaled = %F if the procedure has failed after -boxnbnlloops +// iterations. +// Arguments +// x : the point to scale +// xref : the reference point +// isscaled : %T or %F +// p : scaled point +// +function [ this , isscaled , p ] = _scaleinconstraints ( this , x , xref ) + p = x + [ this.optbase , hasbounds ] = optimbase_hasbounds ( this.optbase ); + nbnlc = optimbase_cget ( this.optbase , "-nbineqconst" ) + // + // 1. No bounds, no nonlinear inequality constraints + // => no problem + // + if ( ( hasbounds == %f ) & ( nbnlc == 0 ) ) then + isscaled = %T + return; + end + // + // 2. Scale into bounds + // + if ( hasbounds ) then + [ this.optbase , p ] = optimbase_proj2bnds ( this.optbase , p ); + this = neldermead_log (this,sprintf(" > After projection into bounds p = [%s]" , ... + _strvec(p))); + end + // + // 3. Scale into non linear constraints + // Try the current point and see if the constraints are satisfied. + // If not, move the point "halfway" to the centroid, + // which should satisfy the constraints, if + // the constraints are convex. + // Perform this loop until the constraints are satisfied. + // If all loops have been performed without success, the scaling + // has failed. + // + isscaled = %F + alpha = 1.0 + p0 = p + while ( alpha > this.guinalphamin ) + [ this.optbase , feasible ] = optimbase_isinnonlincons ( this.optbase , p ); + if ( feasible ) then + isscaled = %T; + break; + end + alpha = alpha * this.boxineqscaling + this = neldermead_log (this,sprintf("Scaling inequality constraint with alpha = %s", ... + string(alpha))); + p = ( 1.0 - alpha ) * xref + alpha * p0; + end + this = neldermead_log (this,sprintf(" > After scaling into inequality constraints p = [%s]" , ... + _strvec(p) ) ); + if ( ~isscaled ) then + this = neldermead_log (this,sprintf(" > Impossible to scale into constraints after %d loops" , ... + this.optbase.nbineqconst )); + end +endfunction +// +// neldermead_logsummary -- +// At each iteration, prints this iteration summary. +// +function this = neldermead_logsummary ( this, iter,xlow,flow,currentcenter,simplex ) + deltafv = abs(optimsimplex_deltafvmax ( simplex )); + totaliter = optimbase_get ( this.optbase , "-iterations" ); + funevals = optimbase_get ( this.optbase , "-funevals" ); + ssize = optimsimplex_size ( simplex ) + this = neldermead_log (this,sprintf("=================================================================")); + this = neldermead_log (this,sprintf("Iteration #%d (total = %d)",iter,totaliter)); + this = neldermead_log (this,sprintf("Function Eval #%d",funevals)); + this = neldermead_log (this,sprintf("Xopt : [%s]",_strvec(xlow))); + this = neldermead_log (this,sprintf("Fopt : %s",string(flow))); + this = neldermead_log (this,sprintf("DeltaFv : %s",string(deltafv))); + this = neldermead_log (this,sprintf("Center : [%s]",_strvec(currentcenter))); + this = neldermead_log (this,sprintf("Size : %s",string(ssize))); + str = string ( simplex ) + for i = 1:size(str,"*") + this = neldermead_log (this,str(i)); + end +endfunction + +// +// neldermead_box -- +// The Nelder-Mead algorithm, with variable-size simplex +// and modifications by Box for bounds and +// inequality constraints. +// +function this = neldermead_box ( this ) + // Check settings correspond to algo + [ this.optbase , hascons ] = optimbase_hasconstraints ( this.optbase ); + if ( ~hascons ) then + errmsg = msprintf(gettext("%s: Problem has no constraints, but Box algorithm is designed for them."), "neldermead_box") + error(errmsg) + end + verbose = optimbase_cget ( this.optbase , "-verbose" ) + // + // Order the vertices for the first time + // + simplex = this.simplex0; + n = optimbase_cget ( this.optbase , "-numberofvariables" ); + fvinitial = optimbase_get ( this.optbase , "-fx0" ); + // Sort function values and x points by increasing function value order + this = neldermead_log (this,"Step #1 : order"); + simplex = optimsimplex_sort ( simplex ); + // Transpose, because optimsimplex returns row vectors + currentcenter = optimsimplex_center ( simplex ).'; + currentxopt = optimbase_cget ( this.optbase , "-x0" ); + newfvmean = optimsimplex_fvmean ( simplex ); + nbve = optimsimplex_getnbve ( simplex ); + ihigh = nbve; + inext = ihigh - 1 + ilow = 1 + [ this.optbase , hasbounds ] = optimbase_hasbounds ( this.optbase ); + nbnlc = optimbase_cget ( this.optbase , "-nbineqconst" ) + rho = this.boxreflect; + // + // Initialize + // + terminate = %f; + iter = 0; + step = "init"; + // + // Nelder-Mead Loop + // + while ( ~terminate ) + this.optbase = optimbase_incriter ( this.optbase ); + iter = iter + 1; + xlow = optimsimplex_getx ( simplex , ilow ).' + flow = optimsimplex_getfv ( simplex , ilow ) + xhigh = optimsimplex_getx ( simplex , ihigh ).' + fhigh = optimsimplex_getfv ( simplex , ihigh ) + xn = optimsimplex_getx ( simplex , inext ).' + fn = optimsimplex_getfv ( simplex , inext ) + // + // Store history + // + xcoords = optimsimplex_getallx ( simplex ) + this = neldermead_storehistory ( this , n , flow , xlow , xcoords ); + currentfopt = flow; + previousxopt = currentxopt; + currentxopt = xlow; + previouscenter = currentcenter; + currentcenter = optimsimplex_center ( simplex ).'; + oldfvmean = newfvmean; + newfvmean = optimsimplex_fvmean ( simplex ); + if ( verbose == 1 ) then + this = neldermead_logsummary ( this, iter,xlow,flow,currentcenter,simplex); + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + stop = neldermead_outputcmd ( this, "iter" , simplex , step ) + if ( stop ) then + status = "userstop" + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate by user''s request")); + end + break + end + + // + // Update termination flag + // + if ( iter > 1 ) then + [ this , terminate , status ] = neldermead_termination (this , ... + fvinitial , oldfvmean , newfvmean , previouscenter , currentcenter , simplex ); + if ( terminate ) then + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Terminate with status : %s",status)); + end + break + end + end + // + // Compute xbar, center of better vertices + // + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Reflect")); + end + xbar = optimsimplex_xbar ( simplex ).'; + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xbar=[%s]" , _strvec(xbar))); + end + // + // Search a point improving cost function + // and satisfying constraints. + // + [ this , scaled , xr , fr ] = _boxlinesearch ( this , n , xbar , xhigh , fhigh , rho ); + if ( scaled == %f ) then + status = "impossibleimprovement" + break + end + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("xr=[%s], f(xr)=%f", _strvec(xr) , fr)); + this = neldermead_log (this,sprintf(" > Perform Reflection")); + end + simplex = optimsimplex_setve ( simplex , ihigh , fr , xr.' ) + step = "boxreflection"; + // + // Sort simplex + // + if ( verbose == 1 ) then + this = neldermead_log (this,sprintf("Sort")); + end + simplex = optimsimplex_sort ( simplex ); + end + this.optbase = optimbase_set ( this.optbase , "-xopt" , xlow ); + this.optbase = optimbase_set ( this.optbase , "-fopt" , flow ); + this.optbase = optimbase_set ( this.optbase , "-status" , status ); + this.simplexopt = simplex; +endfunction + +// +// _strvec -- +// Returns a string for the given vector. +// +function str = _strvec ( x ) + str = strcat(string(x)," ") +endfunction +// +// _boxlinesearch -- +// For Box's method, perform a line search +// from xbar, on the line (xhigh,xbar) and returns: +// status : %t if the search is successful, +// status=%f if the search failed. +// xr : the reflected, scaled point +// fr : the function value. fr=f(xr) if the search successful, +// fr is Nan if the search failed. +// The reflected point satisfies the following +// constraints : +// * fr < fhigh +// * xr satisfies the bounds constraints +// * xr satisfies the nonlinear positive inequality constraints +// * xr satisfies the linear positive inequality constraints +// The method is based on projection and scaling toward the centroid xbar. +// +// Arguments +// n : number of variables +// xbar : the centroid +// xhigh : the high point +// fhigh : function value at xhigh +// rho : reflection factor +// +function [ this , status , xr , fr ] = _boxlinesearch ( this , n , xbar , xhigh , fhigh , rho ) + if ( verbose == 1 ) then + this = neldermead_log (this,"_boxlinesearch"); + this = neldermead_log (this, sprintf ("> xhigh=[%s], fhigh=%s",_strvec(xhigh),string(fhigh))); + this = neldermead_log (this, sprintf ("> xbar=[%s]" , _strvec(xbar) ) ); + end + xr = neldermead_interpolate ( xbar , xhigh , rho ); + if ( verbose == 1 ) then + this = neldermead_log (this, sprintf ( "> xr = [%s]" , _strvec ( xr ) ) ); + end + alphamin = this.guinalphamin + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + // + // The algorithm has 3 steps: + // 1. scale for bounds (cannot fail) + // 2. scale for nonlinear constraints (may fail) + // 3. scale for function improvement (may fail) + // + // 1. Project xr into bounds, with an additional alpha inside the bounds. + // This algo is always succesful. + // Note: + // If the alpha coefficient was not used, the + // projectinbounds method could be used directly. + // + [ this.optbase , hasbounds ] = optimbase_hasbounds ( this.optbase ); + if ( hasbounds ) then + boxboundsalpha = this.boxboundsalpha; + boundsmax = optimbase_cget ( this.optbase , "-boundsmax" ); + boundsmin = optimbase_cget ( this.optbase , "-boundsmin" ); + for ix = 1:n + xmin = boundsmin ( ix ); + xmax = boundsmax ( ix ); + xrix = xr ( ix ); + if ( xrix > xmax ) then + xr ( ix ) = xmax - boxboundsalpha; + elseif ( xrix < xmin ) then + xr ( ix ) = xmin + boxboundsalpha; + end + end + end + // + // 2. Scale from xr to xbar into nonlinear inequality constraints + // and update xr. + // Set status to %f if the process fails, set status=%t if it succeeds. + // + nbnlc = optimbase_cget ( this.optbase , "-nbineqconst" ); + if ( nbnlc == 0 ) then + status = %t + else + status = %f; + alpha = 1.0; + xr0 = xr; + while ( alpha > alphamin ) + [ this.optbase , feasible ] = optimbase_isinnonlincons ( this.optbase , xr ); + if ( feasible ) then + status = %t; + break + end + alpha = alpha * this.boxineqscaling; + xr = ( 1.0 - alpha ) * xbar + alpha * xr0; + end + end + // If scaling failed, returns immediately + // (there is no need to update the function value). + if ( ~status ) then + fr = %nan + return + end + // + // 3. Scale from xr toward xbar until fr < fhigh. + // + status = %f; + xr0 = xr + alpha = 1.0 + while ( alpha > alphamin ) + if ( hasnlcons ) then + [ this.optbase , fr , cr , index ] = optimbase_function ( this.optbase , xr , 2 ); + else + [ this.optbase , fr , index ] = optimbase_function ( this.optbase , xr , 2 ); + end + if ( fr < fhigh ) then + status = %t; + break + end + alpha = alpha * this.boxineqscaling; + xr = ( 1.0 - alpha ) * xbar + alpha * xr0; + end + // If the scaling for function improvement has failed, + // we return. + if ( ~status ) then + fr = %nan + return; + end +endfunction +// +// costf_transposex -- +// Call the cost function and return the value. +// Transpose the value of x, so that the input row vector, +// given by optimsimplex, is transposed into a column vector, +// as required by the cost function. +// +function [ f , this ] = costf_transposex ( x , this ) + xt = x.' + [ f , this ] = neldermead_costf ( xt , this ) +endfunction + +function argin = argindefault ( rhs , vararglist , ivar , default ) + // Returns the value of the input argument #ivar. + // If this argument was not provided, or was equal to the + // empty matrix, returns the default value. + if ( rhs < ivar ) then + argin = default + else + if ( vararglist(ivar) <> [] ) then + argin = vararglist(ivar) + else + argin = default + end + end +endfunction diff --git a/modules/optimization/macros/neldermead/neldermead_updatesimp.bin b/modules/optimization/macros/neldermead/neldermead_updatesimp.bin Binary files differnew file mode 100755 index 000000000..3bf970603 --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_updatesimp.bin diff --git a/modules/optimization/macros/neldermead/neldermead_updatesimp.sci b/modules/optimization/macros/neldermead/neldermead_updatesimp.sci new file mode 100755 index 000000000..f3f433b8c --- /dev/null +++ b/modules/optimization/macros/neldermead/neldermead_updatesimp.sci @@ -0,0 +1,145 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// neldermead_updatesimp -- +// Update the initial simplex simplex0 for a restart. +// Arguments +// <> +// +function this = neldermead_updatesimp ( this ) + simplex0 = optimsimplex_new ( ); + xopt = optimbase_get ( this.optbase , "-xopt" ); + [ this.optbase , hasbounds ] = optimbase_hasbounds ( this.optbase ); + // + // Check the consistency between the initial simplex method + // and the restart simplex method. + simplex0method = neldermead_cget ( this , "-simplex0method" ) + restartsimplexmethod = neldermead_cget ( this , "-restartsimplexmethod" ) + select restartsimplexmethod + case "oriented" then + // An oriented restart is possible only if the initial simplex has n+1 vertices. + if ( simplex0method == "randbounds" ) then + lclmsg = gettext("%s: The initial simplex method ""%s"" is not compatible with the restart simplex method ""%s""") + errmsg = msprintf(lclmsg, "neldermead_updatesimp", simplex0method, restartsimplexmethod) + error(errmsg) + end + case "axes" then + + case "spendley" then + + case "pfeffer" then + + case "randbounds" then + if ( ~hasbounds ) then + lclmsg = gettext("%s: Randomized bounds restart simplex is not available without bounds." ) + errmsg = msprintf ( lclmsg , "neldermead_updatesimp" ) + error ( errmsg ) + end + else + errmsg = msprintf(gettext("%s: Unknown restart simplex method %s"), "neldermead_updatesimp", this.restartsimplexmethod) + error(errmsg) + end + // + // Update the simplex + select this.restartsimplexmethod + case "oriented" then + [ simplex0 , this ] = optimsimplex_new ( "oriented" , this.simplexopt , costf_transposex , this ); + case "axes" then + simplex0 = optimsimplex_destroy ( simplex0 ) + [ simplex0 , this ] = optimsimplex_new ( "axes" , ... + xopt.' , costf_transposex , this.simplex0length , this ); + case "spendley" then + simplex0 = optimsimplex_destroy ( simplex0 ) + [ simplex0 , this ] = optimsimplex_new ( "spendley" , ... + xopt.' , costf_transposex , this.simplex0length , this ); + case "pfeffer" then + simplex0 = optimsimplex_destroy ( simplex0 ) + [ simplex0 , this ] = optimsimplex_new ( "pfeffer" , ... + xopt.' , costf_transposex , this.simplex0deltausual , ... + this.simplex0deltazero , this ); + case "randbounds" then + if ( this.boxnbpoints=="2n" ) then + nbvar=optimbase_cget(this.optbase,"-numberofvariables") + this.boxnbpointseff = 2*nbvar + else + this.boxnbpointseff = this.boxnbpoints + end + simplex0 = optimsimplex_destroy ( simplex0 ) + [ simplex0 , this ] = optimsimplex_new ( "randbounds" , xopt.' , ... + costf_transposex , this.optbase.boundsmin , this.optbase.boundsmax , ... + this.boxnbpointseff , this ) + else + errmsg = msprintf(gettext("%s: Unknown restart simplex method %s"), "neldermead_updatesimp", this.restartsimplexmethod) + error(errmsg) + end + // + // Scale the simplex into the bounds and the nonlinear inequality constraints, if any. + // Caution ! + // The initial simplex may be computed with an "axis-by-axis" simplex, + // so that it does not satisfies bounds constraints. + // The scaling should therefore take into accounts for bounds. + // + nbve = optimsimplex_getnbve ( simplex0 ); + this = neldermead_log (this,"Before scaling:"); + str = string ( simplex0 ) + for i = 1:nbve + this = neldermead_log (this,str(i)); + end + [ this.optbase , hasnlcons ] = optimbase_hasnlcons ( this.optbase ); + if ( hasbounds | hasnlcons ) then + this = neldermead_log (this,sprintf("Scaling initial simplex into nonlinear inequality constraints...")); + nbve = optimsimplex_getnbve ( simplex0 ) + for ive = 1 : nbve + // x is a row vector + x = optimsimplex_getx ( simplex0 , ive ); + this = neldermead_log (this,sprintf("Scaling vertex #%d/%d at [%s]... " , ... + ive , nbve , _strvec(x))); + // Transpose x because xopt is a column vector : xp is now a column vector + [ this , status , xp ] = _scaleinconstraints ( this , x.' , xopt ); + if ( ~status ) then + errmsg = msprintf(gettext("%s: Impossible to scale the vertex #%d/%d at [%s] into inequality constraints"), "neldermead_updatesimp", ... + ive , nbve , strcat(string(x)," ")); + error(errmsg); + end + if ( or(x <> xp) ) then + index = 2 + if ( hasnlcons ) then + [ this.optbase , fv , c , index ] = optimbase_function ( this.optbase , xp , index ); + else + [ this.optbase , fv , index ] = optimbase_function ( this.optbase , xp , index ); + end + // Transpose xp because optimsimplex takes row coordinate vectors. + simplex0 = optimsimplex_setve ( simplex0 , ive , fv , xp.' ) + end + end + end + this = neldermead_log (this,"After scaling:"); + str = string ( simplex0 ) + for i = 1:nbve + this = neldermead_log (this,str(i)); + end + this.simplex0 = optimsimplex_destroy ( this.simplex0 ) + this.simplex0 = simplex0; + this.simplexsize0 = optimsimplex_size ( simplex0 ); + this.simplex0 = optimsimplex_sort ( this.simplex0 ) +endfunction +// +// costf_transposex -- +// Call the cost function and return the value. +// Transpose the value of x, so that the input row vector, +// given by optimsimplex, is transposed into a column vector, +// as required by the cost function. +// +function [ f , this ] = costf_transposex ( x , this ) + xt = x.' + [ f , this ] = neldermead_costf ( xt , this ) +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_cget.bin b/modules/optimization/macros/neldermead/nmplot_cget.bin Binary files differnew file mode 100755 index 000000000..817a6bd09 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_cget.bin diff --git a/modules/optimization/macros/neldermead/nmplot_cget.sci b/modules/optimization/macros/neldermead/nmplot_cget.sci new file mode 100755 index 000000000..91f36f716 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_cget.sci @@ -0,0 +1,30 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// nmplot_cget -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// +function value = nmplot_cget (this,key) + select key + case "-simplexfn" then + value = this.simplexfn; + case "-fbarfn" then + value = this.fbarfn; + case "-foptfn" then + value = this.foptfn; + case "-sigmafn" then + value = this.sigmafn; + else + this.nmbase = neldermead_configure ( this.nmbase , key , value ) + end +endfunction diff --git a/modules/optimization/macros/neldermead/nmplot_configure.bin b/modules/optimization/macros/neldermead/nmplot_configure.bin Binary files differnew file mode 100755 index 000000000..74b62ccd3 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_configure.bin diff --git a/modules/optimization/macros/neldermead/nmplot_configure.sci b/modules/optimization/macros/neldermead/nmplot_configure.sci new file mode 100755 index 000000000..8a51218e6 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_configure.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_configure -- +// Configure nmplot and returns the modified object. +// +function this = nmplot_configure (this,key,value) + select key + case "-simplexfn" then + this.simplexfn = value; + case "-fbarfn" then + this.fbarfn = value; + case "-foptfn" then + this.foptfn = value; + case "-sigmafn" then + this.sigmafn = value; + case "-outputcommand" then + errmsg = msprintf(gettext("%s: Unknown key %s"), "nmplot_configure", key) + error(errmsg) + else + this.nmbase = neldermead_configure ( this.nmbase , key , value ) + end +endfunction diff --git a/modules/optimization/macros/neldermead/nmplot_contour.bin b/modules/optimization/macros/neldermead/nmplot_contour.bin Binary files differnew file mode 100755 index 000000000..9ceb447a5 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_contour.bin diff --git a/modules/optimization/macros/neldermead/nmplot_contour.sci b/modules/optimization/macros/neldermead/nmplot_contour.sci new file mode 100755 index 000000000..788b263a3 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_contour.sci @@ -0,0 +1,37 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_contour -- +// Plot the contours of the cost function. +// The cost function must be a function with two parameters. +// Arguments +// xmin , xmax , ymin , ymax : the bounds for the contour plot +// nx , ny : the number of points in the directions x, y +// xdata , ydata , zdata : vectors of data, as required by the contour command +// +function [ this , xdata , ydata , zdata ] = nmplot_contour ( this , xmin , xmax , ymin , ymax , nx , ny ) + // Check that there are only 2 parameters + n = neldermead_cget ( this.nmbase , "-numberofvariables" ); + if n <> 2 then + errmsg = msprintf(gettext("%s: Unexpected number of variables %d. Cannot draw contour plot for functions which do not have two parameters."),"nmplot_contour",n) + error(errmsg) + end + xdata = linspace(xmin,xmax,nx); + ydata = linspace(ymin,ymax,ny); + for ix = 1:length(xdata) + for iy = 1:length(ydata) + experiment = [xdata(ix) ydata(iy)]'; + [ this.nmbase , fiexp ] = neldermead_function ( this.nmbase , experiment ); + zdata ( ix , iy ) = fiexp; + end + end +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_destroy.bin b/modules/optimization/macros/neldermead/nmplot_destroy.bin Binary files differnew file mode 100755 index 000000000..613a4b8d4 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_destroy.bin diff --git a/modules/optimization/macros/neldermead/nmplot_destroy.sci b/modules/optimization/macros/neldermead/nmplot_destroy.sci new file mode 100755 index 000000000..968e535e3 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_destroy.sci @@ -0,0 +1,17 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_destroy -- +// Destroy a Nelder-Mead plot object. +// +function this = nmplot_destroy (this) + this.nmbase = neldermead_destroy ( this.nmbase ) +endfunction diff --git a/modules/optimization/macros/neldermead/nmplot_function.bin b/modules/optimization/macros/neldermead/nmplot_function.bin Binary files differnew file mode 100755 index 000000000..8cf0b0e82 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_function.bin diff --git a/modules/optimization/macros/neldermead/nmplot_function.sci b/modules/optimization/macros/neldermead/nmplot_function.sci new file mode 100755 index 000000000..ef9c88689 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_function.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_function -- +// Call the cost function and return the value. +// Arguments +// x : the point where the function is to be evaluated. +// index : a flag to pass to the cost function (default = 1) +// f : the cost function +// +function [ this , f ] = nmplot_function ( this , x ) + [ this.nmbase , f ] = neldermead_function ( this.nmbase , x ) +endfunction diff --git a/modules/optimization/macros/neldermead/nmplot_get.bin b/modules/optimization/macros/neldermead/nmplot_get.bin Binary files differnew file mode 100755 index 000000000..4e99007ab --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_get.bin diff --git a/modules/optimization/macros/neldermead/nmplot_get.sci b/modules/optimization/macros/neldermead/nmplot_get.sci new file mode 100755 index 000000000..88c7b7066 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_get.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// nmplot_get -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// +function value = nmplot_get (this,key) + value = neldermead_get ( this.nmbase ); +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_historyplot.bin b/modules/optimization/macros/neldermead/nmplot_historyplot.bin Binary files differnew file mode 100755 index 000000000..4e61804c7 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_historyplot.bin diff --git a/modules/optimization/macros/neldermead/nmplot_historyplot.sci b/modules/optimization/macros/neldermead/nmplot_historyplot.sci new file mode 100755 index 000000000..f508c16a7 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_historyplot.sci @@ -0,0 +1,37 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_historyplot -- +// Plots the history from the given data file +// Arguments +// this : the current nmplot object +// datafile : the data file which contains the history +// mytitle , myxlabel , myylabel : the parameters of the plot +// +function nmplot_historyplot ( this , datafile , mytitle , myxlabel , myylabel ) + if (~isdef("datafile","local")) then + datafile = this.foptfn; + end + if (~isdef("mytitle","local")) then + mytitle = ""; + end + if (~isdef("myxlabel","local")) then + myxlabel = ""; + end + if (~isdef("myylabel","local")) then + myylabel = ""; + end + exec(datafile,-1); + nbiter = size ( history , 1 ) + plot2d ( history(1:nbiter,1) , history(1:nbiter,2) ) + xtitle(mytitle,myxlabel,myylabel) +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_log.bin b/modules/optimization/macros/neldermead/nmplot_log.bin Binary files differnew file mode 100755 index 000000000..5b719d21e --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_log.bin diff --git a/modules/optimization/macros/neldermead/nmplot_log.sci b/modules/optimization/macros/neldermead/nmplot_log.sci new file mode 100755 index 000000000..1ed9747f7 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_log.sci @@ -0,0 +1,18 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_log -- +// Prints the given message. +// +function this = nmplot_log (this,msg) + this.nmbase = neldermead_log ( this.nmbase , msg ) +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_new.bin b/modules/optimization/macros/neldermead/nmplot_new.bin Binary files differnew file mode 100755 index 000000000..1ed19e33b --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_new.bin diff --git a/modules/optimization/macros/neldermead/nmplot_new.sci b/modules/optimization/macros/neldermead/nmplot_new.sci new file mode 100755 index 000000000..63c628618 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_new.sci @@ -0,0 +1,32 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_new -- +// Creates a new Nelder - Mead plot object. +// +function newobj = nmplot_new () + newobj = tlist(["TNMPLOT",... + "simplexfn","fbarfn","foptfn","sigmafn","nmbase",... + "simplexhandle","fbarhandle","fopthandle","sigmahandle"]); + newobj.simplexfn = ""; + newobj.fbarfn = ""; + newobj.foptfn = ""; + newobj.sigmafn = ""; + newobj.simplexhandle = 0; + newobj.fbarhandle = 0; + newobj.fopthandle = 0; + newobj.sigmahandle = 0; + // + // Create and configure parent class + // + newobj.nmbase = neldermead_new(); +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_outputcmd.bin b/modules/optimization/macros/neldermead/nmplot_outputcmd.bin Binary files differnew file mode 100755 index 000000000..6dd65f0c8 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_outputcmd.bin diff --git a/modules/optimization/macros/neldermead/nmplot_outputcmd.sci b/modules/optimization/macros/neldermead/nmplot_outputcmd.sci new file mode 100755 index 000000000..e213eeacc --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_outputcmd.sci @@ -0,0 +1,64 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_outputcmd -- +// This command is called back by the Nelder-Mead +// algorithm. +// Arguments +// state : the current state of the algorithm +// "init", "iter", "done" +// data : the data at the current state +// This is a tlist with the following entries: +// * x : the optimal vector of parameters +// * fval : the minimum function value +// * simplex : the simplex, as a simplex object +// * iteration : the number of iterations performed +// * funccount : the number of function evaluations +// this : the current nmplot object +// stop: set to true when the algorithm must stop +// +function stop = nmplot_outputcmd ( state , data , this ) + nmplot_log ( this , "nmplot_outputcmd (1)") + iter = data.iteration + // Print simplex + x = optimsimplex_getallx ( data.simplex ) + if this.simplexfn <> "" then + nbve = optimsimplex_getnbve ( data.simplex ) + n = optimsimplex_getn ( data.simplex ) + mfprintf ( this.simplexhandle , "// Iteration #%d\n", iter ) + mfprintf ( this.simplexhandle , "history($+1) = [\n" ) + for ive = 1:nbve + mfprintf ( this.simplexhandle , "// Vertex #%d\n", ive ) + for ix = 1:n + mfprintf ( this.simplexhandle , "%e ", x(ive,ix)) + end + mfprintf ( this.simplexhandle , "\n") + end + mfprintf ( this.simplexhandle , "]\n" ) + end + // Function value average + if this.fbarfn <> "" then + fbar = optimsimplex_fvmean ( data.simplex ) + mfprintf ( this.fbarhandle , "%d %e\n", iter , fbar ) + end + // Minimum function value + if this.foptfn <> "" then + fopt = data.fval + mfprintf ( this.fopthandle , "%d %e\n", iter , fopt ) + end + // Sigma + if this.sigmafn <> "" then + sigma = optimsimplex_size ( data.simplex , "sigmaplus" ) + mfprintf ( this.sigmahandle , "%d %e\n", iter , sigma ) + end + stop = %f +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_restart.bin b/modules/optimization/macros/neldermead/nmplot_restart.bin Binary files differnew file mode 100755 index 000000000..7570d856b --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_restart.bin diff --git a/modules/optimization/macros/neldermead/nmplot_restart.sci b/modules/optimization/macros/neldermead/nmplot_restart.sci new file mode 100755 index 000000000..01f56013a --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_restart.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_restart -- +// Update the simplex and restart the search. +// +function this = nmplot_restart (this) + this.nmbase = neldermead_updatesimp ( this.nmbase ); + this = nmplot_search ( this ) +endfunction + + diff --git a/modules/optimization/macros/neldermead/nmplot_search.bin b/modules/optimization/macros/neldermead/nmplot_search.bin Binary files differnew file mode 100755 index 000000000..a35551afd --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_search.bin diff --git a/modules/optimization/macros/neldermead/nmplot_search.sci b/modules/optimization/macros/neldermead/nmplot_search.sci new file mode 100755 index 000000000..44f25e040 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_search.sci @@ -0,0 +1,122 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_search -- +// Search the minimum with Nelder-Mead algorithm. +// +function this = nmplot_search (this) + nmplot_log ( this , "nmplot_search") + this = nmplot_startupfiles ( this ) + this.nmbase = neldermead_configure ( this.nmbase , "-outputcommand" , list(nmplot_outputcmd,this) ); + this.nmbase = neldermead_search ( this.nmbase ) + this = nmplot_shutdownfiles ( this ) +endfunction + + +// +// nmplot_header -- +// Returns a header for the output files +// Arguments +// filename : the target file name +// name : the type of data in the file +// +function report = nmplot_header ( this , filename , name ) + nmplot_log ( this , "nmplot_header") + report = list() + report($+1) = sprintf("//\n") + report($+1) = sprintf("// %s--\n" , filename) + report($+1) = sprintf("// History of the %s during Nelder-Mead algorithm.\n",name) + report($+1) = sprintf("//\n") + report($+1) = sprintf("// Copyright (C) 2008-2009 - INRIA - Michael Baudin\n") + report($+1) = sprintf("//\n") +endfunction + +// +// nmplot_startupfiles -- +// Opens the output files to prepare the algorithm +// execution. +// Arguments +// <no arg> +// +function this = nmplot_startupfiles ( this ) + nmplot_log ( this , "nmplot_startupfiles") + if this.simplexfn <> "" then + this.simplexhandle = mopen ( this.simplexfn , "w" ) + header = nmplot_header ( this , this.simplexfn , "simplex" ) + fd = this.simplexhandle + for i = 1:length(header) + mfprintf(fd,"%s\n",header(i)) + end + mfprintf(fd,"history = list()\n") + end + if this.fbarfn <> "" then + this.fbarhandle = mopen ( this.fbarfn , "w" ) + header = nmplot_header ( this , this.fbarfn , "function value average" ) + fd = this.fbarhandle + for i = 1:length(header) + mfprintf(fd,"%s\n",header(i)) + end + mfprintf(fd,"history = [\n") + end + if this.foptfn <> "" then + this.fopthandle = mopen ( this.foptfn , "w" ) + header = nmplot_header ( this , this.foptfn , "function value optimum" ) + fd = this.fopthandle + for i = 1:length(header) + mfprintf(fd,"%s\n",header(i)) + end + mfprintf(fd,"history = [\n") + end + if this.sigmafn <> "" then + this.sigmahandle = mopen ( this.sigmafn , "w" ) + header = nmplot_header ( this , this.sigmafn , "maximum of oriented length" ) + fd = this.sigmahandle + for i = 1:length(header) + mfprintf(fd,"%s\n",header(i)) + end + mfprintf(fd,"history = [\n") + end +endfunction + +// +// nmplot_shutdownfiles -- +// Close the output files to shutdown the algorithm +// execution. +// Arguments +// <no arg> +// +function this = nmplot_shutdownfiles ( this ) + nmplot_log ( this , "nmplot_shutdownfiles") + if this.simplexfn <> "" then + fd = this.simplexhandle + mclose ( fd ) + nmplot_log ( this , sprintf( "Exported Simplex history in %s",this.simplexfn)) + end + if this.fbarfn <> "" then + fd = this.fbarhandle + mfprintf ( fd , "]\n" ) + mclose ( fd ) + nmplot_log ( this , sprintf( "Exported fbar history in %s",this.fbarfn)) + end + if this.foptfn <> "" then + fd = this.fopthandle + mfprintf ( fd , "]\n" ) + mclose ( fd ) + nmplot_log ( this , sprintf( "Exported fopt history in %s",this.foptfn)) + end + if this.sigmafn <> "" then + fd = this.sigmahandle + mfprintf ( fd , "]\n" ) + mclose ( fd ) + nmplot_log ( this , sprintf( "Exported sigma history in %s",this.sigmafn)) + end +endfunction + diff --git a/modules/optimization/macros/neldermead/nmplot_simplexhistory.bin b/modules/optimization/macros/neldermead/nmplot_simplexhistory.bin Binary files differnew file mode 100755 index 000000000..ec29f7950 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_simplexhistory.bin diff --git a/modules/optimization/macros/neldermead/nmplot_simplexhistory.sci b/modules/optimization/macros/neldermead/nmplot_simplexhistory.sci new file mode 100755 index 000000000..5e6b8eef4 --- /dev/null +++ b/modules/optimization/macros/neldermead/nmplot_simplexhistory.sci @@ -0,0 +1,46 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// nmplot_simplexhistory -- +// Plots the simplex history on the current graphic window. +// Arguments +// this : the current nmplot object +// +function nmplot_simplexhistory ( this , colorforeground , markforeground , markstyle ) + drawlater(); + if (~isdef("foregroundcolor","local")) then + colorforeground = 5; + end + if (~isdef("markforeground","local")) then + markforeground = 3; + end + if (~isdef("markstyle","local")) then + markstyle = 9; + end + exec(this.simplexfn,-1); + nbiter = length ( history ) + n = neldermead_cget ( this.nmbase , "-numberofvariables" ) + for iter = 1:nbiter + simplex = history(iter) + xcoords = simplex(1:n+1,1) + ycoords = simplex(1:n+1,2) + plot2d ( xcoords , ycoords ) + end + f = gcf() + for iter = 1:nbiter + f.children(1).children(iter).children.foreground = colorforeground; + f.children(1).children(iter).children.mark_foreground = markforeground + f.children(1).children(iter).children.mark_style = markstyle; + f.children(1).children(iter).children.closed = "on"; + end + drawnow(); +endfunction + diff --git a/modules/optimization/macros/neldermead/optimget.bin b/modules/optimization/macros/neldermead/optimget.bin Binary files differnew file mode 100755 index 000000000..effda2e98 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimget.bin diff --git a/modules/optimization/macros/neldermead/optimget.sci b/modules/optimization/macros/neldermead/optimget.sci new file mode 100755 index 000000000..840b7cbc6 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimget.sci @@ -0,0 +1,61 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimget -- +// Queries an optimization structure. +// The key is searched in the list of existing fields, +// ignoring the case. +// Only leading characters of the field name are sufficient to +// make the search successful. +// Usage: +// val = optimget ( options , key ) +// val = optimset ( options , key , value ) +// +function val = optimget (varargin) + [lhs,rhs]=argn(); + if rhs<=1 | rhs >=4 then + errmsg = error(msprintf(gettext("%s: Wrong number of arguments : %d expected while %d given"),"optimget", 2,rhs)); + error(errmsg); + end + options = varargin(1); + // Search the field by index + key = varargin(2); + fields = [ + "Display" + "FunValCheck" + "MaxFunEvals" + "MaxIter" + "OutputFcn" + "PlotFcns" + "TolFun" + "TolX" + ]; + // Search for the given key in the list of available fields. + // Use a regexp which ignores the case. + regstr = "/" + key + "/i"; + [r,w] = grep ( fields , regstr , "r" ); + opsize = size(r,2) + if opsize<>1 then + matching = strcat(fields(r(1:opsize))," "); + errmsg = error(msprintf(gettext("%s: Ambiguous property name %s matches several fields : %s"),"optimget", key , matching)); + error(errmsg); + end + // Get the matching field + name = fields(r(1)); + val = options(name); + // When the value is given and the field is empty, return the value. + if rhs==3 then + if val == [] then + val = varargin(3) + end + end +endfunction + diff --git a/modules/optimization/macros/neldermead/optimplotfunccount.bin b/modules/optimization/macros/neldermead/optimplotfunccount.bin Binary files differnew file mode 100755 index 000000000..5d7b46484 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotfunccount.bin diff --git a/modules/optimization/macros/neldermead/optimplotfunccount.sci b/modules/optimization/macros/neldermead/optimplotfunccount.sci new file mode 100755 index 000000000..d8fc56d90 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotfunccount.sci @@ -0,0 +1,63 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimplotfunccount -- +// Emulate the optimplotfunccount command of Matlab. +// Plot the function value during an optimization process. +// Arguments, input +// x : the current point +// optimValues : a tlist which contains the following fields +// funcCount : the number of function evaluations +// fval : the current function value +// iteration : the current iteration +// procedure : a string containing the current type of step +// state : the current state of the algorithm +// "init", "iter", "done" +// Notes: +// The algorithm is the following. +// At initialization of the algorithm, create an empty +// graphic plot, retrieve the handle, and store a special +// key "optimplotfunccount" in the user_data field of the handle. +// When the plot is to update, this key is searched so that the +// correct plot can be update (and not another). +// +function optimplotfunccount ( x , optimValues , state ) + if ( state == "init" ) then + opfvh = scf(); + plot ( 0 , optimValues.funccount ); + opfvh.user_data = "optimplotfunccount"; + opfvh.children.x_label.text = "Iteration"; + opfvh.children.y_label.text = "Function evaluations"; + opfvh.children.title.text = msprintf ( "Total Function Evaluations: %d", optimValues.funccount ) + opfvh.children.children.children.mark_mode = "on"; + opfvh.children.children.children.mark_style = 5; + opfvh.children.children.children.mark_size = 10; + opfvh.children.children.children.mark_background = 6; + else + opfvh = findobj ( "user_data" , "optimplotfunccount" ); + gg = opfvh.children.children; + // Update data + gg.children.data($+1,1:2) = [optimValues.iteration optimValues.funccount]; + // Compute new bounds + itermin = 0; + itermax = optimValues.iteration; + fmin = min(gg.children.data(:,2)); + fmax = max(gg.children.data(:,2)); + // Update bounds + opfvh.children.data_bounds = [ + itermin fmin + itermax fmax + ]; + // Update title + opfvh.children.title.text = msprintf ( "Total Function Evaluations: %d", optimValues.funccount ) + end +endfunction + diff --git a/modules/optimization/macros/neldermead/optimplotfval.bin b/modules/optimization/macros/neldermead/optimplotfval.bin Binary files differnew file mode 100755 index 000000000..be9871025 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotfval.bin diff --git a/modules/optimization/macros/neldermead/optimplotfval.sci b/modules/optimization/macros/neldermead/optimplotfval.sci new file mode 100755 index 000000000..75df19aee --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotfval.sci @@ -0,0 +1,63 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimplotfval -- +// Emulate the optimplotfval command of Matlab. +// Plot the function value during an optimization process. +// Arguments, input +// x : the current point +// optimValues : a tlist which contains the following fields +// funcCount" : the number of function evaluations +// fval : the current function value +// iteration : the current iteration +// procedure : a string containing the current type of step +// state : the current state of the algorithm +// "init", "iter", "done" +// Notes: +// The algorithm is the following. +// At initialization of the algorithm, create an empty +// graphic plot, retrieve the handle, and store a special +// key "optimplotfval" in the user_data field of the handle. +// When the plot is to update, this key is searched so that the +// correct plot can be update (and not another). +// +function optimplotfval ( x , optimValues , state ) + if ( state == "init" ) then + opfvh = scf(); + plot ( 0 , optimValues.fval ); + opfvh.user_data = "optimplotfval"; + opfvh.children.x_label.text = "Iteration"; + opfvh.children.y_label.text = "Function value"; + opfvh.children.title.text = msprintf ( "Current Function Value: %e", optimValues.fval ) + opfvh.children.children.children.mark_mode = "on"; + opfvh.children.children.children.mark_style = 5; + opfvh.children.children.children.mark_size = 10; + opfvh.children.children.children.mark_background = 6; + else + opfvh = findobj ( "user_data" , "optimplotfval" ); + gg = opfvh.children.children; + // Update data + gg.children.data($+1,1:2) = [optimValues.iteration optimValues.fval]; + // Compute new bounds + itermin = 0; + itermax = optimValues.iteration; + fmin = min(gg.children.data(:,2)); + fmax = max(gg.children.data(:,2)); + // Update bounds + opfvh.children.data_bounds = [ + itermin fmin + itermax fmax + ]; + // Update title + opfvh.children.title.text = msprintf ( "Current Function Value: %e", optimValues.fval ) + end +endfunction + diff --git a/modules/optimization/macros/neldermead/optimplotx.bin b/modules/optimization/macros/neldermead/optimplotx.bin Binary files differnew file mode 100755 index 000000000..ff02fcdda --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotx.bin diff --git a/modules/optimization/macros/neldermead/optimplotx.sci b/modules/optimization/macros/neldermead/optimplotx.sci new file mode 100755 index 000000000..6fa7ac6f8 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimplotx.sci @@ -0,0 +1,73 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimplotx -- +// Emulate the optimplotfx command of Matlab. +// Plot the function value during an optimization process. +// Arguments, input +// x : the current point +// optimValues : a tlist which contains the following fields +// funcCount" : the number of function evaluations +// fval : the current function value +// iteration : the current iteration +// procedure : a string containing the current type of step +// state : the current state of the algorithm +// "init", "iter", "done" +// Notes: +// The algorithm is the following. +// At initialization of the algorithm, create an empty +// graphic plot, retrieve the handle, and store a special +// key "optimplotfx" in the user_data field of the handle. +// When the plot is to update, this key is searched so that the +// correct plot can be update (and not another). +// +function optimplotx ( x , optimValues , state ) + if ( state == "init" ) then + // Initialize + opfvh = scf(); + nbvar = length(x) + bar ( 1:nbvar , x ); + gg = gce(); + gg.children.background = 9; + opfvh.user_data = "optimplotx"; + opfvh.children.x_label.text = msprintf ( "Number of variables: %d" , nbvar ); + opfvh.children.y_label.text = "Current point"; + opfvh.children.title.text = msprintf ( "Current Point" ); + else + opfvh = findobj ( "user_data" , "optimplotx" ); + nbvar = length(x) + gg = opfvh.children.children; + for ivar = 1:nbvar + gg.children.data(ivar,2) = x(ivar); + end + xmin = 0; + ymin = min(x); + xmax = nbvar+1; + ymax = max(x); + // A small trick, for a nicer display + if ( ( ymin > 0.0 ) & ( ymax > 0.0 ) ) then + ymin = 0.0 + elseif ( ( ymin < 0.0 ) & ( ymax < 0.0 ) ) then + ymax = 0.0 + end + if ( ymax > 0 ) then + ymax = ymax * 1.1 + end + if ( ymin < 0 ) then + ymin = ymin * 1.1 + end + opfvh.children.data_bounds = [ + xmin ymin + xmax ymax + ]; + end +endfunction + diff --git a/modules/optimization/macros/neldermead/optimset.bin b/modules/optimization/macros/neldermead/optimset.bin Binary files differnew file mode 100755 index 000000000..5538bc7e0 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimset.bin diff --git a/modules/optimization/macros/neldermead/optimset.sci b/modules/optimization/macros/neldermead/optimset.sci new file mode 100755 index 000000000..e388210f7 --- /dev/null +++ b/modules/optimization/macros/neldermead/optimset.sci @@ -0,0 +1,161 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimset -- +// Configures and returns an optimization data structure. +// Usage: +// options = optimset () +// options = optimset ( funname ) +// options = optimset ( key , value ) +// options = optimset ( key1 , value1 , key2 , value2 , ... ) +// options = optimset ( options , key , value ) +// options = optimset ( options , key1 , value1 , key2 , value2 , ... ) +// +function options = optimset (varargin) + [lhs,rhs]=argn(); + if rhs == 0 then + options = optimset_new (); + return + elseif rhs==1 then + // + // options = optimset ( funname ) + // If there is only one argument, it is expected to be the + // name of a method. + // + method = varargin(1); + options = optimset_method ( method ); + return + end + // Set the options variable + if modulo(rhs,2)<>0 then + // + // options = optimset ( options , key , value ) + // options = optimset ( options , key1 , value1 , key2 , value2 , ... ) + // If the number of arguments is odd, + // the first argument is expected to be an optimset struct. + // + options = varargin(1); + t1 = typeof(options); + if t1<>"st" then + errmsg = msprintf(gettext("%s: Odd number of arguments : the first argument is expected to be a struct, but is a %s"), "optimset", t1); + error(errmsg) + end + else + // options = optimset ( key , value ) + // options = optimset ( key1 , value1 , key2 , value2 , ... ) + // Number of input argument is even. + options = optimset_new (); + end + // Set ivar : index of input variable. + // The variable ivar allows to make a loop over input arguments. + if ( modulo(rhs,2)<>0 ) then + ivar = 1; + else + ivar = 0; + end + // + // Process key,values as pairs. + // + nbkeys = rhs/2; + for i=1:nbkeys + ivar = ivar + 1; + key = varargin(ivar); + ivar = ivar + 1; + // Use funcprot to enable the set of a function into the variable "value". + // If not, a warning message is triggered, when a double value + // is stored into "value" after a function has already been + // stored in it. + prot = funcprot(); + funcprot(0); + value = varargin(ivar); + funcprot(prot); + options = optimset_configure (options,key,value); + end +endfunction +// +// optimset_configure -- +// Configure the given key with the given value. +// Arguments +// options : an optimset struct +// key : a string, the key to configure +// value : the value +// +function options = optimset_configure ( options , key , value ) + select key + case "Display" then + if ( ... + ( value == "off" ) | ... + ( value == "iter" ) | ... + ( value == "final" ) | ... + ( value == "notify" ) ... + ) then + options.Display = value; + else + errmsg = msprintf(gettext("%s: Unrecognized value ''%s'' for ''Display'' option."), "optimset", value ) + error(errmsg) + end + case "FunValCheck" then + options.FunValCheck = value; + case "MaxFunEvals" then + options.MaxFunEvals = value; + case "MaxIter" then + options.MaxIter = value; + case "OutputFcn" then + options.OutputFcn = value; + case "PlotFcns" then + options.PlotFcns = value; + case "TolFun" then + options.TolFun = value; + case "TolX" then + options.TolX = value; + else + errmsg = msprintf(gettext("%s: Unrecognized parameter name ''%s''."), "optimset", key) + error(errmsg) + end +endfunction +// +// optimset_new -- +// Returns an empty optimset struct +// +function options = optimset_new () + options = struct(... + "Display" ,[],... + "FunValCheck" ,[],... + "MaxFunEvals" ,[],... + "MaxIter" ,[],... + "OutputFcn" ,[],... + "PlotFcns" ,[],... + "TolFun" ,[],... + "TolX" ,[]... + ); +endfunction +// +// optimset_method -- +// Returns an optimset struct which content is the default +// settings for the given method. +// Arguments +// method : a string, the name of the method +// +function options = optimset_method ( method ) + options = optimset_new (); + select method + case "fminsearch" then + options = optimset_configure ( options , "Display" , "notify" ); + options = optimset_configure ( options , "MaxFunEvals" , "200*numberofvariables" ); + options = optimset_configure ( options , "MaxIter" , "200*numberofvariables" ); + options = optimset_configure ( options , "TolFun" , 1.e-4 ); + options = optimset_configure ( options , "TolX" , 1.e-4 ); + else + errmsg = msprintf(gettext("%s: No default options available: the function ''%s'' does not exist on the path."), "optimset", method) + error(errmsg) + end +endfunction + diff --git a/modules/optimization/macros/numderivative.bin b/modules/optimization/macros/numderivative.bin Binary files differnew file mode 100755 index 000000000..df85e310a --- /dev/null +++ b/modules/optimization/macros/numderivative.bin diff --git a/modules/optimization/macros/numderivative.sci b/modules/optimization/macros/numderivative.sci new file mode 100755 index 000000000..dc630f3fd --- /dev/null +++ b/modules/optimization/macros/numderivative.sci @@ -0,0 +1,353 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) ? - 2008 - Rainer von Seggern +// Copyright (C) ? - 2008 - Bruno Pincon +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2010-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function [J, H] = numderivative(varargin) + // + // Check input arguments + [lhs, rhs] = argn(); + if (rhs < 2 | rhs > 6) then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"), "numderivative", 2, 6)); + end + if (lhs < 1 | lhs > 2) then + error(msprintf(gettext("%s: Wrong number of output arguments: %d to %d expected.\n"), "numderivative", 1, 2)); + end + // + // Get input arguments + __numderivative_f__ = varargin(1) + if and(type(__numderivative_f__) <> [11 13 15 130]) then + // Must be a function (uncompiled or compiled) or a list + error(msprintf(gettext("%s: Wrong type for argument #%d: Function or list expected.\n"), "numderivative", 1)); + end + if type(__numderivative_f__) == 15 then + // List case + // Check that the first element in the list is a function + if and(type(__numderivative_f__(1)) <> [11 13]) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Function expected in first element of list.\n"), "numderivative", 1)); + end + if length(__numderivative_f__) < 2 then + error(msprintf(gettext("%s: Wrong number of elements in input argument #%d: At least %d elements expected, but current number is %d.\n"), "numderivative", 1, 2, length(__numderivative_f__))); + end + end + + // + // Manage x, to get the size n. + x = varargin(2); + if type(x) ~= 1 then + error(msprintf(gettext("%s: Wrong type for argument #%d: Matrix expected.\n"), "numderivative", 2)); + end + [n, p] = size(x); + if (n <> 1 & p <> 1) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Vector expected.\n"), "numderivative", 2)); + end + // Make x a column vector, if required + if p <> 1 then + x = x(:); + [n, p] = size(x); + end + // + // Manage h: make it a column vector, if required. + h = []; + if rhs >= 3 then + h = varargin(3); + if type(h) ~= 1 then + error(msprintf(gettext("%s: Wrong type for argument #%d: Matrix expected.\n"), "numderivative", 3)); + end + if h <> [] then + if size(h, "*") <> 1 then + [nrows, ncols] = size(h); + if (nrows <> 1 & ncols <> 1) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Vector expected.\n"), "numderivative", 3)); + end + if ncols <> 1 then + h = h(:); + end + if or(size(h) <> [n 1]) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"), "numderivative", 3, 1)); + end + end + if or(h < 0) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be > %d.\n"), "numderivative", 3, 0)); + end + end + end + + order = 2; + if (rhs >= 4 & varargin(4) <> []) then + order = varargin(4); + if type(order) ~= 1 then + error(msprintf(gettext("%s: Wrong type for argument #%d: Matrix expected.\n"), "numderivative", 4)); + end + if or(size(order) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), "numderivative", 4, 1, 1)); + end + if and(order <> [1 2 4]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "numderivative", 4, "1, 2, 4")); + end + end + + H_form = "default"; + if (rhs >= 5 & varargin(5) <> []) then + H_form = varargin(5); + if type(H_form) ~= 10 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"), "numderivative", 5)); + end + if or(size(H_form) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), "numderivative", 5, 1, 1)); + end + if and(H_form <> ["default" "blockmat" "hypermat"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "numderivative", 5, "default, blockmat, hypermat")); + end + end + + Q = eye(n, n); + Q_not_given = %t; + if (rhs >= 6 & varargin(6) <> []) then + Q = varargin(6); + Q_not_given = %f; + if type(Q) ~= 1 then + error(msprintf(gettext("%s: Wrong type for argument #%d: Matrix expected.\n"), "numderivative", 6)); + end + if or(size(Q) <> [n n]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), "numderivative", 6, n ,n)); + end + if norm(clean(Q*Q'-eye(n, n))) > 0 then + error(msprintf(gettext("%s: Q must be orthogonal.\n"), "numderivative")); + end + end + + // + // Proceed... + if h == [] then + h_not_given = %t; + else + h_not_given = %f; + // If h is scalar, expand to the same size as x. + if size(h) == [1 1] then + h = h * ones(x); + end + end + // + // Compute Jacobian + if ( h_not_given ) then + h = numderivative_step(x, order, 1); + end + J = numderivative_deriv1(__numderivative_f__, x, h, order, Q); + // + // Quick return if possible + if lhs == 1 then + return + end + + m = size(J, 1); + // + // Compute Hessian matrix + if ( h_not_given ) then + h = numderivative_step(x, order, 2); + end + funForHList = list(numderivative_funForH, __numderivative_f__, h, order, Q); + if ~Q_not_given then + H = numderivative_deriv1(funForHList, x, h, order, Q); + else + H = numderivative_deriv2(funForHList, x, h, order, Q); + end + // + // At this point, H is a m*n-by-n block matrix. + // Update the format of the Hessian + if H_form == "default" then + // H has the old scilab form + H = matrix(H', n*n, m)' + end + if H_form == "hypermat" then + if m > 1 then + // H is a hypermatrix if m > 1 + H = H'; + H = hypermat([n n m], H(:)); + end + end +endfunction + +// +// numderivative_step -- +// Returns the step for given x, given order and given derivative: +// d = 1 is for Jacobian +// d = 2 is for Hessian +// Uses the optimal step. +// Then scale the step depending on abs(x). +function h = numderivative_step(x, order, d) + n = size(x, "*"); + select d + case 1 + // For Jacobian + select order + case 1 + hdefault = sqrt(%eps); + case 2 + hdefault = %eps^(1/3); + case 4 + hdefault = %eps^(1/5); + else + lclmsg = gettext("%s: Unknown value %s for option %s.\n"); + error(msprintf(lclmsg,"numderivative_step", string(d), "d")); + end + case 2 + // For Hessian + select order + case 1 + hdefault = %eps^(1/3); + case 2 + hdefault = %eps^(1/4); + case 4 + hdefault = %eps^(1/6); + else + lclmsg = gettext("%s: Unknown value %s for option %s.\n"); + error(msprintf(lclmsg, "numderivative_step", string(d), "d")); + end + else + lclmsg = gettext("%s: Unknown value %s for option %s.\n"); + error(msprintf(lclmsg, "numderivative_step", string(order), "order")); + end + // Convert this scalar into a vector, with same size as x + // For zero entries in x, use the default. + // For nonzero entries in x, scales by abs(x). + h = hdefault * abs(x); + h(x==0) = hdefault; +endfunction + +// +// numderivative_funForH -- +// Returns the numerical derivative of __numderivative_f__. +// This function is called to compute the numerical Hessian. +function J = numderivative_funForH(x, __numderivative_f__, h, order, Q) + // Transpose ! + J = numderivative_deriv1(__numderivative_f__, x, h, order, Q)'; + J = J(:); +endfunction + +// numderivative_deriv1 -- +// Computes the numerical gradient of __numderivative_f__, using the given step h. +// This function is used for the computation of the jacobian matrix. +function g = numderivative_deriv1(__numderivative_f__, x, h, order, Q) + n = size(x, "*"); + %Dy = []; // At this point, we do not know 'm' yet, so we cannot allocate Dy. + select order + case 1 + D = Q * diag(h); + y = numderivative_evalf(__numderivative_f__, x); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + Dyi = (yplus-y)/h(i); + %Dy = [%Dy Dyi]; + end + g = %Dy*Q'; + case 2 + D = Q * diag(h); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + yminus = numderivative_evalf(__numderivative_f__, x-d); + Dyi = (yplus-yminus)/(2*h(i)); + %Dy = [%Dy Dyi]; + end + g = %Dy*Q'; + case 4 + D = Q * diag(h); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + yminus = numderivative_evalf(__numderivative_f__, x-d); + yplus2 = numderivative_evalf(__numderivative_f__, x+2*d); + yminus2 = numderivative_evalf(__numderivative_f__, x-2*d); + dFh = (yplus-yminus)/(2*h(i)); + dF2h = (yplus2-yminus2)/(4*h(i)); + Dyi = (4*dFh - dF2h)/3; + %Dy = [%Dy Dyi]; + end + g = %Dy*Q'; + end +endfunction + +// numderivative_deriv2 -- +// Computes the numerical gradient of the argument __numderivative_f__, using the given step h. +// This function is used for the computation of the hessian matrix, to take advantage of its symmetry +function g = numderivative_deriv2(__numderivative_f__, x, h, order, Q) + n = size(x, "*"); + %Dy = zeros(m*n, n); // 'm' is known at this point, so we can allocate Dy to reduce memory operations + select order + case 1 + D = Q * diag(h); + y = numderivative_evalf(__numderivative_f__, x); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + for j=0:m-1 + Dyi(1+j*n:i-1+j*n) = %Dy(i+j*n, 1:i-1)'; // Retrieving symmetric elements (will not be done for the first vector) + Dyi(i+j*n:(j+1)*n) = (yplus(i+j*n:(j+1)*n)-y(i+j*n:(j+1)*n))/h(i); // Computing the new ones + end + %Dy(:, i) = Dyi; + end + g = %Dy*Q'; + case 2 + D = Q * diag(h); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + yminus = numderivative_evalf(__numderivative_f__, x-d); + for j=0:m-1 + Dyi(1+j*n:i-1+j*n) = %Dy(i+j*n, 1:i-1)'; // Retrieving symmetric elements (will not be done for the first vector) + Dyi(i+j*n:(j+1)*n) = (yplus(i+j*n:(j+1)*n)-yminus(i+j*n:(j+1)*n))/(2*h(i)); // Computing the new ones + end + %Dy(:, i) = Dyi; + end + g = %Dy*Q'; + case 4 + D = Q * diag(h); + for i=1:n + d = D(:, i); + yplus = numderivative_evalf(__numderivative_f__, x+d); + yminus = numderivative_evalf(__numderivative_f__, x-d); + yplus2 = numderivative_evalf(__numderivative_f__, x+2*d); + yminus2 = numderivative_evalf(__numderivative_f__, x-2*d); + for j=0:m-1 + dFh(1+j*n:i-1+j*n) = %Dy(i+j*n, 1:i-1)'; // Retrieving symmetric elements (will not be done for the first vector) + dFh(i+j*n:(j+1)*n) = (yplus(i+j*n:(j+1)*n)-yminus(i+j*n:(j+1)*n))/(2*h(i)); // Computing the new ones + dF2h(1+j*n:i-1+j*n) = %Dy(i+j*n, 1:i-1)'; // Retrieving symmetric elements (will not be done for the first vector) + dF2h(i+j*n:(j+1)*n) = (yplus2(i+j*n:(j+1)*n)-yminus2(i+j*n:(j+1)*n))/(4*h(i)); // Computing the new ones + end + Dyi = (4*dFh - dF2h)/3; + %Dy(:, i) = Dyi; + end + g = %Dy*Q'; + end +endfunction + +// numderivative_evalf -- +// Computes the value of __numderivative_f__ at the point x. +// The argument __numderivative_f__ can be a function (macro or linked code) or a list. +function y = numderivative_evalf(__numderivative_f__, x) + if type(__numderivative_f__) == 15 then + // List case + __numderivative_fun__ = __numderivative_f__(1); + instr = "y = __numderivative_fun__(x, __numderivative_f__(2:$))"; + elseif or(type(__numderivative_f__) == [11 13 130]) then + // Function case + instr = "y = __numderivative_f__(x)"; + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: A function expected.\n"), "numderivative", 1)); + end + ierr = execstr(instr, "errcatch") + if ierr <> 0 then + lamsg = lasterror(); + lclmsg = "%s: Error while evaluating the function: ""%s""\n"; + error(msprintf(gettext(lclmsg), "numderivative", lamsg)); + end +endfunction diff --git a/modules/optimization/macros/numdiff.bin b/modules/optimization/macros/numdiff.bin Binary files differnew file mode 100755 index 000000000..a177f26f7 --- /dev/null +++ b/modules/optimization/macros/numdiff.bin diff --git a/modules/optimization/macros/numdiff.sci b/modules/optimization/macros/numdiff.sci new file mode 100755 index 000000000..53cc4daf4 --- /dev/null +++ b/modules/optimization/macros/numdiff.sci @@ -0,0 +1,50 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function %g=numdiff(%__func,%x,%dx) + warnobsolete("numderivative","6.0") + // given a function %__func from R^n to R^p + //computes the matrix g such as + // [ d f ] + // [ i ] + //g = [ ---- ] + // ij [ d x ] + // [ j ] + // using finite difference methods + if type(%__func)==15 then + params=%__func;params(1)=null(); + %__func=%__func(1) + else + params=list() + end + if type(%__func)==10 then //hard coded function given by its name + error(msprintf(gettext("%s: Hard coded function not allowed, create a Scilab function using call."),"numdiff")); + end + + %x=%x(:); + %n=size(%x,"*") + if argn(2)<3 then + %dx=sqrt(%eps)*(1+1d-3*abs(%x)) + end + if size(params)==0 then + %y0=%__func(%x) + %g(size(%y0,1),%n)=0 + for %j=1:%n + %v=0*%x;%v(%j)=%dx(%j); + %g(:,%j)=(-%y0+%__func(%x+%v))/%dx(%j); + end + else + %y0=%__func(%x,params(:)) + %g(size(%y0,1),%n)=0 + for %j=1:%n + %v=0*%x;%v(%j)=%dx(%j); + %g(:,%j)=(-%y0+%__func(%x+%v,params(:)))/%dx(%j); + end + end +endfunction diff --git a/modules/optimization/macros/optimbase/%TOPTIM_p.bin b/modules/optimization/macros/optimbase/%TOPTIM_p.bin Binary files differnew file mode 100755 index 000000000..bdc92b91e --- /dev/null +++ b/modules/optimization/macros/optimbase/%TOPTIM_p.bin diff --git a/modules/optimization/macros/optimbase/%TOPTIM_p.sci b/modules/optimization/macros/optimbase/%TOPTIM_p.sci new file mode 100755 index 000000000..e1b6fc30c --- /dev/null +++ b/modules/optimization/macros/optimbase/%TOPTIM_p.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TOPTIM_p -- +// Prints the string containing the Optim Base component. +// +function %TOPTIM_p ( this ) + str = string ( this ) + srows = size(str,"r") + for i = 1 : srows + mprintf("%s\n",str(i)) + end +endfunction + diff --git a/modules/optimization/macros/optimbase/%TOPTIM_string.bin b/modules/optimization/macros/optimbase/%TOPTIM_string.bin Binary files differnew file mode 100755 index 000000000..4b044a2e6 --- /dev/null +++ b/modules/optimization/macros/optimbase/%TOPTIM_string.bin diff --git a/modules/optimization/macros/optimbase/%TOPTIM_string.sci b/modules/optimization/macros/optimbase/%TOPTIM_string.sci new file mode 100755 index 000000000..35c0dc4b4 --- /dev/null +++ b/modules/optimization/macros/optimbase/%TOPTIM_string.sci @@ -0,0 +1,79 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TOPTIM_string -- +// Returns the string containing the Optim Base component. +// +function str = %TOPTIM_string ( this ) + str = [] + k = 1 + str(k) = sprintf("Optim Base Object:\n") + k = k + 1 + str(k) = sprintf("==================") + k = k + 1 + str(k) = sprintf("Number of variables : %s\n", string(this.numberofvariables)); + k = k + 1 + x0 = optimbase_cget (this,"-x0") + str(k) = sprintf("Initial Guess : [%s]\n" , _strvec(x0) ); + k = k + 1 + str(k) = sprintf("Initial Function Value :%s\n",_strvec(this.fx0)); + k = k + 1 + str(k) = sprintf("Number of Inequality Constraints :%d\n",this.nbineqconst); + k = k + 1 + str(k) = sprintf("Bounds Mininimum : [%s]\n", _strvec(this.boundsmin)); + k = k + 1 + str(k) = sprintf("Bounds Maxinimum :[%s]\n", _strvec(this.boundsmax)); + k = k + 1 + str(k) = sprintf("Optimum Parameters : [%s]\n" , _strvec(this.xopt)); + k = k + 1 + str(k) = sprintf("Optimum Function Value :%s\n",string(this.fopt)); + k = k + 1 + str(k) = sprintf("Number of iterations : %d\n", this.iterations); + k = k + 1 + str(k) = sprintf("Maximum number of iterations : %s\n", string(this.maxiter)); + k = k + 1 + str(k) = sprintf("Number function evaluations : %d\n", this.funevals); + k = k + 1 + str(k) = sprintf("Maximum number of function evaluations : %s\n", string(this.maxfunevals)); + k = k + 1 + str(k) = sprintf("Termination Method on function value : %s\n", string(this.tolfunmethod)); + k = k + 1 + str(k) = sprintf("Termination Absolute Tolerance on function value : %s\n", string(this.tolfunabsolute)); + k = k + 1 + str(k) = sprintf("Termination Relative Tolerance on function value : %s\n", string(this.tolfunrelative)); + k = k + 1 + str(k) = sprintf("Termination Method on x : %s\n", string(this.tolxmethod)); + k = k + 1 + str(k) = sprintf("Termination Absolute Tolerance on x : %s\n", string(this.tolxabsolute)); + k = k + 1 + str(k) = sprintf("Termination Relative Tolerance on x : %s\n", string(this.tolxrelative)); + k = k + 1 + str(k) = sprintf("Optimization Status : %s\n", this.status); + k = k + 1 + str(k) = sprintf("Verbose logging : %s\n", string(this.verbose)); + k = k + 1 + str(k) = sprintf("Verbose Termination : %s\n", string(this.verbosetermination)); + k = k + 1 + str(k) = sprintf("Verbose Log File : %s\n", this.logfile ); + k = k + 1 + str(k) = sprintf("Verbose Log File Startup Up: %s\n", string(this.logstartup) ); + k = k + 1 + str(k) = sprintf("Store History : %s\n", string(this.storehistory)); +endfunction + +// +// _strvec -- +// Returns a string for the given vector. +// +function str = _strvec ( x ) + str = strcat(string(x)," ") +endfunction + + diff --git a/modules/optimization/macros/optimbase/lib b/modules/optimization/macros/optimbase/lib Binary files differnew file mode 100755 index 000000000..310678186 --- /dev/null +++ b/modules/optimization/macros/optimbase/lib diff --git a/modules/optimization/macros/optimbase/names b/modules/optimization/macros/optimbase/names new file mode 100755 index 000000000..a1a02724d --- /dev/null +++ b/modules/optimization/macros/optimbase/names @@ -0,0 +1,29 @@ +%TOPTIM_p +%TOPTIM_string +optimbase_cget +optimbase_checkbounds +optimbase_checkcostfun +optimbase_checkx0 +optimbase_configure +optimbase_destroy +optimbase_function +optimbase_get +optimbase_hasbounds +optimbase_hasconstraints +optimbase_hasnlcons +optimbase_histget +optimbase_histset +optimbase_incriter +optimbase_isfeasible +optimbase_isinbounds +optimbase_isinnonlincons +optimbase_log +optimbase_logshutdown +optimbase_logstartup +optimbase_new +optimbase_outputcmd +optimbase_outstruct +optimbase_proj2bnds +optimbase_set +optimbase_stoplog +optimbase_terminate diff --git a/modules/optimization/macros/optimbase/optimbase_cget.bin b/modules/optimization/macros/optimbase/optimbase_cget.bin Binary files differnew file mode 100755 index 000000000..71794c989 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_cget.bin diff --git a/modules/optimization/macros/optimbase/optimbase_cget.sci b/modules/optimization/macros/optimbase/optimbase_cget.sci new file mode 100755 index 000000000..f779b69cb --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_cget.sci @@ -0,0 +1,70 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_cget -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// +function value = optimbase_cget (this,key) + [lhs,rhs]=argn(); + if ( rhs <> 2 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_cget", 3); + error(errmsg) + end + select key + case "-verbose" then + value = this.verbose; + case "-verbosetermination" then + value = this.verbosetermination; + case "-function" then + value = this.fun; + case "-method" then + value = this.method; + case "-x0" then + value = this.x0; + case "-maxfunevals" then + value = this.maxfunevals; + case "-maxiter" then + value = this.maxiter; + case "-tolfunabsolute" then + value = this.tolfunabsolute; + case "-tolfunrelative" then + value = this.tolfunrelative; + case "-tolxabsolute" then + value = this.tolxabsolute; + case "-tolxrelative" then + value = this.tolxrelative; + case "-tolxmethod" then + value = this.tolxmethod; + case "-tolfunmethod" then + value = this.tolfunmethod; + case "-outputcommand" then + value = this.outputcommand; + case "-numberofvariables" then + value = this.numberofvariables; + case "-storehistory" then + value = this.storehistory; + case "-boundsmin" then + value = this.boundsmin; + case "-boundsmax" then + value = this.boundsmax; + case "-nbineqconst" then + value = this.nbineqconst; + case "-logfile" then + value = this.logfile; + case "-withderivatives" then + value = this.withderivatives; + else + errmsg = msprintf(gettext("%s: Unknown key %s") , "optimbase_cget" , key) + error(errmsg) + end +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_checkbounds.bin b/modules/optimization/macros/optimbase/optimbase_checkbounds.bin Binary files differnew file mode 100755 index 000000000..0d4c296a3 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkbounds.bin diff --git a/modules/optimization/macros/optimbase/optimbase_checkbounds.sci b/modules/optimization/macros/optimbase/optimbase_checkbounds.sci new file mode 100755 index 000000000..bde51e2cf --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkbounds.sci @@ -0,0 +1,42 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_checkbounds -- +// Check if the bounds are consistent and puts an error message if not. +// One could generate an error, but errors are not testable +// with the current system. +// +function this = optimbase_checkbounds ( this ) + maxl = length ( this.boundsmax ) + minl = length ( this.boundsmin ) + if ( maxl > 0 | minl > 0 ) then + if ( this.numberofvariables <> maxl ) then + errmsg = sprintf(gettext("%s: The number of variables %d does not match the number of max bounds: %d.\n") , ... + "optimbase_checkbounds",this.numberofvariables , maxl ) + error(errmsg) + end + if ( this.numberofvariables <> minl ) then + errmsg = sprintf(gettext("%s: The number of variables %d does not match the number of min bounds: %d.\n") , ... + "optimbase_checkbounds",this.numberofvariables , minl ) + error(errmsg) + end + for ix = 1 : this.numberofvariables + xmin = this.boundsmin ( ix ) + xmax = this.boundsmax ( ix ) + if ( xmax < xmin ) then + errmsg = sprintf(gettext("%s: The max bound %s for variable #%d is lower than the min bound %s.\n"), ... + "optimbase_checkbounds",string(xmax) , ix , string(xmin) ) + error(errmsg) + end + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_checkcostfun.bin b/modules/optimization/macros/optimbase/optimbase_checkcostfun.bin Binary files differnew file mode 100755 index 000000000..237fb6827 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkcostfun.bin diff --git a/modules/optimization/macros/optimbase/optimbase_checkcostfun.sci b/modules/optimization/macros/optimbase/optimbase_checkcostfun.sci new file mode 100755 index 000000000..1f9b6c900 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkcostfun.sci @@ -0,0 +1,141 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_checkcostfun -- +// Check that the cost function is correctly connected. +// Generate an error if there is one. +// +function this = optimbase_checkcostfun ( this ) + if ( this.x0 == [] ) then + errmsg = msprintf ( gettext ( "%s: Cannot check cost function when x0 is empty" ) , "optimbase_checkcostfun" ) + error ( errmsg ); + end + // + // If there are no nonlinear constraints and no derivatives, check that the index is correctly managed. + // + if ( ( this.nbineqconst == 0 ) & ( ~this.withderivatives ) ) then + // + index = 1; + cmd = "[ this , f , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,index]=costf(x0,1)" , ierr ) + this = optimbase_checkshape ( this , "index" , index , 1 , 1 , 1 ); + // + index = 2; + cmd = "[ this , f , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,index]=costf(x0,2)" , ierr ) + this = optimbase_checkshape ( this , "f" , f , index , 1 , 1 ); + this = optimbase_checkshape ( this , "index" , index , 2 , 1 , 1 ); + end + // + // If there are nonlinear constraints and no derivatives, check that the index is correctly managed. + // + if ( ( this.nbineqconst > 0 ) & ( ~this.withderivatives ) ) then + // + index = 1; + cmd = "[ this , f , c , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,c,index]=costf(x0,1)" , ierr ) + this = optimbase_checkshape ( this , "index" , index , 1 , 1 , 1 ); + // + index = 2; + cmd = "[ this , f , c , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,c,index]=costf(x0,2)" , ierr ) + this = optimbase_checkshape ( this , "f" , f , index , 1 , 1 ); + this = optimbase_checkshape ( this , "index" , index , 2 , 1 , 1 ); + // + index = 5; + cmd = "[ this , f , c , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,c,index]=costf(x0,5)" , ierr ) + this = optimbase_checkshape ( this , "c" , c , index , 1 , this.nbineqconst ); + this = optimbase_checkshape ( this , "index" , index , 5 , 1 , 1 ); + // + index = 6; + cmd = "[ this , f , c , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,c,index]=costf(x0,6)" , ierr ) + this = optimbase_checkshape ( this , "f" , f , index , 1 , 1 ); + this = optimbase_checkshape ( this , "c" , c , index , 1 , this.nbineqconst ); + this = optimbase_checkshape ( this , "index" , index , 6 , 1 , 1 ); + end + // + // If there are no nonlinear constraints and derivatives, check that the index is correctly managed. + // + if ( ( this.nbineqconst == 0 ) & ( this.withderivatives ) ) then + // + index = 1; + cmd = "[ this , f , g , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,g,index]=costf(x0,1)" , ierr ) + this = optimbase_checkshape ( this , "index" , index , 1 , 1 , 1 ); + // + index = 2; + cmd = "[ this , f , g , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,g,index]=costf(x0,2)" , ierr ) + this = optimbase_checkshape ( this , "f" , f , index , 1 , 1 ); + this = optimbase_checkshape ( this , "index" , index , 2 , 1 , 1 ); + // + index = 3; + cmd = "[ this , f , g , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,g,index]=costf(x0,2)" , ierr ) + this = optimbase_checkshape ( this , "g" , g , index , 1 , this.numberofvariables ); + this = optimbase_checkshape ( this , "index" , index , 3 , 1 , 1 ); + // + index = 4; + cmd = "[ this , f , g , index ] = optimbase_function ( this , this.x0 , index )"; + ierr=execstr(cmd,"errcatch"); + optimbase_checkstatus ( "[f,g,index]=costf(x0,4)" , ierr) + this = optimbase_checkshape ( this , "f" , f , index , 1 , 1 ); + this = optimbase_checkshape ( this , "g" , g , index , 1 , this.numberofvariables ); + this = optimbase_checkshape ( this , "index" , index , 4 , 1 , 1 ); + end +endfunction + +// +// optimbase_checkstatus -- +// Generates an error if ierr is nonzero, that is, +// if the cost function could not be evaluated. +// +function optimbase_checkstatus ( cmdstr , ierr ) + if ( ierr <> 0 ) then + lamsg = lasterror() + lclmsg = gettext ( "%s: Cannot evaluate cost function with ""%s"": %s" ) + errmsg = msprintf (lclmsg , "optimbase_checkcostfun",cmdstr, lamsg ) + error ( errmsg ); + end +endfunction + +// +// optimbase_checkcostfun -- +// Check that the cost function is correctly connected. +// Generate an error if there is one. +// +function this = optimbase_checkshape ( this , varname , value , index , expectednrows , expectedncols ) + if ( size(value,1) <> expectednrows ) then + if ( size(value,1) == expectedncols & size(value,2) == 1) then + // Allow column vector returns, just transpose them to get row vectors. + value = value'; + else + errmsg = msprintf ( gettext ( "%s: The matrix %s from costf(x0,%d) has %d rows, instead of %d." ) , "optimbase_checkcostfun" , varname , index , size(value,1) , expectednrows ) + error ( errmsg ); + end + end + if ( size(value,2) <> expectedncols ) then + errmsg = msprintf ( gettext ( "%s: The matrix %s from costf(x0,%d) has %d columns, instead of %d." ) , "optimbase_checkcostfun" , varname , index , size(value,2) , expectedncols ) + error ( errmsg ); + end +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_checkx0.bin b/modules/optimization/macros/optimbase/optimbase_checkx0.bin Binary files differnew file mode 100755 index 000000000..35148a2ad --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkx0.bin diff --git a/modules/optimization/macros/optimbase/optimbase_checkx0.sci b/modules/optimization/macros/optimbase/optimbase_checkx0.sci new file mode 100755 index 000000000..03764953d --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_checkx0.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_checkx0 -- +// Returns %T if the initial guess is consistent with the bounds +// and the non linear inequality constraints, if any. +// +function this = optimbase_checkx0 ( this ) + [ this , isfeasible ] = optimbase_isfeasible ( this , this.x0 ) + if ( isfeasible <> 1 ) then + error(sprintf ( gettext("%s: Initial guess is not feasible."),"optimbase_checkx0") ) + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_configure.bin b/modules/optimization/macros/optimbase/optimbase_configure.bin Binary files differnew file mode 100755 index 000000000..715fa3a9d --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_configure.bin diff --git a/modules/optimization/macros/optimbase/optimbase_configure.sci b/modules/optimization/macros/optimbase/optimbase_configure.sci new file mode 100755 index 000000000..b990ece3a --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_configure.sci @@ -0,0 +1,224 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_configure -- +// Configure the current object with the given value for the given key. +// +function this = optimbase_configure (this,key,value) + UN=number_properties("tiny") + [lhs,rhs]=argn(); + if ( rhs <> 3 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_configure", 3); + error(errmsg) + end + select key + case "-verbose" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.verbose = value; + case "-verbosetermination" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.verbosetermination = value; + case "-logfile" then + optimbase_typestring ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + if ( this.logstartup ) then + this = optimbase_logshutdown ( this ) + end + this.logfile = value; + this = optimbase_logstartup ( this ); + case "-x0" then + optimbase_typereal ( value , "value" , 3 ); + [n,m] = size(value); + if m<>1 then + if n==1 then // Allowing row vectors by transposing them into column vectors + value = value'; + temp = m; // Switch the sizes in case we want to reuse them later in this function + m = n; + n = temp; + else + error(msprintf(gettext("%s: Wrong size for x0 argument: A vector expected."),"optimbase_configure")); + end + end + this.x0 = value; + this.numberofvariables = n; // Setting x0 also sets the size of the system + case "-maxfunevals" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 1 ) + this.maxfunevals = value; + case "-maxiter" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 1 ) + this.maxiter = value; + case "-tolfunabsolute" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.tolfunabsolute = value; + case "-tolfunrelative" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.tolfunrelative = value; + case "-tolxabsolute" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.tolxabsolute = value; + case "-tolxrelative" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.tolxrelative = value; + case "-tolxmethod" then + optimbase_typeboolean ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + this.tolxmethod = value; + case "-tolfunmethod" then + optimbase_typeboolean ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + this.tolfunmethod = value; + case "-function" then + optimbase_typecallable ( value , "value" , 3) + this.fun = value; + case "-outputcommand" then + optimbase_typecallable ( value , "value" , 3) + this.outputcommand = value; + case "-numberofvariables" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 1 ) + this.numberofvariables = value; + case "-storehistory" then + optimbase_typeboolean ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + this.storehistory = value; + case "-boundsmin" then + optimbase_typereal ( value , "value" , 3 ); + this.boundsmin = value; + case "-boundsmax" then + optimbase_typereal ( value , "value" , 3 ); + this.boundsmax = value; + case "-nbineqconst" then + optimbase_typereal ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + optimbase_checkgreq ( "optimbase_configure" , value , "value" , 3 , 0 ) + this.nbineqconst = value; + case "-withderivatives" then + optimbase_typeboolean ( value , "value" , 3 ); + optimbase_checkscalar ( "optimbase_configure" , value , "value" , 3 ) + this.withderivatives = value; + // + // Obsolete options. + // + else + errmsg = msprintf(gettext("%s: Unknown key %s"),"optimbase_configure",key) + error(errmsg) + end +endfunction +// Generates an error if the given variable is not of type real +function optimbase_typereal ( var , varname , ivar ) + if ( type ( var ) <> 1 ) then + errmsg = msprintf(gettext("%s: Expected real variable for variable %s at input #%d, but got %s instead."),"optimbase_typereal", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type string +function optimbase_typestring ( var , varname , ivar ) + if ( type ( var ) <> 10 ) then + errmsg = msprintf(gettext("%s: Expected string variable for variable %s at input #%d, but got %s instead."),"optimbase_typestring", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type function (macro) +function optimbase_typefunction ( var , varname , ivar ) + if ( type ( var ) <> 13 ) then + errmsg = msprintf(gettext("%s: Expected function but for variable %s at input #%d, got %s instead."),"optimbase_typefunction", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction +// Generates an error if the given variable is not of type boolean +function optimbase_typeboolean ( var , varname , ivar ) + if ( type ( var ) <> 4 ) then + errmsg = msprintf(gettext("%s: Expected boolean but for variable %s at input #%d, got %s instead."),"optimbase_typeboolean", varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction + +// Generates an error if the value corresponding to an option is unknown. +function unknownValueForOption ( value , optionname ) + errmsg = msprintf(gettext("%s: Unknown value %s for %s option"),"unknownValueForOption",value , optionname ); + error(errmsg); +endfunction + +function optimbase_typecallable ( var , varname , ivar ) + // Check that var is a function or a list + if ( and ( type ( var ) <> [11 13 15] ) ) then + errmsg = msprintf(gettext("%s: Expected function or list for variable %s at input #%d, but got %s instead."),"optimbase_typecallable", varname , ivar , typeof(var) ); + error(errmsg); + end + if ( type ( var ) == 15 ) then + // Check that var(1) is a function + if ( and ( type ( var(1) ) <> [11 13] ) ) then + errmsg = msprintf(gettext("%s: Expected function for variable %s(1) at input #%d, but got %s instead."),"optimbase_typecallable", varname , ivar , typeof(var) ); + error(errmsg); + end + end +endfunction + +function optimbase_checkrange ( funname , var , varname , ivar , vmin , vmax ) + if ( ~and ( vmin <= var & var <= vmax ) ) then + k = find ( vmin > var | var > vmax ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected that all entries of input argument %s at input #%d are in the range [%s,%s], but entry #%d is equal to %s."),funname,varname,ivar,string(vmin),string(vmax),k,string(var(k))); + error(errmsg); + end +endfunction + +function optimbase_checkgreq ( funname , var , varname , ivar , thr ) + if ( or ( var < thr ) ) then + k = find ( var < thr ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected that all entries of input argument %s at input #%d are greater or equal than %s, but entry #%d is equal to %s."),funname,varname,ivar,string(thr),k,string(var(k))); + error(errmsg); + end +endfunction + +function optimbase_checkflint ( funname , var , varname , ivar ) + if ( or ( round(var)<>var ) ) then + k = find ( round(var)<>var ) + k = k(1) + errmsg = msprintf(gettext("%s: Expected floating point integer for input argument %s at input #%d, but entry #%d is equal to %s."),funname,varname,ivar,k,string(var(k))); + error(errmsg); + end +endfunction + +function optimbase_checkscalar ( funname , var , varname , ivar ) + if ( or(size(var) <> [1 1]) ) then + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), funname, ivar , 1, 1 ); + error(errmsg) + end +endfunction + +function optimbase_checkoption ( funname , var , varname , ivar , expectedopt ) + if ( and ( var <> expectedopt ) ) then + stradd = """ or """ + strexp = """" + strcat(string(expectedopt),stradd) + """" + errmsg = msprintf(gettext("%s: Expected value [%s] for input argument %s at input #%d, but got ""%s"" instead."),funname,strexp,varname,ivar,string(var)); + error(errmsg); + end +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_destroy.bin b/modules/optimization/macros/optimbase/optimbase_destroy.bin Binary files differnew file mode 100755 index 000000000..89485b084 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_destroy.bin diff --git a/modules/optimization/macros/optimbase/optimbase_destroy.sci b/modules/optimization/macros/optimbase/optimbase_destroy.sci new file mode 100755 index 000000000..b966bb055 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_destroy.sci @@ -0,0 +1,27 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_destroy -- +// Destroy an object. +// +function this = optimbase_destroy (this) + [lhs,rhs]=argn(); + if ( rhs <> 1 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_destroy", 1); + error(errmsg) + end + this.historyfopt = []; + this.historyxopt = []; + if ( this.logstartup ) then + this = optimbase_logshutdown ( this ); + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_function.bin b/modules/optimization/macros/optimbase/optimbase_function.bin Binary files differnew file mode 100755 index 000000000..b0bdeb26c --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_function.bin diff --git a/modules/optimization/macros/optimbase/optimbase_function.sci b/modules/optimization/macros/optimbase/optimbase_function.sci new file mode 100755 index 000000000..acc4c0aa3 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_function.sci @@ -0,0 +1,215 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_function -- +// Call the cost function and return the value. +// If a cost function argument is defined in current object, +// pass it to the function. +// If an index is defined as input argument, pass it to the +// function, always as second argument. +// Arguments +// x : the point where the function is to be evaluated. +// index, input : a flag to pass to the cost function +// if index=1, output a message, and compute whatever is required +// if index=2, compute f +// if index=3, compute g +// if index=4, compute f and g +// if index=5, returns c +// if index=6, returns f and c +// if index=7, returns f, g, c and gc +// where +// f : the cost function +// g : the gradient of the cost function +// c : the nonlinear, positive constraints +// gc : the gradient of the nonlinear, positive constraints +// Other values of index might be used in the future, +// for example, when an derivative-based optimizer with +// non linear constraints is required. +// index, output : +// if index > 0, everything went fine +// if index == 0, interrupts the optimization +// if index < 0, f cannot be evaluated +// Calling sequences : +// [ this , f , index ] = optimbase_function ( this , x , index ) +// [ this , f , g , index ] = optimbase_function ( this , x , index ) +// [ this , f , c , index ] = optimbase_function ( this , x , index ) +// [ this , f , g , c , gc , index ] = optimbase_function ( this , x , index ) +// Not Authorized Calling sequences of the optimbase_function: +// Rejected because there is no index in input : +// [ this , f , index ] = optimbase_function ( this , x ) +// [ this , f ] = optimbase_function ( this , x ) +// Rejected because there is no index in output : +// [ this , f ] = optimbase_function ( this , x , index ) +// [ this , f , g ] = optimbase_function ( this , x , index ) +// [ this , f , c ] = optimbase_function ( this , x , index ) +// [ this , f , g , c , gc ] = optimbase_function ( this , x , index ) +// +// Calling sequences of the cost function: +// > Without additional data +// [ f , index ] = costf ( x , index ) +// [ f , g , index ] = costf ( x , index ) +// [ f , c , index ] = costf ( x , index ) +// [ f , g , c , gc , index ] = costf ( x , index ) +// > With additional data +// [ f , index ] = costf ( x , index , a1, a2, ... ) +// [ f , g , index ] = costf ( x , index , a1, a2, ... ) +// [ f , c , index ] = costf ( x , index , a1, a2, ... ) +// [ f , g , c , gc , index ] = costf ( x , index , a1, a2, ... ) +// Not Authorized Calling sequences of the cost function: +// Rejected because there is no index in input : +// [ f ] = costf ( this , x ) +// [ f , index ] = costf ( this , x ) +// [ f ] = costf ( this , x , a1, a2, ... ) +// [ f , index ] = costf ( this , x , a1, a2, ... ) +// Rejected because there is no index in output : +// [ f ] = costf ( this , x , index ) +// [ f , g ] = costf ( this , x , index ) +// [ f , c ] = costf ( this , x , index ) +// [ f , g , c ] = costf ( this , x , index ) +// [ f ] = costf ( this , x , index , a1, a2, ... ) +// [ f , g ] = costf ( this , x , index , a1, a2, ... ) +// [ f , g , c ] = costf ( this , x , index , a1, a2, ... ) +// [ f , c ] = costf ( this , x , index , a1, a2, ... ) +// +function varargout = optimbase_function ( this , x , index ) + [lhs,rhs]=argn(); + if ( rhs <> 3 ) then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 2 are expected."), "optimbase_function", rhs); + error(errmsg) + end + if ( ( lhs < 3 ) | ( lhs > 5 ) ) then + errmsg = msprintf(gettext("%s: Unexpected number of output arguments : %d provided while 3 to 5 are expected."), "optimbase_function", lhs); + error(errmsg) + end + if this.fun == "" then + errmsg = msprintf(gettext("%s: Empty function (use -function option)."), "optimbase_function") + error(errmsg) + end + this.funevals = this.funevals + 1; + if this.verbose == 1 then + msg = sprintf ( "Function Evaluation #%d, index=%d, x= [%s]" , ... + this.funevals , index, strcat(string(x)," ")) + this = optimbase_log ( this , msg ) + end + // + // Setup the callback and its arguments + // + funtype = typeof(this.fun) + if ( funtype == "function" ) then + __optimbase_f__ = this.fun + // + // Backward-compatibility: process the costfargument field + // + if ( typeof(this.costfargument) == "string" ) then + __optimbase_args__ = list() + else + __optimbase_args__ = list(this.costfargument) + end + else + __optimbase_f__ = this.fun(1) + __optimbase_args__ = list(this.fun(2:$)) + end + if ( this.withderivatives ) then + if ( this.nbineqconst == 0 ) then + // [ f , g , index ] = costf ( x , index ) + // [ f , g , index ] = costf ( x , index , a1, a2, ... ) + // [ this , f , g , index ] = optimbase_function ( this , x , index ) + [ f , g , index ] = __optimbase_f__ ( x , index , __optimbase_args__(1:$) ); + if type(f) <> 1 | ~isreal(f) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 1); + error(errmsg) + end + if type(g) <> 1 | ~isreal(g) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 2); + error(errmsg) + end + if type(index) <> 1 | ~isreal(index) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 3); + error(errmsg) + end + varargout(1) = this + varargout(2) = f + varargout(3) = g + varargout(4) = index + else + // [ f , g , c , gc , index ] = costf ( x , index ) + // [ f , g , c , gc , index ] = costf ( x , index , a1, a2, ... ) + // [ this , f , g , c , gc , index ] = optimbase_function ( this , x , index ) + [ f , g , c , gc , index ] = __optimbase_f__ ( x , index , __optimbase_args__(1:$) ); + if type(f) <> 1 | ~isreal(f) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 1); + error(errmsg) + end + if type(g) <> 1 | ~isreal(g) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 2); + error(errmsg) + end + if type(c) <> 1 | ~isreal(c) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 3); + error(errmsg) + end + if type(gc) <> 1 | ~isreal(gc) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 4); + error(errmsg) + end + if type(index) <> 1 | ~isreal(index) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 5); + error(errmsg) + end + varargout(1) = this + varargout(2) = f + varargout(3) = g + varargout(4) = c + varargout(5) = gc + varargout(6) = index + end + else + if ( this.nbineqconst == 0 ) then + // [ f , index ] = costf ( x , index ) + // [ f , index ] = costf ( x , index , a1, a2, ... ) + // [ this , f , index ] = optimbase_function ( this , x , index ) + [ f , index ] = __optimbase_f__ ( x , index , __optimbase_args__(1:$) ); + if type(f) <> 1 | ~isreal(f) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 1); + error(errmsg) + end + if type(index) <> 1 | ~isreal(index) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 2); + error(errmsg) + end + varargout(1) = this + varargout(2) = f + varargout(3) = index + else + // [ f , c , index ] = costf ( x , index ) + // [ f , c , index ] = costf ( x , index , a1, a2, ... ) + // [ this , f , c , index ] = optimbase_function ( this , x , index ) + [ f , c , index ] = __optimbase_f__ ( x , index , __optimbase_args__(1:$) ); + if type(f) <> 1 | ~isreal(f) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 1); + error(errmsg) + end + if type(c) <> 1 | ~isreal(c) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 2); + error(errmsg) + end + if type(index) <> 1 | ~isreal(index) then + errmsg = msprintf(_("%s: Wrong type for user function output argument #%d: A real matrix expected."), "optimbase_function", 3); + error(errmsg) + end + varargout(1) = this + varargout(2) = f + varargout(3) = c + varargout(4) = index + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_get.bin b/modules/optimization/macros/optimbase/optimbase_get.bin Binary files differnew file mode 100755 index 000000000..f3e447ac8 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_get.bin diff --git a/modules/optimization/macros/optimbase/optimbase_get.sci b/modules/optimization/macros/optimbase/optimbase_get.sci new file mode 100755 index 000000000..4e269707c --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_get.sci @@ -0,0 +1,59 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_get -- +// Get the value for the given key. +// If the key is unknown, generates an error. +// This command corresponds with options which are not +// available directly to the user interface, but are computed internally. +// +function value = optimbase_get (this,key) + [lhs,rhs]=argn(); + if ( rhs <> 2 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_get", 2); + error(errmsg) + end + select key + case "-funevals" then + value = this.funevals; + case "-iterations" then + value = this.iterations; + case "-xopt" then + value = this.xopt; + case "-fopt" then + value = this.fopt; + case "-historyxopt" then + if ( ~this.storehistory ) then + errmsg = msprintf(gettext("%s: History disabled ; enable -storehistory option."),"optimbase_get") + error(errmsg) + else + value = this.historyxopt; + end + case "-historyfopt" then + if ( ~this.storehistory ) then + errmsg = msprintf(gettext("%s: History disabled ; enable -storehistory option."),"optimbase_get") + error(errmsg) + else + value = this.historyfopt; + end + case "-fx0" then + value = this.fx0; + case "-status" then + value = this.status; + case "-logstartup" then + value = this.logstartup; + else + errmsg = msprintf(gettext("%s: Unknown key %s"),"optimbase_get",key) + error(errmsg) + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_hasbounds.bin b/modules/optimization/macros/optimbase/optimbase_hasbounds.bin Binary files differnew file mode 100755 index 000000000..d2fe25873 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasbounds.bin diff --git a/modules/optimization/macros/optimbase/optimbase_hasbounds.sci b/modules/optimization/macros/optimbase/optimbase_hasbounds.sci new file mode 100755 index 000000000..2a457cf89 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasbounds.sci @@ -0,0 +1,25 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + + +// +// optimbase_hasbounds -- +// Returns %T if current problem has bounds. +// Arguments +// this : the current object +// hasbounds : %T or %F (see above) +// +function [ this , hasbounds ] = optimbase_hasbounds ( this ) + maxl = length ( this.boundsmax ) + minl = length ( this.boundsmin ) + hasbounds = ( maxl <> 0 | minl <> 0 ) +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_hasconstraints.bin b/modules/optimization/macros/optimbase/optimbase_hasconstraints.bin Binary files differnew file mode 100755 index 000000000..d3c1bdd1b --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasconstraints.bin diff --git a/modules/optimization/macros/optimbase/optimbase_hasconstraints.sci b/modules/optimization/macros/optimbase/optimbase_hasconstraints.sci new file mode 100755 index 000000000..c387fbbe9 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasconstraints.sci @@ -0,0 +1,30 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + + +// +// optimbase_hasconstraints -- +// Returns %T if current problem has +// * bounds constraints or +// * linear constraints or +// * non linear constraints. +// Arguments +// this : the current object +// hasbounds : %T or %F (see above) +// TODO : linear constraints +// +function [ this , hascons ] = optimbase_hasconstraints ( this ) + hascons = %f + hascons = ( hascons | ( this.nbineqconst > 0 ) ) + maxl = length ( this.boundsmax ) + minl = length ( this.boundsmin ) + hascons = ( hascons | ( maxl <> 0 ) | ( minl <> 0 ) ) +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_hasnlcons.bin b/modules/optimization/macros/optimbase/optimbase_hasnlcons.bin Binary files differnew file mode 100755 index 000000000..70f760f78 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasnlcons.bin diff --git a/modules/optimization/macros/optimbase/optimbase_hasnlcons.sci b/modules/optimization/macros/optimbase/optimbase_hasnlcons.sci new file mode 100755 index 000000000..4d1c31e8e --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_hasnlcons.sci @@ -0,0 +1,24 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + + +// +// optimbase_hasnlcons -- +// Returns %T if current problem has non +// linear constraints. +// Arguments +// this : the current object +// hasnlcons : %T or %F (see above) +// +function [ this , hasnlcons ] = optimbase_hasnlcons ( this ) + hasnlcons = ( this.nbineqconst > 0 ) +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_histget.bin b/modules/optimization/macros/optimbase/optimbase_histget.bin Binary files differnew file mode 100755 index 000000000..850ccccb1 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_histget.bin diff --git a/modules/optimization/macros/optimbase/optimbase_histget.sci b/modules/optimization/macros/optimbase/optimbase_histget.sci new file mode 100755 index 000000000..fd47fd2ce --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_histget.sci @@ -0,0 +1,39 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_histget -- +// Returns the history value for the given key. +// If the key is unknown, generates an error. +// Arguments +// iter : the iteration for which the data is to store +// key : the name of the data to store +// +function value = optimbase_histget ( this , iter , key ) + if ( ~this.storehistory ) then + errmsg = msprintf(gettext("%s: History disabled ; turn on -storehistory option.") , "optimbase_histget" ) + error(errmsg) + end + if iter < 1 then + errmsg = msprintf(gettext("%s: Negative iteration index %d is not allowed.") , "optimbase_histget" , iter ) + error(errmsg) + end + select key + case "-xopt" then + value = this.historyxopt ( iter ); + case "-fopt" then + value = this.historyfopt ( iter ); + else + errmsg = msprintf(gettext("%s: Unknown key %s") , "optimbase_histget" ,key) + error(errmsg) + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_histset.bin b/modules/optimization/macros/optimbase/optimbase_histset.bin Binary files differnew file mode 100755 index 000000000..9c09d75cb --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_histset.bin diff --git a/modules/optimization/macros/optimbase/optimbase_histset.sci b/modules/optimization/macros/optimbase/optimbase_histset.sci new file mode 100755 index 000000000..cb1e80f38 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_histset.sci @@ -0,0 +1,39 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_histset -- +// Set the history value at given iteration for the given key. +// If the key is unknown, generates an error. +// Arguments +// iter : the iteration for which the data is to store +// key : the name of the data to store +// value : the value to store +// +function this = optimbase_histset ( this , iter , key , value ) + if ( ~this.storehistory ) then + errmsg = msprintf(gettext("%s: History disabled ; turn on -storehistory option.") , "optimbase_histset" ) + error(errmsg) + end + if iter < 1 then + errmsg = msprintf(gettext("%s: Negative iteration index are not allowed.") , "optimbase_histset" ) + error(errmsg) + end + select key + case "-xopt" then + this.historyxopt ( iter ) = value; + case "-fopt" then + this.historyfopt ( iter ) = value; + else + errmsg = msprintf(gettext("%s: Unknown key %s" ) , "optimbase_histset" , key ) + error(errmsg) + end +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_incriter.bin b/modules/optimization/macros/optimbase/optimbase_incriter.bin Binary files differnew file mode 100755 index 000000000..37cb03e7d --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_incriter.bin diff --git a/modules/optimization/macros/optimbase/optimbase_incriter.sci b/modules/optimization/macros/optimbase/optimbase_incriter.sci new file mode 100755 index 000000000..a5dcdac05 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_incriter.sci @@ -0,0 +1,18 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_incriter -- +// Increments the number of iterations. +// +function this = optimbase_incriter ( this ) + this.iterations = this.iterations + 1 +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_isfeasible.bin b/modules/optimization/macros/optimbase/optimbase_isfeasible.bin Binary files differnew file mode 100755 index 000000000..ce0d603c9 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isfeasible.bin diff --git a/modules/optimization/macros/optimbase/optimbase_isfeasible.sci b/modules/optimization/macros/optimbase/optimbase_isfeasible.sci new file mode 100755 index 000000000..d7641e893 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isfeasible.sci @@ -0,0 +1,68 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_isfeasible -- +// Returns 1 if the given point satisfies bounds constraints and inequality constraints. +// Returns 0 if the given point is not in the bounds. +// Returns -1 if the given point does not satisfies inequality constraints. +// Arguments +// x : the point to analyse +// isfeasible : = 1, 0 or -1 (see above) +// +function [ this , isfeasible ] = optimbase_isfeasible ( this , x ) + isfeasible = 1 + // + // Check if the point is in the bounds. + // + if ( isfeasible == 1 ) then + [ this , hasbounds ] = optimbase_hasbounds ( this ); + if ( hasbounds ) then + for ix = 1 : this.numberofvariables + xmin = this.boundsmin ( ix ) + xmax = this.boundsmax ( ix ) + xix = x ( ix ) + if ( xix < xmin ) then + isfeasible = 0 + this = optimbase_log ( this , sprintf ( "Component #%d/%d of x is lower than min bound %s", ... + ix , this.numberofvariables , string(xmin) ) ) + break + end + if (xix > xmax) then + isfeasible = 0 + this = optimbase_log ( this , sprintf ( "Component #%d/%d of x is greater than max bound %s", ... + ix , this.numberofvariables , string(xmax) ) ) + break + end + end + end + end + // + // Check inequality constraints + // + if ( isfeasible == 1 ) then + if ( this.nbineqconst > 0) then + if ( this.withderivatives ) then + [ this , f , g , c , gc , index ] = optimbase_function ( this , x , 5 ); + else + [ this , f , c , index ] = optimbase_function ( this , x , 5 ); + end + for ic = 1 : this.nbineqconst + if ( c ( ic ) < 0.0 ) then + this = optimbase_log ( this , sprintf ( "Inequality constraint #%d/%d is not satisfied for x", ... + ic , this.nbineqconst ) ) + isfeasible = -1 + break + end + end + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_isinbounds.bin b/modules/optimization/macros/optimbase/optimbase_isinbounds.bin Binary files differnew file mode 100755 index 000000000..d4cac7e83 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isinbounds.bin diff --git a/modules/optimization/macros/optimbase/optimbase_isinbounds.sci b/modules/optimization/macros/optimbase/optimbase_isinbounds.sci new file mode 100755 index 000000000..6c50ae774 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isinbounds.sci @@ -0,0 +1,42 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_isinbounds -- +// Returns %t if the given point satisfies bounds constraints. +// Returns %f if the given point is not in the bounds. +// Arguments +// x : the point to analyse +// isfeasible : = %t, %f +// +function [ this , isfeasible ] = optimbase_isinbounds ( this , x ) + isfeasible = %t + [ this , hasbounds ] = optimbase_hasbounds ( this ); + if ( hasbounds ) then + for ix = 1 : this.numberofvariables + xmin = this.boundsmin ( ix ) + xmax = this.boundsmax ( ix ) + xix = x ( ix ) + if ( xix < xmin ) then + isfeasible = %f + this = optimbase_log ( this , sprintf ( "Component #%d/%d of x is lower than min bound %s", ... + ix , this.numberofvariables , string(xmin) ) ) + break + end + if (xix > xmax) then + isfeasible = %f + this = optimbase_log ( this , sprintf ( "Component #%d/%d of x is greater than max bound %s", ... + ix , this.numberofvariables , string(xmax) ) ) + break + end + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_isinnonlincons.bin b/modules/optimization/macros/optimbase/optimbase_isinnonlincons.bin Binary files differnew file mode 100755 index 000000000..1614293af --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isinnonlincons.bin diff --git a/modules/optimization/macros/optimbase/optimbase_isinnonlincons.sci b/modules/optimization/macros/optimbase/optimbase_isinnonlincons.sci new file mode 100755 index 000000000..45077a566 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_isinnonlincons.sci @@ -0,0 +1,36 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_isinnonlincons -- +// Returns %t if the given point satisfies inequality constraints. +// Returns %f if the given point does not satisfies inequality constraints. +// Arguments +// x : the point to analyse +// isfeasible : = %t or %f +// +function [ this , isfeasible ] = optimbase_isinnonlincons ( this , x ) + isfeasible = %t + if ( this.nbineqconst > 0) then + if ( this.withderivatives ) then + [ this , f , g , c , gc , index ] = optimbase_function ( this , x , 2 ); + else + [ this , f , c , index ] = optimbase_function ( this , x , 5 ); + end + for ic = 1 : this.nbineqconst + if ( c ( ic ) < 0.0 ) then + this = optimbase_log ( this , sprintf ( "Inequality constraint #%d/%d is not satisfied for x", ... + ic , this.nbineqconst ) ) + isfeasible = %f + break + end + end + end +endfunction diff --git a/modules/optimization/macros/optimbase/optimbase_log.bin b/modules/optimization/macros/optimbase/optimbase_log.bin Binary files differnew file mode 100755 index 000000000..53584c597 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_log.bin diff --git a/modules/optimization/macros/optimbase/optimbase_log.sci b/modules/optimization/macros/optimbase/optimbase_log.sci new file mode 100755 index 000000000..41fa18233 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_log.sci @@ -0,0 +1,30 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_log -- +// If verbose logging is enabled, prints the given message in the console. +// If verbose logging is disabled, does nothing. +// +function this = optimbase_log (this,msg) + [lhs,rhs]=argn(); + if ( rhs <> 2 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_log", 2); + error(errmsg) + end + if ( this.verbose == 1 ) then + if ( this.logfile <> "" ) then + mfprintf ( this.logfilehandle , "%s\n" , msg ); + else + mprintf("%s\n",msg); + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_logshutdown.bin b/modules/optimization/macros/optimbase/optimbase_logshutdown.bin Binary files differnew file mode 100755 index 000000000..e6a46d6aa --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_logshutdown.bin diff --git a/modules/optimization/macros/optimbase/optimbase_logshutdown.sci b/modules/optimization/macros/optimbase/optimbase_logshutdown.sci new file mode 100755 index 000000000..66580da32 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_logshutdown.sci @@ -0,0 +1,27 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_logshutdown -- +// Shut down the logging. +// If the logging is already started up, generates an error. +// If the loggin is started up, if there is a log file, close it. +// +function this = optimbase_logshutdown ( this ) + if ~this.logstartup then + error ( gettext ( "%s: Logging not started." , "optimbase_logshutdown" ) ) + else + this.logstartup = %f; + if ( this.logfile <> "" ) then + mclose( this.logfilehandle ); + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_logstartup.bin b/modules/optimization/macros/optimbase/optimbase_logstartup.bin Binary files differnew file mode 100755 index 000000000..58c345073 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_logstartup.bin diff --git a/modules/optimization/macros/optimbase/optimbase_logstartup.sci b/modules/optimization/macros/optimbase/optimbase_logstartup.sci new file mode 100755 index 000000000..d91d74705 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_logstartup.sci @@ -0,0 +1,40 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_logstartup -- +// Automatically startup logging. +// If the logging is already started up, generates an error. +// If the logging is not started up, if there is a log file configured, +// open that log file to append messages. +// +function this = optimbase_logstartup ( this ) + if ( this.logstartup ) then + error ( gettext ( "%s: Logging already started." , "optimbase_logstartup" ) ) + else + this.logstartup = %t; + if ( this.logfile <> "" ) then + if ( this.logfilehandle <> 0 ) then + error ( gettext ( "%s: Log file handle non zero while starting up the logging." , "optimbase_logstartup" ) ) + end + this.logfilehandle = mopen( this.logfile , "a" ); + c = clock(); + year = c(1); + month = c(2); + day = c(3); + hour = c(4); + minute = c(5); + seconds = c(6); + mfprintf ( this.logfilehandle , "Optimbase ready for logging at %d-%d-%d %d:%d:%d\n" , ... + year , month , day , hour , minute , seconds ); + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_new.bin b/modules/optimization/macros/optimbase/optimbase_new.bin Binary files differnew file mode 100755 index 000000000..f0cdc8211 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_new.bin diff --git a/modules/optimization/macros/optimbase/optimbase_new.sci b/modules/optimization/macros/optimbase/optimbase_new.sci new file mode 100755 index 000000000..9b7e21924 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_new.sci @@ -0,0 +1,136 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_new -- +// Creates a new Optimization object. +// +function newobj = optimbase_new () + [lhs,rhs]=argn(); + if ( rhs <> 0 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_new", 0); + error(errmsg) + end + newobj = tlist(["TOPTIM" + "verbose" + "x0" + "fx0" + "xopt" + "fopt" + "tolfunabsolute" + "tolfunrelative" + "tolfunmethod" + "tolxabsolute" + "tolxrelative" + "tolxmethod" + "funevals" + "maxfunevals" + "iterations" + "maxiter" + "fun" + "status" + "historyfopt" + "historyxopt" + "verbosetermination" + "outputcommand" + "numberofvariables" + "storehistory" + "boundsmin" + "boundsmax" + "nbineqconst" + "logfile" + "logfilehandle" + "logstartup" + "withderivatives" + // + // Obsolete options. + // + "costfargument" + "outputcommandarg" + ]); + // The number of variables to optimize + newobj.numberofvariables = 0 + // The verbose option, controlling the amount of messages + newobj.verbose = 0; + // The verbose option for termination criteria + newobj.verbosetermination = 0; + // The initial guess + newobj.x0 = []; + // The value of the function for the initial guess + newobj.fx0 = []; + // The maximum number of function evaluations + newobj.maxfunevals = 100; + // The maximum number of iterations + newobj.maxiter = 100; + // Possible values : %f, %t + // This criteria is suitable for functions which minimum is + // associated with a function value equal to 0. + newobj.tolfunmethod = %f; + // The absolute tolerance on function value + newobj.tolfunabsolute = 0.0; + // The relative tolerance on function value + newobj.tolfunrelative = %eps; + // The absolute tolerance on x + newobj.tolxabsolute = 0.0; + // The relative tolerance on x + newobj.tolxrelative = sqrt(%eps); + // The number of function evaluations + newobj.funevals = 0; + // The number of iterations + newobj.iterations = 0; + // The optimum parameter + newobj.xopt = 0; + // The optimum function value + newobj.fopt = 0; + // Possible values : %f, %t + newobj.tolxmethod = %t; + // The status of the optimization + newobj.status = ""; + // The command called back for output + newobj.outputcommand = ""; + // The cost function + newobj.fun = ""; + // The flag which enables/disables the storing of the history + newobj.storehistory = %f; + // The array to store the history for xopt + newobj.historyxopt = list(); + // The array to store the history for fopt + newobj.historyfopt = []; + // Maximum bounds for the parameters + newobj.boundsmax = []; + // Minimum bounds for the parameters + newobj.boundsmin = []; + // The number of nonlinear inequality constraints + newobj.nbineqconst = 0; + // The name of the log file + newobj.logfile = ""; + // The handle for the log file + newobj.logfilehandle = 0; + // Set to %t when the logging is started up + newobj.logstartup = %f; + // Set to %t when the method uses derivatives + newobj.withderivatives = %f + // + // Obsolete options + // + // The costf argument is initialized as a string. + // If the user configure this option, it is expected + // that a matrix of values or a list, tlist, mlist is + // passed so that the argument is appended to the name of the + // function. + newobj.costfargument = ""; + // The outputcommand argument is initialized as a string. + // If the user configure this option, it is expected + // that a matrix of values or a list, tlist, mlist is + // passed so that the argument is appended to the name of the + // function. + newobj.outputcommandarg = "" +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_outputcmd.bin b/modules/optimization/macros/optimbase/optimbase_outputcmd.bin Binary files differnew file mode 100755 index 000000000..706bb5e1c --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_outputcmd.bin diff --git a/modules/optimization/macros/optimbase/optimbase_outputcmd.sci b/modules/optimization/macros/optimbase/optimbase_outputcmd.sci new file mode 100755 index 000000000..4a3c954fc --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_outputcmd.sci @@ -0,0 +1,63 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_outputcmd -- +// Calls back user's output command +// Arguments +// this : the current object +// state : the state of the algorithm, +// "init", "done", "iter" +// data : the data to pass to the client output command +// stop : set to true to stop the algorithm +// +function stop = optimbase_outputcmd ( this , ... + state , data ) + if ( this.outputcommand <> "" ) then + // + // Setup the callback and its arguments + // + funtype = typeof(this.outputcommand) + if ( funtype == "function" ) then + __optimbase_f__ = this.outputcommand + // + // Backward-compatibility: process the outputcommandarg field + // + if ( typeof(this.outputcommandarg) == "string" ) then + __optimbase_args__ = list() + else + __optimbase_args__ = list(this.outputcommandarg) + end + else + __optimbase_f__ = this.outputcommand(1) + __optimbase_args__ = list(this.outputcommand(2:$)) + end + // + // Callback the output + // + stop = __optimbase_f__ ( state , data , __optimbase_args__(1:$) ) + // + // Backward-compatibility: define the stop variable + // + if ( exists("stop")==0 ) then + optb_warnheaderobsolete ( "outputfun(state,data)" , "stop=outputfun(state,data)", "5.4.1" ) + stop = %f + end + end +endfunction + +function optb_warnheaderobsolete ( oldheader , newheader , removedVersion ) + warnMessage = msprintf(_("Calling sequence %s is obsolete."),oldheader) + warnMessage = [warnMessage, msprintf(_("Please use %s instead."),newheader)] + warnMessage = [warnMessage, msprintf(_("This feature will be permanently removed in Scilab %s"), removedVersion)] + warning(warnMessage); +endfunction + + diff --git a/modules/optimization/macros/optimbase/optimbase_outstruct.bin b/modules/optimization/macros/optimbase/optimbase_outstruct.bin Binary files differnew file mode 100755 index 000000000..3d02fa8a6 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_outstruct.bin diff --git a/modules/optimization/macros/optimbase/optimbase_outstruct.sci b/modules/optimization/macros/optimbase/optimbase_outstruct.sci new file mode 100755 index 000000000..20c84962a --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_outstruct.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_outstruct -- +// Returns a tlist with basic optimization fields. +// This struct may be enriched by children (specialize) optimization methods. +// Arguments +// this : the current object +// +function data = optimbase_outstruct ( this ) + if this.outputcommand == "" then + errmsg = msprintf( gettext ( "%s: No output command is defined.") , "optimbase_outstruct" ) + error(errmsg) + else + data = tlist(["T_OPTDATA",... + "x","fval","iteration","funccount"]); + data.x = this.xopt; + data.fval = this.fopt; + data.iteration = this.iterations; + data.funccount = this.funevals; + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_proj2bnds.bin b/modules/optimization/macros/optimbase/optimbase_proj2bnds.bin Binary files differnew file mode 100755 index 000000000..4c490c35d --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_proj2bnds.bin diff --git a/modules/optimization/macros/optimbase/optimbase_proj2bnds.sci b/modules/optimization/macros/optimbase/optimbase_proj2bnds.sci new file mode 100755 index 000000000..92887fba1 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_proj2bnds.sci @@ -0,0 +1,41 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_proj2bnds -- +// Returns a point, which is the projection +// of the given point into the bounds. +// Arguments +// this : the current object +// x : the point to project +// p : the projected point +// +function [ this , p ] = optimbase_proj2bnds ( this , x ) + [ this , hasbounds ] = optimbase_hasbounds ( this ) + if ( ~hasbounds ) then + p = x + return + end + p = x + for ix = 1:this.numberofvariables + xmin = this.boundsmin ( ix ) + xmax = this.boundsmax ( ix ) + pix = p ( ix ) + if (pix > xmax) then + this = optimbase_log ( this , sprintf ( "Projecting p(%d) = %s on max bound %s" , ix , string(pix) , string(xmax) )) + p ( ix ) = xmax + elseif ( pix < xmin) then + this = optimbase_log ( this , sprintf ( "Projecting p(%d) = %s on min bound %s" , ix , string(pix) , string(xmin) )) + p ( ix ) = xmin + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_set.bin b/modules/optimization/macros/optimbase/optimbase_set.bin Binary files differnew file mode 100755 index 000000000..348d765a1 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_set.bin diff --git a/modules/optimization/macros/optimbase/optimbase_set.sci b/modules/optimization/macros/optimbase/optimbase_set.sci new file mode 100755 index 000000000..e01b1cd77 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_set.sci @@ -0,0 +1,53 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_set -- +// Set the value for the given key. +// If the key is unknown, generates an error. +// +function this = optimbase_set ( this , key , value ) + [lhs,rhs]=argn(); + if ( rhs <> 3 ) then + errmsg = msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"), "optimbase_set", 3); + error(errmsg) + end + select key + case "-iterations" then + this.iterations = value; + case "-xopt" then + this.xopt = value; + case "-fopt" then + this.fopt = value; + case "-historyxopt" then + if ( ~this.storehistory ) then + errmsg = msprintf( gettext ( "%s: History disabled ; turn on -storehistory option.") , "optimbase_set" ) + error(errmsg) + else + this.historyxopt = value; + end + case "-historyfopt" then + if ( ~this.storehistory ) then + errmsg = msprintf(gettext ( "%s: History disabled ; turn on -storehistory option.") , "optimbase_set" ) + error(errmsg) + else + this.historyfopt = value; + end + case "-fx0" then + this.fx0 = value; + case "-status" then + this.status = value; + else + errmsg = msprintf(gettext ( "%s: Unknown key %s") , "optimbase_set", key ) + error(errmsg) + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_stoplog.bin b/modules/optimization/macros/optimbase/optimbase_stoplog.bin Binary files differnew file mode 100755 index 000000000..58c3405da --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_stoplog.bin diff --git a/modules/optimization/macros/optimbase/optimbase_stoplog.sci b/modules/optimization/macros/optimbase/optimbase_stoplog.sci new file mode 100755 index 000000000..c5f3adc75 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_stoplog.sci @@ -0,0 +1,23 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimbase_stoplog -- +// Prints the given stopping rule message if verbose termination is enabled. +// If verbose termination is disabled, does nothing. +// +function this = optimbase_stoplog ( this , msg ) + if ( this.verbose == 1 ) then + if ( this.verbosetermination == 1 ) then + this = optimbase_log ( this , msg ) + end + end +endfunction + diff --git a/modules/optimization/macros/optimbase/optimbase_terminate.bin b/modules/optimization/macros/optimbase/optimbase_terminate.bin Binary files differnew file mode 100755 index 000000000..1b6d5dc21 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_terminate.bin diff --git a/modules/optimization/macros/optimbase/optimbase_terminate.sci b/modules/optimization/macros/optimbase/optimbase_terminate.sci new file mode 100755 index 000000000..b9575e8d9 --- /dev/null +++ b/modules/optimization/macros/optimbase/optimbase_terminate.sci @@ -0,0 +1,129 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimbase_terminate -- +// Returns %t if the algorithm terminates. +// Returns %f if the algorithm must continue. +// Arguments, input +// this : the current object +// previousfopt : the previous value of the objective function +// currentfopt : the current value of the objective function +// previousxopt : the previous value of x +// currentxopt : the current value of x +// terminate : 1 if the algorithm terminates, 0 if the algorithm must continue. +// Arguments, output +// status : termination status +// status = "continue" +// status = "maxiter" +// status = "maxfuneval" +// status = "tolf" +// status = "tolx" +// +function [ this , terminate , status ] = optimbase_terminate (this , ... + previousfopt , currentfopt , previousxopt , currentxopt ) + terminate = %f; + status = "continue"; + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > Termination ?")); + end + // + // Criteria #1 : maximum number of iterations + // + if ( ~terminate ) then + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > iterations=%d >= maxiter=%d",this.iterations, this.maxiter)); + end + if ( this.iterations >= this.maxiter ) then + terminate = %t; + status = "maxiter"; + if warning("query") =="on" then + msg = "%s: Exiting: Maximum number of iterations has been exceeded\n" + ... + " - increase MaxIter option.\n"; + mprintf(gettext(msg) , "optimbase_terminate" ) + end + end + end + // + // Criteria #2 : maximum number of call to function + // + if ( ~terminate ) then + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > funevals=%d >= maxfunevals=%d",this.funevals, this.maxfunevals)); + end + if ( this.funevals >= this.maxfunevals ) then + terminate = %t; + status = "maxfuneval"; + if warning("query") =="on" then + msg = "%s: Exiting: Maximum number of function evaluations has been exceeded\n" + ... + " - increase MaxFunEvals option.\n" + mprintf(gettext(msg) , "optimbase_terminate" ) + end + end + end + // + // Criteria #3 : tolerance on function + // Note : + // This termination criteria works well in the special case where the function + // value at optimum is several order of magnitude smaller + // than the initial function value (ie f(x0)). + // This is the case when the function value at optimum is zero. + // When the function value at optimum is non-zero, or if the + // initial function value is strictly positive (e.g. f(x0)=10) + // and the optimum function value is strictly negative (e.g. f(x*)=-10), + // that criteria fails miserably. + // + if ( ~terminate ) then + if ( this.tolfunmethod ) + tolfr = this.tolfunrelative; + tolfa = this.tolfunabsolute; + acfopt = abs(currentfopt); + apfopt = abs(previousfopt); + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > abs(currentfopt)=%s < tolfunrelative * abs(previousfopt) + tolfunabsolute=%s",... + string(acfopt), string(tolfr * apfopt + tolfa))); + end + if ( acfopt < tolfr * apfopt + tolfa ) then + terminate = %t; + status = "tolf"; + end + end + end + // + // Criteria #4 : tolerance on x + // Note + // What means a relative error on x ? + // Notes: if xn and xn+1 are very close to xopt and xopt different from 0, + // the relative error between xn and xn+1 is small. + // But if xopt, xn and xn+1 are close to 0, the relative error may be a + // completely wrong criteria. The absolute tolerance should be used in this case. + // + if ( ~terminate ) then + if ( this.tolxmethod ) then + normdelta = norm(currentxopt - previousxopt); + normold = norm(currentxopt); + tolxr = this.tolxrelative; + tolxa = this.tolxabsolute; + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > e(x)=%s < %s * %s + %s",... + string(normdelta), string(tolxr) , string(normold) , string(tolxa) )); + end + if ( normdelta < tolxr * normold + tolxa ) then + terminate = %t; + status = "tolx"; + end + end + end + if ( this.verbose == 1 ) then + this = optimbase_stoplog (this,sprintf(" > Terminate = %s, status = %s",... + string(terminate) , status )); + end +endfunction diff --git a/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.bin b/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.bin Binary files differnew file mode 100755 index 000000000..cbabcd893 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.bin diff --git a/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.sci b/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.sci new file mode 100755 index 000000000..a0a3feeae --- /dev/null +++ b/modules/optimization/macros/optimsimplex/%TSIMPLEX_p.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TSIMPLEX_p -- +// Prints the string containing the Optim Simplex component. +// +function %TSIMPLEX_p ( this ) + str = string ( this ) + srows = size(str,"r") + for i = 1 : srows + mprintf("%s\n",str(i)) + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.bin b/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.bin Binary files differnew file mode 100755 index 000000000..27df88c5e --- /dev/null +++ b/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.bin diff --git a/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.sci b/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.sci new file mode 100755 index 000000000..7b539d93a --- /dev/null +++ b/modules/optimization/macros/optimsimplex/%TSIMPLEX_string.sci @@ -0,0 +1,38 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// %TSIMPLEX_string -- +// Returns the string containing the Optim Simplex component. +// +function str = %TSIMPLEX_string ( this ) + function str = mysize(x) + [n,m]=size(x) + if ( n==0 & m==0 ) then + str = sprintf("[] matrix"); + else + str = sprintf("%d-by-%d matrix\n",n,m); + end + endfunction + + str = [] + k = 1 + str(k) = sprintf("Optim Simplex Object:\n") + k = k + 1 + str(k) = sprintf("=====================") + k = k + 1 + str(k) = sprintf("nbve: %d\n",this.nbve); + k = k + 1 + str(k) = sprintf("n: %d\n",this.n); + k = k + 1 + str(k) = sprintf("x: %s\n",mysize(this.x)); + k = k + 1 + str(k) = sprintf("fv: %s\n",mysize(this.fv)); +endfunction + diff --git a/modules/optimization/macros/optimsimplex/lib b/modules/optimization/macros/optimsimplex/lib Binary files differnew file mode 100755 index 000000000..bff4cb992 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/lib diff --git a/modules/optimization/macros/optimsimplex/names b/modules/optimization/macros/optimsimplex/names new file mode 100755 index 000000000..0567c2059 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/names @@ -0,0 +1,37 @@ +%TSIMPLEX_p +%TSIMPLEX_string +optimsimplex_center +optimsimplex_check +optimsimplex_compsomefv +optimsimplex_computefv +optimsimplex_deltafv +optimsimplex_deltafvmax +optimsimplex_destroy +optimsimplex_dirmat +optimsimplex_fvmean +optimsimplex_fvstdev +optimsimplex_fvvariance +optimsimplex_getall +optimsimplex_getallfv +optimsimplex_getallx +optimsimplex_getfv +optimsimplex_getn +optimsimplex_getnbve +optimsimplex_getve +optimsimplex_getx +optimsimplex_gradientfv +optimsimplex_log +optimsimplex_new +optimsimplex_reflect +optimsimplex_setall +optimsimplex_setallfv +optimsimplex_setallx +optimsimplex_setfv +optimsimplex_setn +optimsimplex_setnbve +optimsimplex_setve +optimsimplex_setx +optimsimplex_shrink +optimsimplex_size +optimsimplex_sort +optimsimplex_xbar diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_center.bin b/modules/optimization/macros/optimsimplex/optimsimplex_center.bin Binary files differnew file mode 100755 index 000000000..716833e7f --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_center.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_center.sci b/modules/optimization/macros/optimsimplex/optimsimplex_center.sci new file mode 100755 index 000000000..f8b12e6a2 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_center.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_center -- +// Returns the center of the given simplex +// Arguments +// <no arg> +// +function sicenter = optimsimplex_center ( this ) + sicenter = mean(this.x,"r"); +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_check.bin b/modules/optimization/macros/optimsimplex/optimsimplex_check.bin Binary files differnew file mode 100755 index 000000000..2566bbedc --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_check.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_check.sci b/modules/optimization/macros/optimsimplex/optimsimplex_check.sci new file mode 100755 index 000000000..98809e8a0 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_check.sci @@ -0,0 +1,39 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimsimplex_check -- +// Check the consistency of the internal data. +// Generates an error if necessary. +// Arguments +// <no arg> +// +function optimsimplex_check ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_check", 1)); + end + nx1 = size(this.x,1) + nx2 = size(this.x,2) + if this.nbve<> 0 & nx1 <> this.nbve then + error(msprintf(gettext("%s: Number of rows of x is %d, which is different from number of vertices = %d."),"optimsimplex_check" , nx1 , this.nbve )); + end + if this.n<> 0 & nx2 <> this.n then + error(msprintf(gettext("%s: Number of columns of x is %d, which is different from dimension = %d."),"optimsimplex_check" , nx2 , this.n )); + end + nf1 = size(this.fv,1) + nf2 = size(this.fv,2) + if this.n<> 0 & nf1 <> this.nbve then + error(msprintf(gettext("%s: Number of rows of fv is %d, which is different from number of vertices = %d."),"optimsimplex_check" , nf1 , this.nbve )); + end + if this.nbve<> 0 & nf2 <> 1 then + error(msprintf(gettext("%s: Number of columns of fv is %d, which is different from 1."),"optimsimplex_check" , nf2 )); + end +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.bin Binary files differnew file mode 100755 index 000000000..b7ac45794 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.sci new file mode 100755 index 000000000..9ef137d43 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_compsomefv.sci @@ -0,0 +1,63 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_compsomefv -- +// Set the values of the function at given vertices. +// Arguments +// fun : the function to compute at vertices +// indices : the indices of the vertices to compute +// data : user-defined data +// +function [ this , data ] = optimsimplex_compsomefv ( varargin ) + function argin = argindefault ( rhs , vararglist , ivar , default ) + // Returns the value of the input argument #ivar. + // If this argument was not provided, or was equal to the + // empty matrix, returns the default value. + if ( rhs < ivar ) then + argin = default + else + if ( typeof(vararglist(ivar))== "constant" ) then + if ( vararglist(ivar) <> [] ) then + argin = vararglist(ivar) + else + argin = default + end + else + argin = vararglist(ivar) + end + end + endfunction + [lhs,rhs]=argn(); + if ( rhs<3 | rhs>4 ) then + errmsg = msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"), "optimsimplex_computefv", 3,4); + error(errmsg) + end + this = varargin(1) + fun = varargin(2) + indices = argindefault ( rhs , varargin , 3 , this.nbve ) + data = argindefault ( rhs , varargin , 4 , [] ) + if ( typeof(data)=="constant" ) then + if ( data==[] ) then + for j = indices; + this.fv(j) = fun (this.x(j,:)); + end + else + for j = indices; + [ this.fv(j) , data ] = fun ( this.x(j,:) , data ); + end + end + else + for j = indices; + [ this.fv(j) , data ] = fun ( this.x(j,:) , data ); + end + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_computefv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_computefv.bin Binary files differnew file mode 100755 index 000000000..d3324a3ff --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_computefv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_computefv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_computefv.sci new file mode 100755 index 000000000..7d9f48fdc --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_computefv.sci @@ -0,0 +1,55 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_computefv -- +// Set the values of the function at vertices points. +// Arguments +// fun : the function to compute at vertices +// data : user-defined data +// +function [ this , data ] = optimsimplex_computefv ( varargin ) + function argin = argindefault ( rhs , vararglist , ivar , default ) + // Returns the value of the input argument #ivar. + // If this argument was not provided, or was equal to the + // empty matrix, returns the default value. + if ( rhs < ivar ) then + argin = default + else + if ( typeof(vararglist(ivar))== "constant" ) then + if ( vararglist(ivar) <> [] ) then + argin = vararglist(ivar) + else + argin = default + end + else + argin = vararglist(ivar) + end + end + endfunction + [lhs,rhs]=argn(); + if (rhs>3) then + errmsg = msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"), "optimsimplex_computefv", 2,3); + error(errmsg) + end + this = varargin(1) + fun = varargin(2) + data = argindefault ( rhs , varargin , 3 , [] ) + if (typeof(data)=="constant") then + if ( data == [] ) then + this = optimsimplex_compsomefv ( this , fun , 1:this.nbve ) + else + [ this , data ] = optimsimplex_compsomefv ( this , fun , 1:this.nbve , data ) + end + else + [ this , data ] = optimsimplex_compsomefv ( this , fun , 1:this.nbve , data ) + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.bin Binary files differnew file mode 100755 index 000000000..bd2d99bbf --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.sci new file mode 100755 index 000000000..35fbea7a7 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_deltafv.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_deltafv -- +// Returns the vector of difference of function +// values with respect to the function value at vertex #1. +// Arguments +// <no arg> +// +function df = optimsimplex_deltafv ( this ) + df = this.fv(2:this.nbve) - this.fv(1)*ones(this.nbve-1,1) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.bin b/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.bin Binary files differnew file mode 100755 index 000000000..9680e562a --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.sci b/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.sci new file mode 100755 index 000000000..1108a4b2e --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_deltafvmax.sci @@ -0,0 +1,27 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_deltafvmax -- +// Returns the difference of function +// value between the high and the low vertices. +// It is expected that the vertex #1 is associated with +// the smallest function value and that the vertex #nbve +// is associated with the highest function value. +// Arguments +// <no arg> +// Note +// Since vertices are ordered, the high +// is greater than the low. +// +function dfm = optimsimplex_deltafvmax ( this ) + dfm = this.fv(this.nbve) - this.fv(1) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_destroy.bin b/modules/optimization/macros/optimsimplex/optimsimplex_destroy.bin Binary files differnew file mode 100755 index 000000000..9d5006703 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_destroy.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_destroy.sci b/modules/optimization/macros/optimsimplex/optimsimplex_destroy.sci new file mode 100755 index 000000000..f75d39b5e --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_destroy.sci @@ -0,0 +1,19 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_destroy -- +// Destroy the given object. +// +function this = optimsimplex_destroy (this) + this.x = []; + this.fv = []; +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.bin b/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.bin Binary files differnew file mode 100755 index 000000000..2f68dfc29 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.sci b/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.sci new file mode 100755 index 000000000..b027c2e5e --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_dirmat.sci @@ -0,0 +1,24 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_dirmat -- +// Returns the n x n matrix of simplex directions i.e. +// the matrix of differences of vertices coordinates +// with respect to the vertex #1. +// Arguments +// <no arg> +// +function m = optimsimplex_dirmat ( this ) + nv = this.nbve; + v1 = this.x(1,1:this.n); + m(1:this.n,1:nv-1) = (this.x(2:nv,1:this.n) - v1 .*. ones(nv-1,1)).'; +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.bin b/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.bin Binary files differnew file mode 100755 index 000000000..c4108f4e1 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.sci b/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.sci new file mode 100755 index 000000000..a30ed1c44 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvmean.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_fvmean -- +// Returns the mean of the function +// value on the simplex. +// Arguments +// <no arg> +// +function sd = optimsimplex_fvmean ( this ) + sd = mean(this.fv) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.bin b/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.bin Binary files differnew file mode 100755 index 000000000..e5ad4f162 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.sci b/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.sci new file mode 100755 index 000000000..4a5153847 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvstdev.sci @@ -0,0 +1,21 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_fvstdev -- +// Returns the standard deviation of the function +// value on the simplex. +// Arguments +// <no arg> +// +function sd = optimsimplex_fvstdev ( this ) + sd = stdev(this.fv) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.bin b/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.bin Binary files differnew file mode 100755 index 000000000..a779b40e8 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.sci b/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.sci new file mode 100755 index 000000000..094032ac3 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_fvvariance.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_fvvariance -- +// Returns the variance function values +// Arguments +// <no arg> +// +function df = optimsimplex_fvvariance ( this ) + df = variance ( this.fv(1:this.nbve) ) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getall.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getall.bin Binary files differnew file mode 100755 index 000000000..ebf2e2e92 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getall.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getall.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getall.sci new file mode 100755 index 000000000..90afc7576 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getall.sci @@ -0,0 +1,28 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getall -- +// Returns all the coordinates of all the vertices and the function values +// in the same matrix, with size nbve X n+1, which is organized as follows : +// * data is organized by row : function value, then x +// * simplex(k,1) is the function value of the vertex #k, with kve = 1 , nbve +// * simplex(k,2:n+1) is the coordinates of the vertex #k, with kve = 1 , nbve +// Arguments +// <no arg> +// +function simplex = optimsimplex_getall ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getall", 1)); + end + simplex = zeros ( this.nbve , this.n+1 ); + simplex ( 1:this.nbve , 1 ) = this.fv ( 1:this.nbve , 1 ) + simplex ( 1:this.nbve , 2:this.n+1 ) = this.x ( 1:this.nbve , 1:this.n ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.bin Binary files differnew file mode 100755 index 000000000..3525c2d44 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.sci new file mode 100755 index 000000000..c7ce57c11 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getallfv.sci @@ -0,0 +1,25 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getallfv -- +// Returns all the function values of all the vertices, +// as a column vector. +// The function value of vertex #k is stored in fv(k) +// with k = 1 , nbve +// Arguments +// <no arg> +// +function fv = optimsimplex_getallfv ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getallfv", 1)); + end + fv = this.fv ( 1:this.nbve , 1 ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getallx.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getallx.bin Binary files differnew file mode 100755 index 000000000..becbd57d6 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getallx.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getallx.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getallx.sci new file mode 100755 index 000000000..636b404f6 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getallx.sci @@ -0,0 +1,24 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getallx -- +// Returns all the coordinates of all the vertices. +// The vertex #k is stored in x(1:n,k) +// with k = 1 , nbve +// Arguments +// <no arg> +// +function x = optimsimplex_getallx ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getallx", 1)); + end + x = this.x ( 1:this.nbve , 1:this.n ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getfv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getfv.bin Binary files differnew file mode 100755 index 000000000..64c43a1af --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getfv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getfv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getfv.sci new file mode 100755 index 000000000..93ad303ee --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getfv.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getfv -- +// Returns the function value at given index +// Arguments +// ive : vertex index +// +function fv = optimsimplex_getfv ( this , ive ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getfv", 1)); + end + if type(ive) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_getfv", 2)); + end + if or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_getfv", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_getfv", 2)); + end + fv = this.fv ( ive , 1 ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getn.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getn.bin Binary files differnew file mode 100755 index 000000000..175fa15fc --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getn.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getn.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getn.sci new file mode 100755 index 000000000..efdc3c26e --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getn.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getn -- +// Returns the dimension of the space of the simplex +// Arguments +// <no arg> +// +function n = optimsimplex_getn ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getn", 1)); + end + n = this.n +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.bin Binary files differnew file mode 100755 index 000000000..4c0f81c84 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.sci new file mode 100755 index 000000000..105d24025 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getnbve.sci @@ -0,0 +1,22 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getnbve -- +// Returns the number of vertices in the simplex +// Arguments +// <no arg> +// +function n = optimsimplex_getnbve ( this ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getnbve", 1)); + end + n = this.nbve +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getve.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getve.bin Binary files differnew file mode 100755 index 000000000..74bf51cee --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getve.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getve.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getve.sci new file mode 100755 index 000000000..0a0167eea --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getve.sci @@ -0,0 +1,32 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getve -- +// Returns the vertex at given index as a tlist, +// with fields n, x and fv +// Arguments +// ive : vertex index +// +function vertex = optimsimplex_getve ( this , ive ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getve", 1)); + end + if type(ive) <> 1| or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_getve", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_getve", 2)); + end + vertex = tlist(["T_VERTEX","x","n","fv"]); + vertex.n = this.n; + vertex.x = this.x ( ive , : ); + vertex.fv = this.fv ( ive ); +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getx.bin b/modules/optimization/macros/optimsimplex/optimsimplex_getx.bin Binary files differnew file mode 100755 index 000000000..757c37e37 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getx.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_getx.sci b/modules/optimization/macros/optimsimplex/optimsimplex_getx.sci new file mode 100755 index 000000000..038b66a5c --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_getx.sci @@ -0,0 +1,32 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_getx -- +// Returns the coordinates of the vertex at given index, +// as a row vector. +// Arguments +// ive : vertex index +// +function x = optimsimplex_getx ( this , ive ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_getx", 1)); + end + if type(ive) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_getx", 2)); + end + if or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_getx", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_getx", 2)); + end + x = this.x ( ive , : ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.bin Binary files differnew file mode 100755 index 000000000..663e96cc0 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.sci new file mode 100755 index 000000000..bbc728b0b --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_gradientfv.sci @@ -0,0 +1,70 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_gradientfv -- +// Returns the simplex gradient of the function. +// Arguments +// fun : the function to use +// method : the method to use, "forward" or "centered" +// data : user-defined data, added to the function if provided +// +function [ g , data ] = optimsimplex_gradientfv ( this , fun , method , data ) + if ( this.nbve <> this.n+1 ) then + errmsg = msprintf(gettext("%s: The gradient can be applied only with a simplex made of n+1 points, but the dimension is %d and the number of vertices is %d"), "optimsimplex_gradientfv" , this.n , this.nbve) + error(errmsg) + end + if (~isdef("method","local")) then + method = "forward"; + end + select method + case "forward" then + g = optimsimplex_gradforward ( this ) + case "centered" then + if (~isdef("data","local")) then + g = optimsimplex_gradcenter ( this , fun ) + else + [ g , data ] = optimsimplex_gradcenter ( this , fun , data ) + end + else + errmsg = msprintf(gettext("%s: Unknown method %s"),"optimsimplex_gradientfv",method) + error(errmsg) + end +endfunction +// +// optimsimplex_gradforward -- +// Returns the simplex forward gradient of the function. +// Arguments +// <no arg> +// +function g = optimsimplex_gradforward ( this ) + v = optimsimplex_dirmat ( this ) + d = optimsimplex_deltafv ( this ) + g = v.'\d +endfunction +// +// optimsimplex_gradcenter -- +// Returns the simplex centered gradient of the function. +// Arguments +// fun : name of the function +// data : user-defined data +// +function [ g , data ] = optimsimplex_gradcenter ( this , fun , data ) + g1 = optimsimplex_gradforward ( this ) + if (~isdef("data","local")) then + r = optimsimplex_reflect ( this , fun ) + else + [ r , data ] = optimsimplex_reflect ( this , fun , data ) + end + g2 = optimsimplex_gradforward ( r ) + g = (g1 + g2)/2 + r = optimsimplex_destroy ( r ) +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_log.bin b/modules/optimization/macros/optimsimplex/optimsimplex_log.bin Binary files differnew file mode 100755 index 000000000..8769bef38 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_log.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_log.sci b/modules/optimization/macros/optimsimplex/optimsimplex_log.sci new file mode 100755 index 000000000..77c61b74a --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_log.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_log -- +// Prints the given message. +// +function this = optimsimplex_log (this,msg) + if this.verbose == 1 then + mprintf("%s\n",msg); + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_new.bin b/modules/optimization/macros/optimsimplex/optimsimplex_new.bin Binary files differnew file mode 100755 index 000000000..bf2cde4a6 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_new.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_new.sci b/modules/optimization/macros/optimsimplex/optimsimplex_new.sci new file mode 100755 index 000000000..26e5b2cc1 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_new.sci @@ -0,0 +1,534 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_new -- +// Creates a new simplex object. +// Note +// * n is the dimension of the space +// * one vertex is a point in the space, defined +// by its n coordinates and associated with a function +// value +// * the simplex is made of k>=n+1 vertices +// * the function value for vertex #kve is in fv(kve), +// with kve = 1 , k +// * the vertex #kve is stored in x(kve,1:n) +// with kve = 1 , k +// Arguments +// coords : list of point coordinates in the simplex +// fun : the function to compute at vertices +// data : user-defined data, passed to the function +// Uses : +// newobj = optimsimplex_new ( ) +// newobj = optimsimplex_new ( coords ) +// newobj = optimsimplex_new ( coords , fun ) +// [ newobj , data ] = optimsimplex_new ( coords , fun , data ) +// newobj = optimsimplex_new ( "axes" , x0 ) +// newobj = optimsimplex_new ( "axes" , x0 , fun ) +// newobj = optimsimplex_new ( "axes" , x0 , fun , len ) +// [ newobj , data ] = optimsimplex_new ( "axes" , x0 , fun , len , data ) +// newobj = optimsimplex_new ( "spendley" , x0 ) +// newobj = optimsimplex_new ( "spendley" , x0 , fun ) +// newobj = optimsimplex_new ( "spendley" , x0 , fun , len ) +// [ newobj , data ] = optimsimplex_new ( "spendley" , x0 , fun , len , data ) +// newobj = optimsimplex_new ( "pfeffer" , x0 ) +// newobj = optimsimplex_new ( "pfeffer" , x0 , fun ) +// newobj = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual ) +// newobj = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual , deltazero ) +// [ newobj , data ] = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual , deltazero , data ) +// newobj = optimsimplex_new ( "randbounds" , x0 , fun , boundsmin , boundsmax , nbve ) +// [ newobj , data ] = optimsimplex_new ( "randbounds" , x0 , fun , boundsmin , boundsmax , nbve , data ) +// newobj = optimsimplex_new ( "oriented" , simplex0 ) +// newobj = optimsimplex_new ( "oriented" , simplex0 , fun ) +// [ newobj , data ] = optimsimplex_new ( "oriented" , simplex0 , fun , data ) +// +function [ newobj , data ] = optimsimplex_new ( varargin ) + function newobj = optimsimplex_coords ( varargin ) + // newobj = optimsimplex_coords ( ) + // newobj = optimsimplex_coords ( coords ) + [lhs,rhs]=argn(); + if ( rhs> 1 ) then + errmsg = msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"), "optimsimplex_coords", 0,1); + error(errmsg) + end + coords = argindefault ( rhs , varargin , 1 , [] ) + assert_typereal ( coords , "coords" , 1 ); + newobj = tlist(["TSIMPLEX",... + "verbose","x","n","fv","nbve"]); + newobj.verbose = 0; + // The dimension of the space + newobj.n = 0; + // The number of vertices + newobj.nbve = 0; + // The coordinates of the vertices, with size nbve x n + newobj.x = []; + // The function values, with size nbve x 1 + newobj.fv = []; + // + // Take input arguments into account + // + if ( coords<>[] ) then + nbve = size(coords,1) + n = size(coords,2) + if nbve < n + 1 then + error(msprintf(gettext("%s: The numbers of columns of coords is %d but is expected to be at least %d"),... + "optimsimplex_new" , nbve , n + 1)) + end + newobj.n = n; + newobj.nbve = nbve; + newobj.x(1:nbve,1:n) = coords(1:nbve,1:n); + end + endfunction + // + // optimsimplex_axes -- + // Configure the current simplex so that it is computed from the axes and a length. + // Arguments + // x0 : the initial point, as a row vector + // length : the length of the simplex + // If length is a value, that unique length + // is used in all directions. + // If length is a vector with n values, each + // length is used with the corresponding + // direction. + // + function newobj = optimsimplex_axes ( x0 , len ) + newobj = optimsimplex_coords ( ) + n = length(x0); + newobj.n = n; + newobj.nbve = n + 1; + nl=length(len) + if ( nl==1 ) then + xlen = len * ones(1,n) + else + xlen = len + end + newobj.x = zeros ( newobj.nbve , n ) + newobj.fv = zeros ( newobj.nbve , 1 ) + // + // Set all points + // + nv = newobj.nbve; + newobj.x ( 1:nv , : ) = x0 (1:n) .*. ones(nv,1); + newobj.x ( 2:nv , : ) = newobj.x ( 2:nv , : ) + diag(xlen); + endfunction + + // + // optimsimplex_spendley -- + // Configure the current simplex so that it is computed from Spendley's method, + // i.e. a regular simplex made of k = n+1 vertices. + // Arguments + // x0 : the initial point, as a row vector + // len : the length of the simplex + // + function newobj = optimsimplex_spendley ( x0 , len ) + newobj = optimsimplex_coords ( ) + n = length(x0); + newobj.n = n; + newobj.nbve = n + 1; + newobj.x = zeros ( n+1 , n ) + newobj.fv = zeros ( n+1 , 1 ) + // + // Compute p (diagonal term) , q (off-diagonal term) + // + p = (n - 1.0 + sqrt(n + 1))/(n * sqrt(2.0)) + q = (sqrt(n + 1) - 1.0)/(n * sqrt(2.0)) + // + // Set all points + // + nv = newobj.nbve; + newobj.x ( 1:nv , : ) = x0 (1:n) .*. ones(nv,1); + newobj.x ( 2:nv , : ) = newobj.x ( 2:nv , : ) + diag(ones(n,1)*p) + q*ones(n,n) - diag(ones(n,1)*q); + endfunction + + // + // optimsimplex_pfeffer -- + // Configure the current simplex so that it is computed from Pfeffer's method, + // i.e. a relative delta for non-zero values and an absolute delta + // for zero values. + // Arguments + // x0 : the initial point, as a row vector + // deltausual : the absolute delta for non-zero values + // deltazero : the absolute delta for zero values + // References + // "Global Optimization Of Lennard-Jones Atomic Clusters" + // Ellen Fan, Thesis, February 26, 2002, McMaster University + // Method due to L. Pfeffer at Stanford + // + function newobj = optimsimplex_pfeffer ( x0 , deltausual , deltazero ) + newobj = optimsimplex_coords ( ) + n = length(x0); + newobj.n = n; + newobj.nbve = n + 1; + newobj.x = zeros ( n+1 , n ) + newobj.fv = zeros ( n+1 , 1 ) + // + // Set 1st point + // + newobj.x ( 1 , 1:n ) = x0 (1,1:n) + // + // Set points #2 to #n+1 + // + for j = 2 : newobj.n+1 + newobj.x ( j,1:n ) = x0 (1:n) + if ( x0( j-1 ) == 0.0 ) then + newobj.x ( j , j-1 ) = deltazero + else + newobj.x ( j , j-1 ) = newobj.x ( j , j-1 ) + deltausual * x0( j-1 ) + end + end + endfunction + + // + // optimsimplex_randbounds -- + // Configure the current simplex so that it is computed by taking the bounds + // into account with random scaling. + // Arguments + // x0 : the initial point + // boundsmin : array of minimum bounds + // boundsmax : array of maximum bounds + // nbve : total number of vertices in the simplex + // + function newobj = optimsimplex_randbounds ( x0 , boundsmin , boundsmax , nbve ) + newobj = optimsimplex_coords ( ) + newobj.n = n; + newobj.nbve = nbve; + newobj.x = zeros ( nbve , n ) + newobj.fv = zeros ( nbve , 1 ) + // + // Set 1st point + // + newobj.x ( 1 , 1:n ) = x0 (1:n) + // + // Set points #2 to #nbve, by randomizing the bounds + // + bminmat = boundsmin( 1,1:n ) .*. ones(nbve-1,1); + bmaxmat = boundsmax( 1,1:n ) .*. ones(nbve-1,1); + thetas = rand(n,nbve-1); + newobj.x ( 2:nbve , 1:n ) = bminmat + (thetas.') .* (bmaxmat - bminmat) + endfunction + + // + // optimsimplex_oriented -- + // Returns an oriented simplex, in sorted order. + // This simplex may be used, as Kelley suggests + // for a restart of Nelder-Mead algorithm. + // Arguments + // fun : the function to compute at vertices + // + function newobj = optimsimplex_oriented ( simplex0 ) + sgrad = optimsimplex_gradientfv ( simplex0 ) + ssize = optimsimplex_size ( simplex0 , "sigmaminus" ) + n = simplex0.n + // Compute the betas + ipos = find(sgrad >= 0.0); + ineg = find(sgrad < 0.0); + betav(ipos) = ssize; + betav(ineg) = -ssize; + betav = -0.5 * betav + // Prepare a matrix with beta as diagonal terms + mid = diag(betav); + // Compute simplex + newobj = optimsimplex_new() + newobj.n = simplex0.n + newobj.nbve = simplex0.n+1 + newobj.x = zeros ( n+1 , n ) + newobj.fv = zeros ( n+1 , 1 ) + // Store all points + x1 = simplex0.x ( 1 , 1:n ) + newobj.x ( 1:n+1, 1:n ) = x1 ( 1 , 1:n ) .*. ones(n+1,1) + // Retrieve the function value for the first simplex + // This saves one function evaluation + newobj.fv ( 1 ) = simplex0.fv ( 1 ) + newobj.x ( 2:n+1, 1:n ) = mid ( 1:n , 1:n ) + newobj.x ( 2:n+1, 1:n ) + endfunction + + // Generates an error if the given variable is not of type real + function assert_typereal ( var , varname , ivar ) + if ( type ( var ) <> 1 ) then + errmsg = msprintf(gettext("%s: Expected real variable for variable %s at input #%d, but got %s instead."),"assert_typereal", varname , ivar , typeof(var) ); + error(errmsg); + end + endfunction + // Generates an error if the given variable is not of type string + function assert_typestring ( var , varname , ivar ) + if ( type ( var ) <> 10 ) then + errmsg = msprintf(gettext("%s: Expected string variable for variable %s at input #%d, but got %s instead."),"assert_typestring", varname , ivar , typeof(var) ); + error(errmsg); + end + endfunction + // Generates an error if the given variable is not of type function (macro) + function assert_typefunction ( var , varname , ivar ) + if ( type ( var ) <> 13 ) then + errmsg = msprintf(gettext("%s: Expected function but for variable %s at input #%d, got %s instead."),"assert_typefunction", varname , ivar , typeof(var) ); + error(errmsg); + end + endfunction + // Generates an error if the given variable is not of type boolean + function assert_typeboolean ( var , varname , ivar ) + if ( type ( var ) <> 4 ) then + errmsg = msprintf(gettext("%s: Expected boolean but for variable %s at input #%d, got %s instead."),"assert_typeboolean", varname , ivar , typeof(var) ); + error(errmsg); + end + endfunction + + // Generates an error if the value corresponding to an option is unknown. + function unknownValueForOption ( value , optionname ) + errmsg = msprintf(gettext("%s: Unknown value %s for %s option"),"unknownValueForOption",value , optionname ); + error(errmsg); + endfunction + + function argin = argindefault ( rhs , vararglist , ivar , default ) + // Returns the value of the input argument #ivar. + // If this argument was not provided, or was equal to the + // empty matrix, returns the default value. + if ( rhs < ivar ) then + argin = default + else + if ( typeof(vararglist(ivar))== "constant" ) then + if ( vararglist(ivar) <> [] ) then + argin = vararglist(ivar) + else + argin = default + end + else + argin = vararglist(ivar) + end + end + endfunction + + [lhs,rhs]=argn(); + if rhs>7 then + errmsg = msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"), "optimsimplex_new", 0,7); + error(errmsg) + end + if rhs == 0 then + newobj = optimsimplex_coords ( ) + return; + end + var1 = varargin(1); + data = [] + if typeof(var1) == "string" then + stype = varargin(1); + select stype + case "axes" then + // newobj = optimsimplex_new ( "axes" , x0 ) + // newobj = optimsimplex_new ( "axes" , x0 , fun ) + // newobj = optimsimplex_new ( "axes" , x0 , fun , len ) + // [ newobj , data ] = optimsimplex_new ( "axes" , x0 , fun , len , data ) + if rhs<2 | rhs > 5 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 2 to 5 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + x0 = varargin(2); + fun = argindefault ( rhs , varargin , 3 , [] ) + len = argindefault ( rhs , varargin , 4 , 1.0 ) + data = argindefault ( rhs , varargin , 5 , [] ) + // + // Check inputs + // + assert_typereal ( x0 , "x0" , 3 ); + assert_typereal ( len , "len" , 1 ); + if size(x0,1)<>1 then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",2,1,size(x0,2)); + error(errmsg); + end + if ( fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + if ( size(len,1)<>1 ) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",4,1,size(len,2)); + error(errmsg); + end + if ( size(len,"*") <> 1 ) + if ( size ( len , 2 ) <> size ( x0 , 2 ) ) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",4,size(len,1),size(x0,2)); + error(errmsg); + end + end + newobj = optimsimplex_axes ( x0 , len ) + case "spendley" then + // newobj = optimsimplex_new ( "spendley" , x0 ) + // newobj = optimsimplex_new ( "spendley" , x0 , fun ) + // newobj = optimsimplex_new ( "spendley" , x0 , fun , len ) + // [ newobj , data ] = optimsimplex_new ( "spendley" , x0 , fun , len , data ) + if rhs<2 | rhs > 5 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 2 to 5 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + x0 = varargin(2); + fun = argindefault ( rhs , varargin , 3 , [] ) + len = argindefault ( rhs , varargin , 4 , 1.0 ) + data = argindefault ( rhs , varargin , 5 , [] ) + // + // Check inputs + // + assert_typereal ( x0 , "x0", 1 ); + if ( fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + assert_typereal ( len , "len" , 3 ); + if size(x0,1)<>1 then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",2,1,size(x0,2)); + error(errmsg); + end + if ( size(len)<>[1 1] ) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",4,1,1); + error(errmsg); + end + newobj = optimsimplex_spendley ( x0 , len ) + case "pfeffer" then + // newobj = optimsimplex_new ( "pfeffer" , x0 ) + // newobj = optimsimplex_new ( "pfeffer" , x0 , fun ) + // newobj = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual ) + // newobj = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual , deltazero ) + // [ newobj , data ] = optimsimplex_new ( "pfeffer" , x0 , fun , deltausual , deltazero , data ) + if rhs<2 | rhs > 6 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 2 to 6 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + x0 = varargin(2); + fun = argindefault ( rhs , varargin , 3 , [] ) + deltausual = argindefault ( rhs , varargin , 4 , 0.05 ) + deltazero = argindefault ( rhs , varargin , 5 , 0.0075 ) + data = argindefault ( rhs , varargin , 6 , [] ) + // + // Check inputs + // + assert_typereal ( x0 , "x0" , 1 ); + assert_typereal ( deltausual , "deltausual", 3 ); + assert_typereal ( deltazero , "deltazero" , 4 ); + if size(x0,1)<>1 then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",2,1,size(x0,2)); + error(errmsg); + end + if (size(deltausual)<>[1 1]) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",3,1,1); + error(errmsg); + end + if (size(deltazero)<>[1 1]) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",4,1,1); + error(errmsg); + end + if ( fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + newobj = optimsimplex_pfeffer ( x0 , deltausual , deltazero ) + case "randbounds" then + // newobj = optimsimplex_new ( "randbounds" , x0 , fun , boundsmin , boundsmax ) + // newobj = optimsimplex_new ( "randbounds" , x0 , fun , boundsmin , boundsmax , nbve ) + // [ newobj , data ] = optimsimplex_new ( "randbounds" , x0 , fun , boundsmin , boundsmax , nbve , data ) + if rhs<5 | rhs > 7 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 6 to 7 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + x0 = varargin(2); + fun = varargin(3); + boundsmin = varargin(4); + boundsmax = varargin(5); + n = length ( x0 ) + nbve = argindefault ( rhs , varargin , 6 , n+1 ) + data = argindefault ( rhs , varargin , 7 , [] ) + // + // Check inputs + // + assert_typereal ( x0 , "x0", 1 ); + if ( fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + assert_typereal ( boundsmin , "boundsmin" , 3 ); + assert_typereal ( boundsmax , "boundsmax" , 4 ); + assert_typereal ( nbve , "nbve" , 5 ); + if ( size(x0,1)<>1 ) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",2,1,size(x0,2)); + error(errmsg); + end + if ( size(boundsmin,1)<>1 | size(boundsmin,2)<>size(x0,2)) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",4,1,size(x0,2)); + error(errmsg); + end + if ( size(boundsmax,1)<>1 | size(boundsmax,2)<>size(x0,2)) then + errmsg = msprintf(gettext("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"optimsimplex_new",5,1,size(x0,2)); + error(errmsg); + end + + newobj = optimsimplex_randbounds ( x0 , boundsmin , boundsmax , nbve ) + case "oriented" then + // newobj = optimsimplex_new ( "oriented" , simplex0 ) + // newobj = optimsimplex_new ( "oriented" , simplex0 , fun ) + // [ newobj , data ] = optimsimplex_new ( "oriented" , simplex0 , fun , data ) + if rhs<2 | rhs > 4 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 2 to 4 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + simplex0 = varargin(2); + fun = argindefault ( rhs , varargin , 3 , [] ) + data = argindefault ( rhs , varargin , 4 , [] ) + // + // Check inputs + // + if (typeof(simplex0)<> "TSIMPLEX") then + errmsg = msprintf(gettext ( "%s: Wrong type for argument #%d: %s expected.\n") , "optimsimplex_new",2,"TSIMPLEX") + error(errmsg) + end + if (fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + if ( simplex0.nbve == [] ) then + errmsg = msprintf(gettext ( "%s: The initial simplex has no vertices.") , "optimsimplex_new") + error(errmsg) + end + if ( simplex0.n == [] ) then + errmsg = msprintf(gettext ( "%s: The initial simplex has no dimension.") , "optimsimplex_new") + error(errmsg) + end + if ( simplex0.nbve <> simplex0.n+1 ) then + errmsg = msprintf(gettext ( "%s: The oriented simplex can be computed only with a simplex made of n+1 points, but the dimension is %d and the number of vertices is %d") , "optimsimplex_new", simplex0.n , simplex0.nbve) + error(errmsg) + end + + newobj = optimsimplex_oriented ( simplex0 ) + else + errmsg = msprintf(gettext("%s: Unknown key %s"),"optimsimplex_new",key) + error(errmsg) + end + else + // newobj = optimsimplex_new ( coords ) + // newobj = optimsimplex_new ( coords , fun ) + // [ newobj , data ] = optimsimplex_new ( coords , fun , data ) + if rhs < 1 | rhs > 3 then + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while 1 to 3 are expected."), "optimsimplex_new", rhs); + error(errmsg) + end + coords = varargin(1); + fun = argindefault ( rhs , varargin , 2 , [] ) + data = argindefault ( rhs , varargin , 3 , [] ) + // + // Check inputs + // + if (fun <> [] ) then + assert_typefunction ( fun , "fun" , 2 ); + end + newobj = optimsimplex_coords ( coords ) + end + // + // Compute function values, if required. + if ( fun<>[] ) then + if ( typeof(data)=="constant" ) then + if ( data==[] ) then + newobj = optimsimplex_computefv ( newobj , fun ) + else + [ newobj , data ] = optimsimplex_computefv ( newobj , fun , data ) + end + else + [ newobj , data ] = optimsimplex_computefv ( newobj , fun , data ) + end + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_reflect.bin b/modules/optimization/macros/optimsimplex/optimsimplex_reflect.bin Binary files differnew file mode 100755 index 000000000..333eb5464 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_reflect.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_reflect.sci b/modules/optimization/macros/optimsimplex/optimsimplex_reflect.sci new file mode 100755 index 000000000..8f3af4809 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_reflect.sci @@ -0,0 +1,38 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_reflect -- +// Returns a new simplex by reflexion of current simplex, by reflection with respect +// to the first vertex in the simplex. +// This move is used in the centered simplex gradient. +// Arguments +// fun : name of the function +// data : user-defined data +// +function [ r , data ] = optimsimplex_reflect ( this , fun , data ) + nv = this.nbve; + n = this.n; + r = optimsimplex_new ( ); + r.n = n + r.nbve = nv + r.x = zeros ( nv , n ) + r.fv = zeros( nv , 1 ) + r.x(1,1:n) = this.x(1,1:n); + r.fv(1) = this.fv(1); + twox1 = 2*this.x(1,1:n) .*. ones(nv-1,1); + r.x(2:nv,1:r.n) = twox1 - this.x(2:nv,1:n) ; + if (~isdef("data","local")) then + r = optimsimplex_compsomefv ( r , fun , 2:nv ) + else + [ r , data ] = optimsimplex_compsomefv ( r , fun , 2:nv , data ) + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setall.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setall.bin Binary files differnew file mode 100755 index 000000000..1fe4f1d41 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setall.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setall.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setall.sci new file mode 100755 index 000000000..7de5cd0b5 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setall.sci @@ -0,0 +1,39 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setall -- +// Set all the coordinates and the function values of all the vertices. +// The given matrix is expected to have the following organization +// * size nbve X n+1 +// * data is organized by row : function value, then x +// * simplex(k,1) is the function value of the vertex #k, with k = 1 , nbve +// * simplex(k,2:n+1) is the coordinates of the vertex #k, with k = 1 , nbve +// Arguments +// simplex : the simplex to set +// +function this = optimsimplex_setall ( this , simplex ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setall", 1)); + end + if type(simplex) <> 1 | ~isreal(simplex) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "optimsimplex_setall", 2)); + end + nbve = size(simplex,1) + np1 = size(simplex,2) + if np1 > nbve then + errmsg = msprintf(gettext ( "%s: The number of vertices (i.e. the number of rows) is %d which is smaller than the number of columns %d (i.e. n+1).") , "optimsimplex_setall",nbve,np1); + error(errmsg); + end + this.n = np1 - 1; + this.nbve = nbve; + this.fv ( 1:nbve , 1 ) = simplex ( 1:nbve , 1 ) + this.x ( 1:nbve , 1:this.n ) = simplex ( 1:nbve , 2:this.n+1 ) +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.bin Binary files differnew file mode 100755 index 000000000..33753f1b4 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.sci new file mode 100755 index 000000000..652a58360 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setallfv.sci @@ -0,0 +1,35 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setallfv -- +// Set all the function values of all the vertices. +// The vertex #k is expected to be stored in fv(k) +// with k = 1 , nbve +// Arguments +// fv : the array of function values +// +function this = optimsimplex_setallfv ( this , fv ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setallfv", 1)); + end + if type(fv) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real vector expected.\n"), "optimsimplex_setallfv", 2)); + end + fv1 = size ( fv , 1 ); + if fv1 <> this.nbve then + error ( msprintf ( gettext ( "%s: The number of rows in the function value array is %d, while expected %d." ), "optimsimplex_setallfv" , fv1 , this.nbve )) + end + fv2 = size ( fv , 2 ); + if fv2 <> 1 then + error ( msprintf ( gettext ( "%s: The number of columns in the function value array is %d, while expected 1." ), "optimsimplex_setallfv" , fv2 )) + end + this.fv ( 1:this.nbve , 1 ) = fv ( 1:this.nbve ); +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setallx.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setallx.bin Binary files differnew file mode 100755 index 000000000..a432415b8 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setallx.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setallx.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setallx.sci new file mode 100755 index 000000000..02dd7d8cc --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setallx.sci @@ -0,0 +1,35 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setallx -- +// Set all the coordinates of all the vertices. +// The vertex #k is expected to be stored in x(k,1:n) +// with k = 1 , nbve +// Arguments +// x : the coordinates of the vertices. +// +function this = optimsimplex_setallx ( this , x ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setallx", 1)); + end + if type(x) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "optimsimplex_setallx", 2)); + end + nx1 = size ( x , 1 ); + if nx1 <> this.nbve then + error ( msprintf ( gettext ( "%s: The number of rows in x is %d, while expected %d." ), "optimsimplex_setallx" , nx1 , this.nbve )) + end + nx2 = size ( x , 2 ); + if nx2 <> this.n then + error ( msprintf ( gettext ( "%s: The number of columns in x is %d, while expected %d." ), "optimsimplex_setallx" , nx2 , this.n )) + end + this.x ( 1:this.nbve , 1:this.n ) = x ( 1:this.nbve , 1:this.n ); +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setfv.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setfv.bin Binary files differnew file mode 100755 index 000000000..2a5c3ba56 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setfv.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setfv.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setfv.sci new file mode 100755 index 000000000..e74dae7cd --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setfv.sci @@ -0,0 +1,36 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setfv -- +// Set the function value at given index and +// returns an updated simplex. +// Arguments +// ive : vertex index +// fv : the function value +// +function this = optimsimplex_setfv ( this , ive , fv ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setfv", 1)); + end + if type(ive) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_setfv", 2)); + end + if type(fv) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real vector expected.\n"), "optimsimplex_setfv", 3)); + end + if or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_setfv", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_setfv", 2)); + end + this.fv ( ive , 1 ) = fv; +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setn.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setn.bin Binary files differnew file mode 100755 index 000000000..1cc811587 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setn.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setn.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setn.sci new file mode 100755 index 000000000..277e21057 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setn.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setn -- +// Set the dimension of the space of the simplex. +// Arguments +// n : the dimension +// +function this = optimsimplex_setn ( this , n ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setn", 1)); + end + if type(n) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_setn", 2)); + end + if or(size(n) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_setn", 2)); + end + if n-floor(n) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_setn", 2)); + end + this.n = n; +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.bin Binary files differnew file mode 100755 index 000000000..10a937de5 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.sci new file mode 100755 index 000000000..dcbf4a850 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setnbve.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setnbve -- +// Set the number of vertices of the simplex. +// Arguments +// nbve : the number of vertices +// +function this = optimsimplex_setnbve ( this , nbve ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setnbve", 1)); + end + if type(nbve) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_setnbve", 2)); + end + if or(size(nbve) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_setnbve", 2)); + end + if nbve-floor(nbve) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_setnbve", 2)); + end + this.nbve = nbve; +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setve.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setve.bin Binary files differnew file mode 100755 index 000000000..703aed9db --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setve.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setve.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setve.sci new file mode 100755 index 000000000..4e94bd68d --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setve.sci @@ -0,0 +1,40 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setve -- +// Sets the coordinates of the vertex and the function value at given index in the current simplex. +// Arguments +// ive : vertex index +// fv : the function value +// x : the coordinates of the point, as a row vector +// +function this = optimsimplex_setve ( this , ive , fv , x ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setve", 1)); + end + if type(ive) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_setve", 2)); + end + if type(fv) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real vector expected.\n"), "optimsimplex_setve", 3)); + end + if type(x) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "optimsimplex_setve", 4)); + end + if or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_setve", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_setve", 2)); + end + this.x(ive,:) = x; + this.fv(ive,1) = fv; +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setx.bin b/modules/optimization/macros/optimsimplex/optimsimplex_setx.bin Binary files differnew file mode 100755 index 000000000..231be06b7 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setx.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_setx.sci b/modules/optimization/macros/optimsimplex/optimsimplex_setx.sci new file mode 100755 index 000000000..5cb2d3fbd --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_setx.sci @@ -0,0 +1,35 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_setx -- +// Set the coordinates of the vertex at given index, +// as a row vector, into the current simplex. +// Arguments +// ive : vertex index +// +function this = optimsimplex_setx ( this , ive , x ) + if typeof(this) <> "TSIMPLEX" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: TSIMPLEX expected.\n"), "optimsimplex_setx", 1)); + end + if type(ive) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "optimsimplex_setx", 2)); + end + if type(x) <> 1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "optimsimplex_setx", 3)); + end + if or(size(ive) <> [1 1]) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "optimsimplex_setx", 2)); + end + if ive-floor(ive) <> 0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer expected.\n"), "optimsimplex_setx", 2)); + end + this.x ( ive , 1:this.n ) = x(1:this.n); +endfunction diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_shrink.bin b/modules/optimization/macros/optimsimplex/optimsimplex_shrink.bin Binary files differnew file mode 100755 index 000000000..da64577c0 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_shrink.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_shrink.sci b/modules/optimization/macros/optimsimplex/optimsimplex_shrink.sci new file mode 100755 index 000000000..2db5e5386 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_shrink.sci @@ -0,0 +1,36 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_shrink -- +// Shrink the simplex with given coefficient sigma +// and returns an updated simplex. +// The shrink is performed with respect to the 1st point +// in the simplex. +// Arguments +// fun : the function to compute at vertices +// sigma : shrinkage factor (default value = 0.5) +// data : user-defined data +// +function [ this , data ] = optimsimplex_shrink ( this , fun , sigma , data ) + if (~isdef("sigma","local")) then + sigma = 0.5; + end + nv = this.nbve; + mv1 = this.x(1,:) .*. ones ( nv - 1 , 1 ); + newx = ( 1.0 - sigma ) * mv1(1:nv-1,:) + sigma * this.x ( 2 : nv , : ) ; + this.x(2:nv,:) = newx(1:nv-1,:); + if (~isdef("data","local")) then + this = optimsimplex_compsomefv ( this , fun , 2 : nv ) + else + [ this , data ] = optimsimplex_compsomefv ( this , fun , 2 : nv , data ) + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_size.bin b/modules/optimization/macros/optimsimplex/optimsimplex_size.bin Binary files differnew file mode 100755 index 000000000..2fd83ee33 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_size.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_size.sci b/modules/optimization/macros/optimsimplex/optimsimplex_size.sci new file mode 100755 index 000000000..3e21fd724 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_size.sci @@ -0,0 +1,64 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_size -- +// Returns the size of the simplex. +// Arguments, input +// method : the method to use to compute the simplex, "Nash" +// "diameter", "sigmaplus" or "sigmaminus" (default is "sigmaplus") +// References +// [1] Compact Numerical Methods For Computers +// Linear Algebra and Function Minimization +// J.C. Nash +// 1990 +// Chapter 14. Direct Search Methods +// [2] Iterative Methods for Optimization +// C.T. Kelley +// 1999 +// Chapter 6., section 6.2 +// +function ssize = optimsimplex_size ( this , method ) + n = this.n; + nv = this.nbve; + if (~isdef("method","local")) then + method = "sigmaplus"; + end + select method + case "Nash" then + v1 = this.x(1,:) .*. ones(nv-1,1); + edges = this.x(2:nv,:) - v1; + abedges = abs(edges); + n1 = sum(abedges,"c"); + ssize = sum ( n1 ); + case "diameter" then + ssize = 0.0; + for i = 1:nv + vi = this.x(i,:) .*. ones(nv,1); + edges = vi - this.x(1:nv,:); + n2 = sqrt ( sum ( edges.^2 , "c" ) ); + ssize = max ( max( n2 ) , ssize ); + end + case "sigmaplus" then + v1 = this.x(1,:) .*. ones(nv-1,1); + edges = this.x(2:nv,:) - v1; + n2 = sqrt ( sum ( edges.^2 , "c" ) ); + ssize = max ( n2 ); + case "sigmaminus" then + v1 = this.x(1,:) .*. ones(nv-1,1); + edges = this.x(2:nv,:) - v1; + n2 = sqrt ( sum ( edges.^2 , "c" ) ); + ssize = min ( n2 ); + else + errmsg = msprintf(gettext ( "%s: Unknown simplex size method %s") , "optimsimplex_size",method) + error(errmsg) + end +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_sort.bin b/modules/optimization/macros/optimsimplex/optimsimplex_sort.bin Binary files differnew file mode 100755 index 000000000..630fc3e62 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_sort.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_sort.sci b/modules/optimization/macros/optimsimplex/optimsimplex_sort.sci new file mode 100755 index 000000000..6c4c7a3ac --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_sort.sci @@ -0,0 +1,23 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + + +// +// optimsimplex_sort -- +// Sorts the simplex with increasing function value order so that +// the smallest function value is at vertex #1. +// Arguments +// <no arg> +// +function this = optimsimplex_sort ( this ) + [this.fv,is] = gsort(this.fv,"r","i"); + this.x = this.x ( is , : ); +endfunction + diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_xbar.bin b/modules/optimization/macros/optimsimplex/optimsimplex_xbar.bin Binary files differnew file mode 100755 index 000000000..fbda36636 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_xbar.bin diff --git a/modules/optimization/macros/optimsimplex/optimsimplex_xbar.sci b/modules/optimization/macros/optimsimplex/optimsimplex_xbar.sci new file mode 100755 index 000000000..041bc5357 --- /dev/null +++ b/modules/optimization/macros/optimsimplex/optimsimplex_xbar.sci @@ -0,0 +1,36 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2008-2009 - INRIA - Michael Baudin +// Copyright (C) 2009-2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +// +// optimsimplex_xbar -- +// Returns the center of n vertices, by excluding the +// vertex with index iexcl. +// The default value of iexcl is the number of vertices : in that case, +// if the simplex is sorted in increasing function value +// order, the worst vertex is excluded. +// Arguments +// iexcl : the index of the vertex to exclude in +// center computation. +// +function cen = optimsimplex_xbar ( this , iexcl ) + if (~isdef("iexcl","local")) then + iexcl = this.nbve; + end + if ( size(iexcl,1)<>1 ) then + errmsg = msprintf(gettext("%s: The exclusion index vector has %d rows instead of 1."), ... + "optimsimplex_xbar", size(iexcl,1) ); + error(errmsg); + end + // Vectorize by making the sum of all, subtracting only one vector + cen = sum(this.x(1:this.nbve,1:this.n),"r") + cen = cen - sum(this.x(iexcl,1:this.n),"r") + nexcl = size(iexcl,2) + cen = cen / ( this.nbve - nexcl ) +endfunction diff --git a/modules/optimization/macros/pack.bin b/modules/optimization/macros/pack.bin Binary files differnew file mode 100755 index 000000000..0a69255c5 --- /dev/null +++ b/modules/optimization/macros/pack.bin diff --git a/modules/optimization/macros/pack.sci b/modules/optimization/macros/pack.sci new file mode 100755 index 000000000..3e17d02a6 --- /dev/null +++ b/modules/optimization/macros/pack.sci @@ -0,0 +1,55 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// Copyright (C) 2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [M, sel] = pack(M, blocksizes) + // + // Check input arguments + [lhs, rhs] = argn(); + if rhs <> 2 then + error(msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"),"pack",2)); + end + // + // Check type + if and(typeof(M) <> ["constant" "sparse"]) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix or sparse matrix expected.\n"),"pack",1)); + end + if typeof(blocksizes) <> "constant" then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"pack",2)); + end + // + // Check content + if ~isreal(M) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"pack",1)); + end + if ~isreal(blocksizes) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"pack",2)); + end + if or(blocksizes<1) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Non-negative integers expected.\n"),"pack",2)); + end + if or(blocksizes<>floor(blocksizes)) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer value expected.\n"),"pack",2)); + end + // + // Proceed... + sel = [] + kk = 0 + blocksizes = matrix(blocksizes, 1, size(blocksizes,"*")) + for ni=blocksizes + k = kk + for j=1:ni + sel = [sel, k+(j:ni)] + k = k+ni + end + kk = kk+ni*ni + end + M = M(sel, :) + +endfunction diff --git a/modules/optimization/macros/pencost.bin b/modules/optimization/macros/pencost.bin Binary files differnew file mode 100755 index 000000000..c67d88361 --- /dev/null +++ b/modules/optimization/macros/pencost.bin diff --git a/modules/optimization/macros/pencost.sci b/modules/optimization/macros/pencost.sci new file mode 100755 index 000000000..ee1150413 --- /dev/null +++ b/modules/optimization/macros/pencost.sci @@ -0,0 +1,78 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [fpen,gpen,ind]=pencost(x,ind,fncts,ne,nc,cpen); + // pencost=template of external function for penalized problem: + // + // min f(x) + // g_i(x) = 0 i=1:ne + // g_i(x) <= 0 i=ne+1:nc (0<=ne<=nc) + // + //function pencost defines a penalized cost function and its gradient + //which is passed to scilab's optim function. + // + //A penalized problem is defined through the scilab function fncts + //which defines the constraints g_1,..,g_nc and the cost function f. + // + //fncts = scilab external with calling sequence: + //[gisandf,theirgrads,indic]=fncts(x,indic) + //which returns + // in row vector gisandf [g_1(x),...,g_nc(x),f(x)] + // + // in column 1 of matrix theirgrads grad(g_1)_x + //.......... + // in column i of matrix theirgrads grad(g_i)_x + //........... + // in column nc of matrix theirgrads grad(g_nc)_x + // in column nc+1 of matrix theirgrads grad(g_nc)_x + // + // ne = number of equality constraints + // nc = total number of constraints + // + //EXAMPLE: + // + //minimize f(x)=0.5*(x(1)^2+x(2)^2) + // g_1(x)= x(1)+x(2)-1 <=0 + // g_2(x)=- x(1) <= 0 + // + // no equality constraint (ne=0) + // two inequality constraints (-> nc=2 constraints) + // + // 1-define your problem through a function (usually in a .sci file): + //deff('[gsf,grds,indic]=myproblem(x,indic)',... + // 'gsf=[x(1)+x(2)-1,-x(1),norm(x)^2];... + // grds=[1,-1,x(1);... + // 1,0,x(2)]') + // + // 2-call scilab's optim function (after loading pencost.sci (this file)); + // exec('pencost.sci','c') + // ne=0;nc=2;x0=[4;7]; + // penalizing constant cpen=100; + // [f,x]=optim(list(pencost,myproblem,ne,nc,cpen),x0) + // + // or (passing myproblem,ne,nc,cpen by context) + // fncts=myproblem;[f,x]=optim(pencost,x0) + // + [f,gradf,indic]=fncts(x,ind); + if indic < 0 then ind=indic, return, end; + if nc >ne then + for i=ne+1:nc, f(i)=max([0 f(i)]); end; + end; + fpen=f(nc+1) + 0.5*cpen*norm(f(1:nc))^2; + if ind==2 then return, end; + gpen=gradf(:,nc+1); + if ne >0 then + for i=1:ne, gpen=gpen + cpen*f(i)*gradf(:,i),end; + end; + if nc > ne + for i=ne+1:nc, + if f(i)>0 then gpen=gpen + cpen*f(i)*gradf(:,i),end; + end; + end; +endfunction diff --git a/modules/optimization/macros/qpsolve.bin b/modules/optimization/macros/qpsolve.bin Binary files differnew file mode 100755 index 000000000..67072e3ff --- /dev/null +++ b/modules/optimization/macros/qpsolve.bin diff --git a/modules/optimization/macros/qpsolve.sci b/modules/optimization/macros/qpsolve.sci new file mode 100755 index 000000000..6841a6f88 --- /dev/null +++ b/modules/optimization/macros/qpsolve.sci @@ -0,0 +1,34 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2013 - Raise Partner - Mohamed Houacine: fixed bug #13116 +// Copyright (C) INRIA - Serge Steer +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// + +function [x, iact, iter, f]=qpsolve(Q,p,C,b,ci,cs,me) + + rhs = argn(2); + if rhs <> 7 + error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "qpsolve", 7)); + end + C(me+1:$, :) = -C(me+1:$, :); + b(me+1:$) = -b(me+1:$); + // replace boundary contraints by linear constraints + Cb = []; bb = []; + if ci <> [] then + Cb = [Cb; speye(Q)] + bb = [bb; ci] + end + if cs <> [] then + Cb = [Cb; -speye(Q)] + bb = [bb; -cs] + end + C = [C; Cb]; b = [b; bb] + [x, iact, iter, f] = qp_solve(Q, -p, C', b, me) + +endfunction + diff --git a/modules/optimization/macros/recons.bin b/modules/optimization/macros/recons.bin Binary files differnew file mode 100755 index 000000000..5066244bd --- /dev/null +++ b/modules/optimization/macros/recons.bin diff --git a/modules/optimization/macros/recons.sci b/modules/optimization/macros/recons.sci new file mode 100755 index 000000000..791198cde --- /dev/null +++ b/modules/optimization/macros/recons.sci @@ -0,0 +1,42 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function [r,ind]=recons(r,ind) + //reconstruct a list from a flat list (see aplat) + if ind==-1 then return;end + nr=size(r) + ma=0 + for k=nr:-1:1 + mm=size(ind(k),"*"); + if ma<=mm then ma=mm;ki=k; end + end + + if ma<=1 then return; end + vi=ind(ki);vi=vi(1:ma-1); + k=ki + vj=vi + + while vj==vi + k=k+1 + if k>nr then break; end + vv=ind(k); + if size(vv,"*")==ma then vj=vv(1:ma-1); else vj=[]; end + end + kj=k-1 + rt=list(r(ki)) + for k=ki+1:kj + rt(k-ki+1)=r(ki+1) + r(ki+1)=null() + ind(ki+1)=null() + end + ind(ki)=vi + r(ki)=rt + [r,ind]=recons(r,ind) + +endfunction diff --git a/modules/optimization/macros/unpack.bin b/modules/optimization/macros/unpack.bin Binary files differnew file mode 100755 index 000000000..4ba454de8 --- /dev/null +++ b/modules/optimization/macros/unpack.bin diff --git a/modules/optimization/macros/unpack.sci b/modules/optimization/macros/unpack.sci new file mode 100755 index 000000000..7e86e0bd2 --- /dev/null +++ b/modules/optimization/macros/unpack.sci @@ -0,0 +1,59 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// Copyright (C) 2011 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function MM=unpack(M,blocksizes) + // + // Check input arguments + [lhs,rhs]=argn(); + if rhs<>2 then + error(msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"),"unpack",2)); + end + // + // Check type + if typeof(M) <> "constant" then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"unpack",1)); + end + if typeof(blocksizes) <> "constant" then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"unpack",2)); + end + // + // Check content + if ~isreal(M) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"unpack",1)); + end + if ~isreal(blocksizes) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real matrix expected.\n"),"unpack",2)); + end + if or(blocksizes<1) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Non-negative integers expected.\n"),"unpack",2)); + end + if or(blocksizes<>floor(blocksizes)) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: An integer value expected.\n"),"unpack",2)); + end + // + // Proceed... + MM=[] + [mM,nM]=size(M) + n=sum(blocksizes) + for j=1:nM + ptr=1 + Mu=[] + for ni=blocksizes + Mui=[] + for l=1:ni + Mui(l:ni,l)=M(ptr:ptr+ni-l,j) + Mui(l,l:ni)=M(ptr:ptr+ni-l,j)' + ptr=ptr+ni-l+1 + end + Mu=[Mu;matrix(Mui,ni*ni,1)] + end + MM=[MM,Mu] + end +endfunction diff --git a/modules/optimization/macros/vec2list.bin b/modules/optimization/macros/vec2list.bin Binary files differnew file mode 100755 index 000000000..f4cb2ad90 --- /dev/null +++ b/modules/optimization/macros/vec2list.bin diff --git a/modules/optimization/macros/vec2list.sci b/modules/optimization/macros/vec2list.sci new file mode 100755 index 000000000..b55923cbf --- /dev/null +++ b/modules/optimization/macros/vec2list.sci @@ -0,0 +1,31 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +// +function li=vec2list(bigVector,varsizes,ind) + //bigVector: big vector + //varsizes: k x 2 matrix, varsizes(i,:)=size of ith matrix + //li: list of k matrices, li(i)=matrix of size varsizes(i,:); + + [LHS, RHS] = argn(0) + if RHS < 2 then + error(sprintf(gettext("%s: Wrong number of input argument(s): %d or %d expected.\n"), "vec2list", 2, 3)); + end + + if bigVector==[] then + n=0;for dimi=varsizes',n=n+prod(dimi);end + bigVector=zeros(n,1); + end + li=list();point=1;i=0; + for dimi=varsizes' + newpoint=point+prod(dimi)-1;i=i+1; + li(i)=matrix(bigVector(point:newpoint),dimi(1),dimi(2)); + point=newpoint+1; + end + if RHS==3 then li=recons(li,ind); end +endfunction |