From d6f2ec1ad170a36f781baef1bb0159a90bab737e Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Fri, 19 Sep 2008 12:49:13 +0000 Subject: [PATCH] Merging mk rev. 211, 212: Matlab interface now works with binary data using uint32 (GAIndividualIntegerData). --- .../@JEInterface/JEInterface.m | 16 +- .../@JEInterface/convertUnsignedJE.m | 14 + .../MatlabInterface/@JEInterface/getResult.m | 4 + .../@JEInterface/runEvalLoopJE.m | 25 +- .../@JEInterface/setResultJE.m | 1 - .../go/individuals/AbstractEAIndividual.java | 32 +- .../individuals/GAIndividualIntegerData.java | 28 +- .../codings/ga/GAStandardCodingInteger.java | 2 +- .../go/problems/MatlabEvalMediator.java | 42 +- .../server/go/problems/MatlabProblem.java | 358 ++++++++---------- .../go/problems/WaitForEvARunnable.java | 60 +++ .../go/strategies/MonteCarloSearch.java | 12 +- 12 files changed, 359 insertions(+), 235 deletions(-) create mode 100644 resources/MatlabInterface/@JEInterface/convertUnsignedJE.m create mode 100644 src/eva2/server/go/problems/WaitForEvARunnable.java diff --git a/resources/MatlabInterface/@JEInterface/JEInterface.m b/resources/MatlabInterface/@JEInterface/JEInterface.m index ec96fcb7..3cc07077 100644 --- a/resources/MatlabInterface/@JEInterface/JEInterface.m +++ b/resources/MatlabInterface/@JEInterface/JEInterface.m @@ -6,7 +6,7 @@ function int = JEInterface(interfaceName, fhandle, range, varargin) % name as a String to allow callbacks from Java. % fhandle: a function handle defining the optimization target. % range: a 2 x dim array defining the solution subspace with lower and -% upper bounds. +% upper bounds - or a scalar defining the bitwidth for binary problems. % optset: (optional) an optimset struct defining optimization parameters, % especially tolerance and maximum function calls. Defaults to the % EvA2 default values. @@ -24,6 +24,11 @@ function int = JEInterface(interfaceName, fhandle, range, varargin) % and TolFun for a certain time, e.g. 100 evaluations. % To ignore a criterion, set it to 0. E.g. to perform 10^5 evaluations in % any case, set TolX=TolFun=0 and MaxFunEvals=10^5. +% +% You may define a 2xdim range with a double valued function handle or for +% binary problems set a scalar as range defining the number of bits to be +% used. The values passed to the function handle will then be arrays of +% uint32, each of them representing 32 bits. int.args = []; int.opts = optimset('MaxFunEvals', eva2.OptimizerFactory.getDefaultFitCalls, 'TolX', 1e-4, 'TolFun', 1e-4); @@ -40,6 +45,7 @@ int.funCalls = 0; int.mediator = ''; int.optParams = []; int.optParamValues = []; +int.hexMask=hex2dec('ffffffff'); if (isa(interfaceName, 'char')); int.callback = interfaceName; @@ -56,7 +62,11 @@ if (isa(range, 'double') && (size(range,1) == 2)) int.dim=length(range); int.range=transpose(range); else - error('Wrong third argument type, expected double array of 2 x dim'); + %error('Wrong third argument type, expected double array of 2 x dim'); + if (size(range,1)==size(range,2)==1) + int.range=[]; + int.dim=range; + end end int = class(int,'JEInterface'); @@ -80,7 +90,7 @@ switch nargin end % finally create the java object -int.mp = eva2.server.go.problems.MatlabProblem(int.callback, int.dim, int.range); +int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.range); diff --git a/resources/MatlabInterface/@JEInterface/convertUnsignedJE.m b/resources/MatlabInterface/@JEInterface/convertUnsignedJE.m new file mode 100644 index 00000000..a6e787f8 --- /dev/null +++ b/resources/MatlabInterface/@JEInterface/convertUnsignedJE.m @@ -0,0 +1,14 @@ +function [ z ] = convertUnsignedJE( int, x ) +%CONVERTUNSIGNEDJE Convert signed 32-bit integer to unsigned. +% Detailed explanation goes here + +z=zeros(size(x,1),size(x,2), 'uint32'); +for j=1 : size(x,1) + for i=1 : size(x,2) + if (x(j,i) < 0) + z(j,i) = 1+bitxor(uint32(-x(j,i)), int.hexMask); + else + z(j,i) = x(j,i); + end + end +end \ No newline at end of file diff --git a/resources/MatlabInterface/@JEInterface/getResult.m b/resources/MatlabInterface/@JEInterface/getResult.m index 1921d419..983a951b 100644 --- a/resources/MatlabInterface/@JEInterface/getResult.m +++ b/resources/MatlabInterface/@JEInterface/getResult.m @@ -13,6 +13,10 @@ end if (isempty(sol)) fit = NaN; else + if (isempty(int.range)) + sol=convertUnsignedJE(int, sol); + end; + if (isempty(int.args)) fit = feval(int.f, sol); else diff --git a/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m b/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m index f29b3b12..d1cd82bf 100644 --- a/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m +++ b/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m @@ -64,10 +64,24 @@ try int.mediator.run; if (~int.mediator.isFinished()) x = int.mediator.getQuestion(); - if (isempty(int.args)) - res = feval(int.f, x); - else - res = feval(int.f, x, int.args); + if (isempty(int.range)) + %size(x) + x=convertUnsignedJE(int, x); + %disp('here B'); + %x + end +% size(x) + try + if (isempty(int.args)) + res = feval(int.f, x); + else + res = feval(int.f, x, int.args); + end + %res + catch ME + disp('function evaluation failed:'); + disp(ME.message); + stopOptimization=1; end int.mediator.setAnswer(res); drawnow; @@ -79,8 +93,9 @@ try end end clear global JEMediator; -catch +catch ME disp('Error in evaluate!'); + disp(ME.message); %int.mediator.quit; % just in case %int.mediator=''; diff --git a/resources/MatlabInterface/@JEInterface/setResultJE.m b/resources/MatlabInterface/@JEInterface/setResultJE.m index 6a5edead..5785abb0 100644 --- a/resources/MatlabInterface/@JEInterface/setResultJE.m +++ b/resources/MatlabInterface/@JEInterface/setResultJE.m @@ -2,7 +2,6 @@ function int = setJEResult(int, result) % Interface function to be called by EvA2. % Write back the solution and retrieve some additional data. - int.result = result; int.finished = 1; int.msg=int.mp.getInfoString; diff --git a/src/eva2/server/go/individuals/AbstractEAIndividual.java b/src/eva2/server/go/individuals/AbstractEAIndividual.java index e19ffeae..9be63226 100644 --- a/src/eva2/server/go/individuals/AbstractEAIndividual.java +++ b/src/eva2/server/go/individuals/AbstractEAIndividual.java @@ -962,4 +962,34 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java. return isDominatingDebConstraints((AbstractEAIndividual)indy); } -} \ No newline at end of file + /** + * Return the individual data (phenotype) as BitSet, int[], double[], int[] (coding permutation) + * or InterfaceProgram[]. + * + * @param individual + * @return + */ + public static Object getIndyData(AbstractEAIndividual individual) { + if (individual instanceof InterfaceDataTypeBinary) { + BitSet b = ((InterfaceDataTypeBinary)individual).getBinaryData(); + return b; + } else if (individual instanceof InterfaceDataTypeInteger) { + int[] b = ((InterfaceDataTypeInteger)individual).getIntegerData(); + return b; + } else if (individual instanceof InterfaceDataTypeDouble) { + double[] b = ((InterfaceDataTypeDouble)individual).getDoubleData(); + return b; + } else if (individual instanceof InterfaceDataTypePermutation) { + int[] b = ((InterfaceDataTypePermutation)individual).getPermutationData()[0]; + return b; + } else if (individual instanceof InterfaceDataTypeProgram) { + InterfaceProgram[] b = ((InterfaceDataTypeProgram)individual).getProgramData(); + return b; + } else { + System.err.println("error in AbstractEAIndividual::getDefaultDataString: type " + individual.getClass() + " not implemented"); + return null; + } + } + +} + \ No newline at end of file diff --git a/src/eva2/server/go/individuals/GAIndividualIntegerData.java b/src/eva2/server/go/individuals/GAIndividualIntegerData.java index d7092dc0..23ec32f8 100644 --- a/src/eva2/server/go/individuals/GAIndividualIntegerData.java +++ b/src/eva2/server/go/individuals/GAIndividualIntegerData.java @@ -135,7 +135,7 @@ public class GAIndividualIntegerData extends AbstractEAIndividual implements Int return this.m_Range.length; } - /** This method will set the range of the double attributes. If range.length + /** This method will set the range of the integer attributes. If range.length * does not equal doubledata.length only range[i] will be used to set all * ranges. * @param range The new range for the double data. @@ -152,6 +152,32 @@ public class GAIndividualIntegerData extends AbstractEAIndividual implements Int this.setIntegerDataLength(range.length); } + /** + * Set lower and upper integer range in all dimensions. + * + * @param lower + * @param upper + */ + public void SetIntRange(int lower, int upper) { + for (int i=0; i 0) { // avoid evil case setting dim to 0 during object init + ((InterfaceDataTypeDouble)this.m_Template).setDoubleDataLength(getProblemDimension()); + ((InterfaceDataTypeDouble)this.m_Template).SetDoubleRange(range); + } + } else { + m_Template = new GAIndividualIntegerData(); + int intLen = 1+((getProblemDimension()-1)/32); + int lastIntCodingBits = getProblemDimension()-((intLen-1)*32); + if (lastIntCodingBits > 32) System.err.println("ERROR in MatlabProblem:initTemplate"); + ((GAIndividualIntegerData)m_Template).setIntegerDataLength(intLen); + ((GAIndividualIntegerData)m_Template).SetIntRange(Integer.MIN_VALUE, Integer.MAX_VALUE); + if (lastIntCodingBits < 32) ((GAIndividualIntegerData)m_Template).SetIntRange(intLen-1, 0, (int)Math.pow(2, lastIntCodingBits)-1); +// System.err.println("integer length is "+((GAIndividualIntegerData)m_Template).getIntegerData().length); +// System.err.println("Range is " + BeanInspector.toString(((GAIndividualIntegerData)m_Template).getIntRange())); +// m_Template = new GAIndividualBinaryData(); +// ((GAIndividualBinaryData)m_Template).setBinaryDataLength(getProblemDimension()); + } + } + public void setMediator(MatlabEvalMediator h) { handler = h; } - + public void initProblem() { - init(/*this.jmInterface*/ null, this.problemDimension, this.range, defTestOut); + init(this.problemDimension, range, defTestOut); } - - private void init(String nameJEInterface, int dim, double[][] rng, String outFile) { + + private void init(int dim, double[][] rng, String outFile) { problemDimension = dim; - if ((rng != null) && (dim != rng.length)) throw new ArrayIndexOutOfBoundsException("Mismatching dimension and range!"); +// if ((rng != null) && (dim != rng.length)) throw new ArrayIndexOutOfBoundsException("Mismatching dimension and range!"); range = rng; + if (range==null) isDouble = false; + else isDouble = true; + +// System.err.println("isDouble: " + isDouble); +// System.err.println("range: " + BeanInspector.toString(range)); initTemplate(); // res = new ResultArr(); if ((dos == null) && TRACE) { @@ -105,39 +131,10 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex } } - log("range is " + BeanInspector.toString(range)+ "\n"); - log("template len: " + ((ESIndividualDoubleData)m_Template).getDGenotype().length + "\n"); -// try { -// if (matlab == null) -// matlab = new Matlab();//this command links to the current matlab session -// try { -// matlab.eval("JE='hello'"); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } catch (Error e) { -// log("Error: " + e.toString()); -// System.err.println("Error: could not create MatlabProblem instance. MatlabProblem can only be used from Matlab."); -// } - -// this.jmInterface = nameJEInterface; -// mtCmd = new String("evaluateJE("+jmInterface+")"); +// log("range is " + BeanInspector.toString(range)+ "\n"); +// log("template len: " + ((ESIndividualDoubleData)m_Template).getDGenotype().length + "\n"); } - -// /** -// * @return the jmInterface -// */ -// public String getJmInterfaceName() { -// return jmInterface; -// } -// /** -// * @param jmInterface the jmInterface to set -// */ -// public void setJmInterfaceName(String jmInterface) { -// this.jmInterface = jmInterface; -// } - public void setStatsOutput(int verboLevel) { if ((verboLevel >= 0) && (verboLevel <= 3)) { verbosityLevel = verboLevel; @@ -148,7 +145,7 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex public String jmiInterfaceNameTipText() { return "Name of the JEInterface instance in Matlab"; } - + /** * @param problemDimension the problemDimension to set */ @@ -165,27 +162,27 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex return "The dimension of the problem."; } - public double[][] makeRange() { - if (range==null) range=super.makeRange(); - return range; - } +// public double[][] makeRange() { +// if (range==null) range=super.makeRange(); +// return range; +// } - protected double getRangeLowerBound(int dim) { - return (range==null) ? super.getRangeLowerBound(dim) : range[dim][0]; - } +// protected double getRangeLowerBound(int dim) { +// return (range==null) ? super.getRangeLowerBound(dim) : range[dim][0]; +// } - protected double getRangeUpperBound(int dim) { - return (range==null) ? super.getRangeUpperBound(dim) : range[dim][1]; - } +// protected double getRangeUpperBound(int dim) { +// return (range==null) ? super.getRangeUpperBound(dim) : range[dim][1]; +// } // public double[] getCurrentDoubleArray() { -// return currArray; +// return currArray; // } -// + // public double[] getNewDoubleArray() { -// currArray = new double[problemDimension]; -// for (int i=0; i 0)) { if ((specValues == null) || (specValues.length != specParams.length)) { System.err.println("mismatching value list for parameter arguments: " + specValues); @@ -267,7 +238,7 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex new Thread(new WaitForEvARunnable(runnable, this)).start(); } } - + public void startPostProcess(InterfacePostProcessParams ppp) { if (ppp.isDoPostProcessing()) { if (allowSingleRunnable && (runnable != null) && (!runnable.isFinished())) { @@ -275,17 +246,17 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex } else { handler.setFinished(false); log("\nstarting post process thread... " + BeanInspector.toString(ppp)); - // runnable.setTextListener(this); + // runnable.setTextListener(this); runnable.setDoRestart(true); runnable.setDoPostProcessOnly(true); runnable.setPostProcessingParams(ppp); - // runnable.restartOpt(); - // log("\nppp are " + BeanInspector.toString(runnable.getGOParams().getPostProcessParams())); + // runnable.restartOpt(); + // log("\nppp are " + BeanInspector.toString(runnable.getGOParams().getPostProcessParams())); new Thread(new WaitForEvARunnable(runnable, this)).start(); } } else System.err.println("Nothing to be done."); } - + /** * Request post processing of the last optimization results with given parameters * and export the result solution set to matlab. @@ -298,7 +269,7 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex PostProcessParams ppp = new PostProcessParams(steps, sigma, nBest); startPostProcess(ppp); } - + /** * Request post processing of the last optimization results with given parameters * and export the result solution set to matlab. @@ -310,7 +281,7 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex public void requestPostProcessing(int steps, double sigma) { requestPostProcessing(steps, sigma, -1); } - + public void stopOptimize() { log(">>>>>>>>>> Stop event!\n"); if (runnable != null) { @@ -325,64 +296,46 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex sb.append(runnable.terminatedBecause()); return sb.toString(); } - + public int getFunctionCalls() { if (runnable == null) return 0; return runnable.getGOParams().getOptimizer().getPopulation().getFunctionCalls(); } -// + // Matlab getMatlab() { -// return matlab; +// return matlab; // } -// + void exportResultPopulationToMatlab(Population pop) { - double[][] solSet; if ((pop != null) && (pop.size()>0)) { - solSet = new double[pop.size()][]; - for (int i=0; i