OK, Voici CalcTAT (la rule), et les deux classes qu'elle invoque: Fmin et Fcalculation. La méthode dont je parlais est dans Fcalculation (deriveF). Fmin contient une méthode cherchant le minimum de la valeur retournée par deriveF. Merci pour le coup de main Paul Eric Chatellier a écrit :
Le 24/09/2010 14:37, Paul MARCHAL a écrit :
Bonjour,
Au cours d'une simulation, j'invoque plusieurs fois, depuis une mes règles, une méthode dont la classe se trouve dans les scripts. A la première invocation, la méthode est exécutée correctement, mais à partir de la seconde, elle n'est plus exécutée du tout malgré son invocation, sans message d'erreur dans le debug.txt. J'imagine qu'il s'agit plus d'un problème de programmation Java qu'un problème directement lié à ISIS mais quelqu'un a t il une solution? J'attends de voir s'il n'y a pas de solution simple avant d'envoyer mon code.
Bonjour,
Je n'ai pas très bien compris le problème. Pourriez-vous nous envoyer le code en question ?
Merci.
-- Paul Marchal IFREMER DOP/DHMMN 150, Quai Gambetta BP 699 62321 Boulogne sur mer FRANCE Tel: (+33) 321 99 56 86 Fax: (+33) 321 99 56 01 Mail: paul.marchal@ifremer.fr /* * Copyright (C) 2010 pmarchal * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package rules; import static org.nuiton.i18n.I18n._; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import scripts.ResultName; import scripts.SiMatrix; import scripts.Fmin; import scripts.Fmin_methods; import scripts.FminTest; import scripts.Fcalculation; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.io.File; import java.io.Writer; import java.io.FileWriter; import java.io.BufferedWriter; import java.io.FileReader; import org.nuiton.math.matrix.*; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.Date; import fr.ifremer.isisfish.types.Month; import fr.ifremer.isisfish.entities.*; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.datastore.ResultStorage; import org.nuiton.util.FileUtil; /** * CalcTAC.java * * Created: 8 septembre 2010 * * @author pmarchal <anonymous@labs.libre-entreprise.org> * @version $Revision: 1545 $ * Last update: $Date: 10 septembre 2010 $ * by : $Author: pmarchal $ */ public class CalcTAC extends AbstractRule { /** to use log facility, just put in your code: log.info("..."); */ private static Log log = LogFactory.getLog(CalcTAC.class); // Output files facility; public String FichierOpti1 = "C:/Paul/DPCP/P6/DEEPFISHMAN/Science/WP5/ISIS_Output/FichierOpti1.csv"; protected File OptiFile1; public BufferedWriter outOpti1; public String [] necessaryResult = { // put here all necessary result for this rule // example: // ResultName.MATRIX_BIOMASS, // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET, }; public String[] getNecessaryResult() { return this.necessaryResult; } /** * Permet d'afficher a l'utilisateur une aide sur la regle. * @return L'aide ou la description de la regle */ public String getDescription() throws Exception { return _("TODO description rule"); } public MatrixND matrixN0; public MatrixND matrixNmsy; public MatrixND matrixNcur; public MatrixND matrixB0; public MatrixND matrixBmsy; public MatrixND matrixBcur; public MatrixND matrixCmsy; public MatrixND matrixCcur; public MatrixND matrixYmsy; public MatrixND matrixYcur; public MatrixND matrixFmsy; public MatrixND matrixFcur; public MatrixND matrixFsq; /** * Appelee au demarrage de la simulation, cette methode permet d'initialiser * des valeurs * @param simulation La simulation pour lequel on utilise cette regle */ public void init(SimulationContext context) throws Exception { Date date = new Date(0); List<Strategy> strs = SiMatrix.getSiMatrix(context).getStrategies(date); List<Metier> metiers = SiMatrix.getSiMatrix(context).getMetiers(date); List<Month> months = Arrays.asList(Month.MONTH); List<Population> populations = SiMatrix.getSiMatrix(context).getPopulations(date); List<Zone> zones = SiMatrix.getSiMatrix(context).getZones(date); OptiFile1 = new File(FichierOpti1); outOpti1 = new BufferedWriter(new FileWriter(OptiFile1, false)); } /** * La condition qui doit etre vrai pour faire les actions * @param simulation La simulation pour lequel on utilise cette regle * @return vrai si on souhaite que les actions soit faites */ public boolean condition(SimulationContext context, Date date, Metier metier) throws Exception { return date.getYear() > 0; } /** * Si la condition est vrai alors cette action est executee avant le pas * de temps de la simulation. * @param simulation La simulation pour lequel on utilise cette regle */ // Booleen permettant que ne boucler que sur un seul metier dans la preaction : boolean first = true; public void preAction(SimulationContext context, Date date, Metier metier) throws Exception { if (first){ List<Strategy> strs = SiMatrix.getSiMatrix(context).getStrategies(date); List<Metier> metiers = SiMatrix.getSiMatrix(context).getMetiers(date); List<Month> months = Arrays.asList(Month.MONTH); List<Population> populations = SiMatrix.getSiMatrix(context).getPopulations(date); List<Zone> zones = SiMatrix.getSiMatrix(context).getZones(date); ResultStorage resultmanager = context.getSimulationStorage().getResultStorage(); // Calculation of B0; the biomass available without French DW fishing; int jan1 = 12; Date datejan1 = new Date(jan1); double recruitWeight = 0.0; double recruitNumber = 0.0; if (date.compareTo(datejan1) == 0){ //loop applicable in january year 1; outOpti1.write("date"+";"+"pop"+";"+"age.getId()"+";"+ "mortNat.getValue(age.getId())"+";"+"countN0"+";"+"countB0"+";"+"cumcountB0"+";"+ "countCcur"+";"+"countNcur"+";"+"mortNat.getValue(age)"+";"+"Fcur"); outOpti1.newLine(); matrixN0 = MatrixFactory.getInstance().create( "matrixN0", new List[]{populations}, new String[]{"Populations"}); matrixNmsy = MatrixFactory.getInstance().create( "matrixNmsy", new List[]{populations}, new String[]{"Populations"}); matrixNcur = MatrixFactory.getInstance().create( "matrixNcur", new List[]{populations}, new String[]{"Populations"}); matrixB0 = MatrixFactory.getInstance().create( "matrixB0", new List[]{populations}, new String[]{"Populations"}); matrixBmsy = MatrixFactory.getInstance().create( "matrixBmsy", new List[]{populations}, new String[]{"Populations"}); matrixBcur = MatrixFactory.getInstance().create( "matrixBcur", new List[]{populations}, new String[]{"Populations"}); matrixCmsy = MatrixFactory.getInstance().create( "matrixCmsy", new List[]{populations}, new String[]{"Populations"}); matrixCcur = MatrixFactory.getInstance().create( "matrixCcur", new List[]{populations}, new String[]{"Populations"}); matrixYmsy = MatrixFactory.getInstance().create( "matrixYmsy", new List[]{populations}, new String[]{"Populations"}); matrixYcur = MatrixFactory.getInstance().create( "matrixYcur", new List[]{populations}, new String[]{"Populations"}); matrixFmsy = MatrixFactory.getInstance().create( "matrixFmsy", new List[]{populations}, new String[]{"Populations"}); Fcalculation optimFsq, optimFmsy; double Fcur; for (Population pop : populations){ int ageMin; if (pop.getName().compareTo("BlueLingSouth") == 0){ ageMin = 7; } else if (pop.getName().compareTo("Pok3a46") == 0){ ageMin = 3; } else{ ageMin = 0; } List<PopulationGroup> agegroups = pop.getPopulationGroup(); matrixFcur = MatrixFactory.getInstance().create( "matrixFcur", new List[]{populations,agegroups}, new String[]{"Populations","AgeGroups"}); matrixFsq = MatrixFactory.getInstance().create( "matrixFsq", new List[]{agegroups}, new String[]{"AgeGroups"}); MatrixND mortNat = MatrixFactory.getInstance().create( "mortNat", new List[]{agegroups}, new String[]{"AgeGroups"}); MatrixND catchYear0 = MatrixFactory.getInstance().create( "catchYear0", new List[]{agegroups}, new String[]{"AgeGroups"}); MatrixND matrixweightAA = MatrixFactory.getInstance().create( "matrixweightAA", new List[]{agegroups}, new String[]{"AgeGroups"}); MatrixND AbundancePop00 = null; MatrixND CatchPop00 = null; AbundancePop00 = resultmanager.getMatrix(date.previousYear(),pop,ResultName.MATRIX_ABUNDANCE_BEGIN_MONTH); MatrixND Prov1 = AbundancePop00.sumOverDim(1); // sum over zones; recruitNumber = Prov1.getValue(ageMin,0); double countN0 = 0.0; double countNcur = 0.0; double countB0 = 0.0; double countBcur = 0.0; double cumcountB0 = 0.0; double cumcountBcur = 0.0; double Fmsy = 0.1; double countCcur = 0.0; double countYcur = 0.0; double cumcountYcur = 0.0; for (Date dat = date.previousYear(); dat.before(date); dat = dat.next()) { CatchPop00 = resultmanager.getMatrix(dat,pop,ResultName.MATRIX_CATCH_PER_STRATEGY_MET_PER_ZONE_POP); MatrixND Prov2 = CatchPop00.sumOverDim(0); // sum over strategies; Prov2 = Prov2.sumOverDim(1); // sum over metiers; Prov2 = Prov2.sumOverDim(3); // sum over zones; for (PopulationGroup age : agegroups){ catchYear0.setValue(age,catchYear0.getValue(age)+Prov2.getValue(0,0,age,0)); } } for (int iage=ageMin; iage <= pop.sizePopulationGroup()-1; iage++){ PopulationGroup age = pop.getPopulationGroup().get(iage); mortNat.setValue(age,age.getNaturalDeathRate(zones.get(0))); if (iage == ageMin){ countN0 = recruitNumber; } else if (iage > ageMin && iage < (pop.sizePopulationGroup()-1)){ countN0 = countN0*Math.exp(-mortNat.getValue(age.getId()-1)); } else if (age.getId() == (pop.sizePopulationGroup() - 1)){ countN0 = countN0*Math.exp(-mortNat.getValue(age.getId()-1))/ (1-Math.exp(-mortNat.getValue(age.getId()))); } countB0 = countN0*age.getMeanWeight(); matrixweightAA.setValue(age.getId(),age.getMeanWeight()); cumcountB0 += countB0; countNcur = Prov1.getValue(age,0); countCcur = catchYear0.getValue(age); optimFsq = new Fcalculation(countCcur,countNcur,mortNat.getValue(age)); Fcur = Fmin.fmin(0.0,2.0,1.0e-10,optimFsq); matrixFcur.setValue(pop,age,Fcur); matrixFsq.setValue(age,Fcur); outOpti1.write(date+";"+pop+";"+age.getId()+";"+ mortNat.getValue(age.getId())+";"+countN0+";"+countB0+";"+cumcountB0+";"+ countCcur+";"+countNcur+";"+mortNat.getValue(age)+";"+matrixFcur.getValue(pop,age)); outOpti1.newLine(); } // end of age loop; matrixB0.setValue(pop,cumcountB0); // optimFmsy = new Fcalculation(ageMin, pop.sizePopulationGroup()-1, recruitNumber, // mortNat, matrixFsq, matrixweightAA); // Fmsy = Fmin.fmin(0.0,2.0,1.0e-10,optimFmsy); } // end of pop loop; } // end of date if-test; first = false; } // end of (first) if-test; } /** * Si la condition est vrai alors cette action est executee apres le pas * de temps de la simulation. * @param simulation La simulation pour lequel on utilise cette regle */ public void postAction(SimulationContext context, Date date, Metier metier) throws Exception { first = true; outOpti1.close(); } } /* * Copyright (C) 2010 pmarchal * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package scripts; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import fr.ifremer.isisfish.util.Doc; import fr.ifremer.isisfish.entities.*; import org.nuiton.math.matrix.*; import java.io.File; import java.io.Writer; import java.io.FileWriter; import java.io.BufferedWriter; import java.io.FileReader; /** * Fcalculation.java * * Created: 24 septembre 2010 * * @author pmarchal <anonymous@labs.libre-entreprise.org> * @version $Revision: 0 $ * * Last update: $Date: 24 septembre 2010 $ * by : $Author: pmarchal $ */ public class Fcalculation extends Object { double C, N, M; double recruitNumber; int ageMin, ageMax; MatrixND mortNat, Fsq, weightAA; public Fcalculation(double Ctemp, double Ntemp, double Mtemp) { C = Ctemp; N = Ntemp; M = Mtemp; System.out.print("C: "+C+" N: "+N+" M: "+M+ "\n"); } /* public Fcalculation(int ageMinTemp, int ageMaxTemp, double recruitNumberTemp, MatrixND mortNatTemp, MatrixND FsqTemp, MatrixND weightAAtemp) { ageMin = ageMinTemp; ageMax = ageMaxTemp; recruitNumber = recruitNumberTemp; mortNat = MatrixFactory.getInstance().create(mortNatTemp); Fsq = MatrixFactory.getInstance().create(FsqTemp); weightAA = MatrixFactory.getInstance().create(weightAAtemp); for (int iage=ageMin; iage <= ageMax; iage++){ mortNat.setValue(iage,mortNatTemp.getValue(iage)); Fsq.setValue(iage,FsqTemp.getValue(iage)); weightAA.setValue(iage,weightAAtemp.getValue(iage)); } } */ public double deriveF(double xx) { // Derives Fsq; double ff; ff = Math.pow((C - (xx/(xx+M))*(1-Math.exp(-(xx+M)))*N),2); System.out.print("xx: "+xx+" ff: "+ff+ "\n"); return ff; } // end of Method deriving Fsq; /* public double deriveF(double xx, double Bmsy, double Ymsy) { // Derives Fmsy; double ff; double countNmsy = 0.0; double countBmsy = 0.0; double countCmsy = 0.0; double countYmsy = 0.0; double cumcountBmsy = 0.0; double cumcountYmsy = 0.0; for (int iage=ageMin; iage <= ageMax; iage++){ if (iage == ageMin){ countNmsy = recruitNumber; } else if (iage > ageMin && iage < ageMax){ countNmsy = countNmsy*Math.exp(-mortNat.getValue(iage-1)-xx*Fsq.getValue(iage-1)); } else if (iage == ageMax){ countNmsy = countNmsy*Math.exp(-mortNat.getValue(iage-1)-xx*Fsq.getValue(iage-1))/ (1-Math.exp(-mortNat.getValue(iage)-xx*Fsq.getValue(iage))); } countBmsy = countNmsy*weightAA.getValue(iage); countCmsy = countNmsy*(xx*Fsq.getValue(iage)/(mortNat.getValue(iage)+xx*Fsq.getValue(iage)))* (1-Math.exp(-mortNat.getValue(iage)-xx*Fsq.getValue(iage))); countYmsy = countCmsy*weightAA.getValue(iage); cumcountBmsy += countBmsy; cumcountYmsy += countCmsy; } // end of for loop; Bmsy = cumcountBmsy; Ymsy = cumcountYmsy; ff = -Ymsy; System.out.print("xx: "+xx+" ff: "+ff+" Ymsy: "+Ymsy+" Bmsy: "+Bmsy+ "\n"); return ff; } // end of Method deriving Fmsy; */ } /* * Copyright (C) 2010 pmarchal * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package scripts; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import fr.ifremer.isisfish.util.Doc; import fr.ifremer.isisfish.entities.*; import org.nuiton.math.matrix.*; /** * Fmin.java * * Created: 8 septembre 2010 * * @author pmarchal <anonymous@labs.libre-entreprise.org> * @version $Revision: 0 $ * * Last update: $Date: 8 septembre 2010 $ * by : $Author: pmarchal $ */ public class Fmin extends Object { /** to use log facility, just put in your code: log.info("..."); */ private static Log log = LogFactory.getLog(Fmin.class); public static double fmin (double a, double b, double tol, Fcalculation minclass) { double c,d,e,eps,xm,p,q,r,tol1,t2,u,v,w,fu,fv,fw,fx,x,tol3; c = .5*(3.0 - Math.sqrt(5.0)); d = 0.0; eps = 1.2e-16; // 1.1102e-16 is machine precision tol1 = eps + 1.0; eps = Math.sqrt(eps); v = a + c*(b-a); w = v; x = v; e = 0.0; fx = minclass.deriveF(x); System.out.print("x: "+x+" fx: "+fx+ "\n"); fv = fx; fw = fx; tol3 = tol/3.0; xm = .5*(a + b); tol1 = eps*Math.abs(x) + tol3; t2 = 2.0*tol1; while (Math.abs(x-xm) > (t2 - .5*(b-a))) { // main loop; p = q = r = 0.0; if (Math.abs(e) > tol1) { // fit the parabola; r = (x-w)*(fx-fv); q = (x-v)*(fx-fw); p = (x-v)*q - (x-w)*r; q = 2.0*(q-r); if (q > 0.0) { p = -p; } else { q = -q; } r = e; e = d; } if ((Math.abs(p) < Math.abs(.5*q*r)) && (p > q*(a-x)) && (p < q*(b-x))) { // parabolic interpolation step; d = p/q; u = x+d; if (((u-a) < t2) || ((b-u) < t2)) { // f must not be evaluated too close to a or b; d = tol1; if (x >= xm) d = -d; } } else { // a golden-section step; if (x < xm) { e = b-x; } else { e = a-x; } d = c*e; } if (Math.abs(d) >= tol1) { // f must not be evaluated too close to x; u = x+d; } else { if (d > 0.0) { u = x + tol1; } else { u = x - tol1; } } fu = minclass.deriveF(u); System.out.print("u: "+u+" fu: "+fu+ "\n"); // Update a, b, v, w, and x if (fx <= fu) { if (u < x) { a = u; } else { b = u; } } if (fu <= fx) { if (u < x) { b = x; } else { a = x; } v = w; fv = fw; w = x; fw = fx; x = u; fx = fu; xm = .5*(a + b); tol1 = eps*Math.abs(x) + tol3; t2 = 2.0*tol1; } else { if ((fu <= fw) || (w == x)) { v = w; fv = fw; w = u; fw = fu; xm = .5*(a + b); tol1 = eps*Math.abs(x) + tol3; t2 = 2.0*tol1; } else if ((fu > fv) && (v != x) && (v != w)) { xm = .5*(a + b); tol1 = eps*Math.abs(x) + tol3;t2 = 2.0*tol1; } else { v = u; fv = fu; xm = .5*(a + b); tol1 = eps*Math.abs(x) + tol3; t2 = 2.0*tol1; } } } return x; } }