Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mrd/models/cagn/CagnModel.java


1   
2    /**
3    * Copyright (C) 2002-2003, Mark Diggory
4    *
5    * This file is part of the CAGN model project.
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. License
20   * information is also available at http://www.gnu.org.
21   *
22   */
23  package org.mrd.models.cagn;
24  
25  import java.util.*;
26  import java.awt.Point;
27  import org.mrd.repast.util.*;
28  import org.mrd.analysis.*;
29  import cern.jet.random.*;
30  import edu.cornell.lassp.houle.RngPack.RandomElement;
31  
32  import uchicago.src.sim.engine.*;
33  import uchicago.src.sim.util.*;
34  
35  import org.apache.commons.pool.*;
36  import org.apache.commons.pool.impl.*;
37  import org.apache.commons.logging.*;
38  
39  /** 
40   * The CAGN Model.
41   * @author Mark Diggory <mdiggory@latte.harvard.edu>
42   */
43  public class CagnModel extends SimModelImpl implements Stepable{
44      
45      /** logging is always good to do, learn to use it. */
46      protected Log log = LogFactory.getLog(this.getClass().getName());
47  
48      /** Every model must have a schedule */
49      protected Schedule schedule;
50      
51      /** Holds value of property maxIterations, stop is scheduled using this. */
52      protected double maxIterations = Double.MAX_VALUE;
53      
54      /** Holds value of property maxIterations, stop is scheduled using this. */
55      protected ObjectPool pool = null;
56      
57      /** the landscape encapsulates agentList and grid datastructures. */
58      protected Landscape landscape;
59      
60      /** Holds the location of the PGM file used to load the landscape */
61      protected String habitatSpaceFile;
62      
63      /** Used to generate the currentIterationSurvival probability. This is later used
64       * by the pairs in calculating thier survival
65       */    
66      protected Beta iteration_survivial_distribution = null;
67      
68      /** Used in the Bernoulli trials of all the pairs to determine their survival roll.
69       */    
70      protected RandomElement survival_generator = null;
71      
72      /** Used in the Bernoulli trials of all the pairs to determine reproduction roll.
73       */    
74      protected RandomElement rep_generator = null;
75      
76      /** Used in all the pairs to determine their dispersal distance.
77       */    
78      protected RandomElement disp_generator = null;
79      
80      /** Holds value of property pairClutchSize. */
81      protected int pairClutchSize;
82      
83      /** Holds value of property pairSearchTime. */
84      protected int pairSearchTime;
85      
86      /** Holds value of property pairMeanDispersalDistance. */
87      protected double pairMeanDispersalDistance;
88      
89      /** Holds value of property modelInitialPairs. */
90      protected int modelInitialPairs;
91      
92      /** Holds value of property pairSurvivalSeed. */
93      protected int pairSurvivalSeed = (int)System.currentTimeMillis();
94      
95      /** Holds value of property pairReproductionSeed. */
96      protected int pairReproductionSeed = (int)System.currentTimeMillis();
97      
98      /** Holds value of property pairDispersalSeed. */
99      protected int pairDispersalSeed = (int)System.currentTimeMillis();
100     
101     /** Holds value of property ageSurvivalTable.
102      */
103     protected double[] ageSurvivalTable = new double[]{1   ,1  ,1  ,.75,.001};
104     
105     /** Holds value of property ageReproductionTable. */
106     protected double[] ageReproductionTable = new double[]{.75 ,1  ,1  ,.75,.75 };
107     
108     /** Holds value of property landReproductionTable. */
109     protected double[] landReproductionTable = new double[]{.001,.25,.50,.75,1.00};
110     
111     /** Holds value of property landSurvivalTable. */
112     protected double[] landSurvivalTable = new double[]{.001,.25,.50,.75,1.00};
113     
114     /** Holds value of property iterationSurvivalMean. */
115     protected double iterationSurvivalMean = 0.9;
116     
117     /** Holds value of property iterationSurvivalStd. */
118     protected double iterationSurvivalStd = 0.1;
119     
120     /** Holds value of property currentIterationSurvival. */
121     protected double currentIterationSurvival;
122 
123     /** Holds value of property iterationDispersalSurvival. */
124     private double iterationDispersalSurvival = 1.0;
125     
126     private RunningBasicStatistics dispersalStatistics;
127     
128     
129     public CagnModel(){
130         super();
131         /*in future these sescriptors can be added to support array functionality in the GUI*/
132         //descriptors.put("AgeReproductionTable",new ArrayPropertyDescriptor("AgeReproductionTable",ageReproductionTable));
133         //descriptors.put("LandReproductionTable",new ArrayPropertyDescriptor("LandReproductionTable",landReproductionTable));
134         //descriptors.put("AgeSurvivalTable",new ArrayPropertyDescriptor("AgeSurvivalTable",ageSurvivalTable));
135         //descriptors.put("LandSurvivalTable",new ArrayPropertyDescriptor("LandSurvivalTable",landSurvivalTable));
136     }
137         
138     /** Model is setup from this method. Runs first.
139      */
140     public void setup() {
141 
142         try{
143             /* 
144              * create a new schedule with an interval of one.
145              */
146             schedule = new Schedule(1.0);
147         
148             /*
149              * this is an object pool capable of recycling the pair agents,
150              * I use this because it reduces the overhead of instantiating
151              * each new pair when its born, the model will only support x 
152              * number of pairs, that is all I need to instantiate
153              */
154             pool = new StackObjectPool(new PairFactory(this), 500);
155             
156             /*
157              * the landscape is a datastructure that combines several features
158              * into one object.
159              * 1.) the agent list for optimized update of the pairs
160              * 2.) the agent grid that establishes "position" for the pairs"
161              * 3.) the habitat grid that establishes "habitat quality" for
162              *     the pairs position in the landscape
163              */
164             landscape = new Landscape(pool, habitatSpaceFile);
165 
166             /* use the seeds that are either generated or parameterized to 
167              * initialize their corresponding generators
168              */
169             survival_generator = new cern.jet.random.engine.MersenneTwister(pairSurvivalSeed);
170             rep_generator = new cern.jet.random.engine.MersenneTwister(pairReproductionSeed);
171             disp_generator = new cern.jet.random.engine.MersenneTwister(pairDispersalSeed);
172             
173 
174             /* This distribution generates temporal variation over simulation
175              * iterations. It uses a Beta Distribution configured using mean and
176              * std. Currently uses the SurvivalGenerator to genrate pseudorandom 
177              * numbers.
178              */
179             
180             /* This is to assure that the std + mean cannot be greater than 1*/
181             if(iterationSurvivalMean + iterationSurvivalStd > 1)
182                 iterationSurvivalStd = 1-iterationSurvivalMean;
183             
184             /* This is to assure that the mean - std cannot be less than or equal to 0*/
185             if(iterationSurvivalMean - iterationSurvivalStd <= 0)
186                 iterationSurvivalStd = iterationSurvivalMean;
187             
188             /* This is to assure that the std cannot be less than or equal to 0*/
189             if (iterationSurvivalStd <= 0){
190                 iterationSurvivalStd = .00000001;
191             }
192             
193             /* This is to assure that the mean cannot be less than or equal to 0*/
194             if (iterationSurvivalMean <= 0){
195                 iterationSurvivalMean = .00000001;
196             }
197             
198             iteration_survivial_distribution = new org.mrd.random.LimitedBeta(iterationSurvivalMean, iterationSurvivalStd,survival_generator,true,true);
199 
200              /* 
201               * get the variation occuring for the "0" iteration of the model.
202               */
203             currentIterationSurvival = iteration_survivial_distribution.nextDouble();
204 
205             /* 
206              * The next section is strictly to setup a randomized distribution of 
207              * intial pairs.
208              *
209              * 1.) make sure our number isn't larger than the spaces available 
210              *     in the landscape.
211              */
212 
213             if(this.modelInitialPairs >= landscape.getSizeX()*landscape.getSizeY()){
214                 Exception e = new Exception("Initial Population too large.");
215                 log.error(e.getMessage(),e);
216             }
217             
218             /*
219              * 2.) we create a list of all possible places on the grid and 
220              *     randomly shuffle this list" 
221              */
222             List shuffle = new ArrayList();
223             for(int i = 0;i < landscape.getSizeX();i++){
224                 for(int j = 0 ; j < landscape.getSizeY();j++){
225                     shuffle.add(new Point(i,j));
226                 }
227             }
228             
229             /** Used to initialize the landscape with pairs.*/    
230             Uniform init_distribution = new Uniform(
231                 new cern.jet.random.engine.MersenneTwister((int)this.getRngSeed())
232             );
233             
234             /*
235              * 3.) add the initial pairs to the randomly chosen locations
236              */
237             
238             SimUtilities.shuffle(shuffle,init_distribution);
239             Iterator points = shuffle.iterator();
240             
241             for (int i = 0; i < modelInitialPairs; i++){
242                 if(points.hasNext()){
243                     Point p = (Point)points.next();
244                     Pair pair = (Pair)pool.borrowObject();
245                     pair.setCurrentAge(init_distribution.nextIntFromTo(0,this.getPairMaxAge()));
246                     landscape.putAgentAt(p.x,p.y,pair);
247                     
248                 }
249             }
250             
251             /*
252              * 4.) birth the pairs into the agents list. 
253              */
254             landscape.birthAgents();
255             
256             /*
257              * 5.) Because the pairs are now "overdispersed", we us the pairs 
258              *     disperse() method which optimizes thier location if better 
259              *     habitat is available. In Pair, disperse() provides for dispersing
260              *     without the risk of mortality, keeping the inital # of agents
261              *     the same.
262              *
263              *     Note: the mean dispersal distance is increased to allow the 
264              *           agents ample capability to get into better position. 
265              *           Otherwise, even if they were dispersed numerous times
266              *           they still may not change position. The mean is adjusted 
267              *           back after the search is complete.
268              */
269             for (java.util.Iterator iter = landscape.getAgents().iterator(); iter.hasNext();) {
270                 Pair pair = (Pair)iter.next();
271                 pair.setDispersalDistance(landscape.getSizeX(), this.disp_generator);
272                 Point disp = pair.search();
273                 pair.setDispersalDistance(this.pairMeanDispersalDistance,this.disp_generator);
274                 if(disp != null){
275                     landscape.moveAgentTo(pair,disp.x,disp.y);
276                 }
277                 
278             }
279             
280             /* lets add in the RunningBAsicStat to collect Average/Std survival */
281             this.dispersalStatistics = new RunningBasicStatistics();
282         }catch(Exception e){
283             log.error(e.getMessage(),e);
284         }
285         
286         
287     }
288     
289     /** Model begins from this method. Executes second.
290      */    
291     public void begin() {
292         log.debug("begin()");
293         
294         /*
295          * Add the neccessary events to the schedule, these setup to occur in
296          * the order they are added.
297          */
298         schedule.scheduleActionAtInterval(1.0,this,"step", Schedule.LAST);
299         schedule.scheduleActionAtIntervalRnd(1.0,landscape.getAgents(),"step", Schedule.LAST);
300         schedule.scheduleActionAtInterval(
301             1.0,
302             new BasicAction(){
303                 public void execute(){
304                     double surv_disp = (double)landscape.getBirthQueue().size();
305                     double fail_disp = (double)landscape.getReaperQueue().size();
306                     
307                     if(surv_disp != 0){
308             iterationDispersalSurvival = surv_disp / (surv_disp + fail_disp);
309             dispersalStatistics.incriment( iterationDispersalSurvival );
310                     }
311                 }
312             },
313             Schedule.LAST
314             );
315         
316         schedule.scheduleActionAtInterval(1.0,landscape,"birthAgents", Schedule.LAST);
317         schedule.scheduleActionAtInterval(1.0,landscape,"reapAgents", Schedule.LAST);
318         schedule.scheduleActionAt(maxIterations, this, "stop", Schedule.LAST);
319         schedule.scheduleActionAtInterval(
320             1.0,
321             new BasicAction(){
322                 public void execute(){
323                     if(landscape.getAgents().size() < 1 ){
324                         stop();
325                     }
326                 }
327             },
328             Schedule.LAST
329             );
330     }
331         
332     /** This method is defined in the stepable interface, it is scheduled
333      * from with the begin method. Any code added here will be executed
334      * when the scheduled event occurs (currently once each iteration).
335      *
336      */    
337     public void step(){
338         log.debug("step()");
339         /* get the variation occuring this iteration */
340         currentIterationSurvival = iteration_survivial_distribution.nextDouble();
341         
342         
343     }
344 
345     /** a required method - displayed on the Controller toolbar.
346      * @return String value for the Name of the model.
347      *
348      */
349     public java.lang.String getName() {
350         return "Simple CAGN Model";
351     }
352     
353     /** Used by the GUI to expose the Parameters that can be Manipulated.
354      * @return the String Array of Parameters that can be accessed from the gui
355      */
356     public java.lang.String[] getInitParam(){
357         return new String[]{
358             "ModelInitialPairs" ,
359             "MaxIterations",
360             
361             "PairDispersalSeed",
362             "PairMeanDispersalDistance",
363             "PairSearchTime",
364             
365             "PairSurvivalSeed",
366             "AgeSurvivalTable",
367             "LandSurvivalTable",
368             
369             "PairReproductionSeed",
370             "LandReproductionTable",
371             "AgeReproductionTable",
372             "PairClutchSize",
373             
374             "PairMaxAge",
375             
376             "IterationSurvivalMean",
377             "IterationSurvivalStd",
378         };
379     }
380     
381     /** Getter for property pairClutchSize.
382      * @return Value of property pairClutchSize.
383      */
384     public int getPairClutchSize() {
385         return this.pairClutchSize;
386     }
387     
388     /** Setter for property pairClutchSize.
389      * @param pairClutchSize New value of property pairClutchSize.
390      */
391     public void setPairClutchSize(int pairClutchSize) {
392         this.pairClutchSize = pairClutchSize;
393     }
394     
395     /** Getter for property pairSearchTime.
396      * @return Value of property pairSearchTime.
397      */
398     public int getPairSearchTime() {
399         return this.pairSearchTime;
400     }
401     
402     /** Setter for property pairSearchTime.
403      * @param pairSearchTime New value of property pairSearchTime.
404      */
405     public void setPairSearchTime(int pairSearchTime) {
406         this.pairSearchTime = pairSearchTime;
407     }
408     
409     /** Getter for property pairMeanDispersalDistance.
410      * @return Value of property pairMeanDispersalDistance.
411      */
412     public double getPairMeanDispersalDistance() {
413         return this.pairMeanDispersalDistance;
414     }
415     
416     /** Setter for property pairMeanDispersalDistance.
417      * @param pairMeanDispersalDistance New value of property pairMeanDispersalDistance.
418      */
419     public void setPairMeanDispersalDistance(double pairMeanDispersalDistance) {
420         this.pairMeanDispersalDistance = pairMeanDispersalDistance;
421     }
422     
423     /** Getter for property modelInitialPairs.
424      * @return Value of property modelInitialPairs.
425      */
426     public int getModelInitialPairs() {
427         return this.modelInitialPairs;
428     }
429     
430     /** Setter for property modelInitialPairs.
431      * @param modelInitialPairs New value of property modelInitialPairs.
432      */
433     public void setModelInitialPairs(int modelInitialPairs) {
434         this.modelInitialPairs = modelInitialPairs;
435     }
436     
437     /** Getter for property pairSurvivalSeed.
438      * @return Value of property pairSurvivalSeed.
439      */
440     public int getPairSurvivalSeed() {
441         return this.pairSurvivalSeed;
442     }
443     
444     /** Setter for property pairSurvivalSeed.
445      * @param pairSurvivalSeed New value of property pairSurvivalSeed.
446      */
447     public void setPairSurvivalSeed(int pairSurvivalSeed) {
448         this.pairSurvivalSeed = pairSurvivalSeed;
449     }
450     
451     /** Getter for property pairReproductionSeed.
452      * @return Value of property pairReproductionSeed.
453      */
454     public int getPairReproductionSeed() {
455         return this.pairReproductionSeed;
456     }
457     
458     /** Setter for property pairReproductionSeed.
459      * @param pairReproductionSeed New value of property pairReproductionSeed.
460      */
461     public void setPairReproductionSeed(int pairReproductionSeed) {
462         this.pairReproductionSeed = pairReproductionSeed;
463     }
464     
465     /** Getter for property pairDispersalSeed.
466      * @return Value of property pairDispersalSeed.
467      */
468     public int getPairDispersalSeed() {
469         return this.pairDispersalSeed;
470     }
471     
472     /** Setter for property pairDispersalSeed.
473      * @param pairDispersalSeed New value of property pairDispersalSeed.
474      */
475     public void setPairDispersalSeed(int pairDispersalSeed) {
476         this.pairDispersalSeed = pairDispersalSeed;
477     }
478     
479     /** Getter for property survivalTable.
480      * @return Value of property survivalTable.
481      */
482     public String getAgeSurvivalTable() {
483         return StringUtils.mush(ageSurvivalTable);
484     }
485     
486     /** Setter for property survivalTable.
487      * @param table as a String
488      */
489     public void setAgeSurvivalTable(String table) {
490         this.ageSurvivalTable = StringUtils.chop(table);
491     }
492     
493     /** Getter for property survivalTable.
494      * @return Value of property survivalTable.
495      */
496     public String getAgeReproductionTable() {
497         return StringUtils.mush(ageReproductionTable);
498     }
499     
500     /** Setter for property survivalTable.
501      * @param table as a String
502      */
503     public void setAgeReproductionTable(String table) {
504         this.ageReproductionTable = StringUtils.chop(table);
505         
506     }
507     
508     /** Getter for property landReproductionTable.
509      * @return Value of property landReproductionTable.
510      */
511     public String getLandReproductionTable() {
512         return StringUtils.mush(this.landReproductionTable);
513     }
514     
515     /** Setter for property landReproductionTable.
516      * @param table As a String
517      */
518     public void setLandReproductionTable(String table) {
519         this.landReproductionTable = StringUtils.chop(table);
520     }
521     
522     /** Getter for property landSurvivalTable.
523      * @return Value of property landSurvivalTable.
524      */
525     public String getLandSurvivalTable() {
526         return StringUtils.mush(this.landSurvivalTable);
527     }
528     
529     /** Setter for property landSurvivalTable.
530      * @param table As a String
531      */
532     public void setLandSurvivalTable(String table) {
533         this.landSurvivalTable = StringUtils.chop(table);
534     }
535     
536     /** Getter for property maxAge.
537      * @return Value of property maxAge.
538      */
539     public int getPairMaxAge() {
540         return ageSurvivalTable.length;
541     }
542     
543     /** Getter for property landscape.
544      * @return Value of property landscape.
545      */
546     public Landscape getLandscape() {
547         return this.landscape;
548     }
549     
550     /** Getter for property habitatSpace.
551      * @return Value of property habitatSpace.
552      */
553     public String getHabitatSpaceFile() {
554         return habitatSpaceFile;
555     }
556     
557     /** Setter for property habitatSpace.
558      * @param habitatSpaceFile returns the file used to load the landscape
559      */
560     public void setHabitatSpaceFile(String habitatSpaceFile) {
561         this.habitatSpaceFile = habitatSpaceFile;
562     }
563     
564     /** Getter for property iterationSurvivalMean.
565      * @return Value of property iterationSurvivalMean.
566      */
567     public double getIterationSurvivalMean() {
568         return this.iterationSurvivalMean;
569     }
570     
571     /** Setter for property iterationSurvivalMean.
572      * @param iterationSurvivalMean New value of property iterationSurvivalMean.
573      */
574     public void setIterationSurvivalMean(double iterationSurvivalMean) {
575         this.iterationSurvivalMean = iterationSurvivalMean;
576     }
577     
578     /** Getter for property iterationSurvivalStd.
579      * @return Value of property iterationSurvivalStd.
580      */
581     public double getIterationSurvivalStd() {
582         return this.iterationSurvivalStd;
583     }
584     
585     /** Setter for property iterationSurvivalStd.
586      * @param iterationSurvivalStd New value of property iterationSurvivalStd.
587      */
588     public void setIterationSurvivalStd(double iterationSurvivalStd) {
589         this.iterationSurvivalStd = iterationSurvivalStd;
590     }
591     
592     /** Getter for property currentIterationSurvival.
593      * @return Value of property currentIterationSurvival.
594      */
595     public double getCurrentIterationSurvival() {
596         return this.currentIterationSurvival;
597     }
598     
599         /** Getter for property maxIterations.
600      * @return Value of property maxIterations.
601      */
602     public double getMaxIterations() {
603         return this.maxIterations;
604     }
605     
606     /** Setter for property maxIterations.
607      * @param maxIterations New value of property maxIterations.
608      */
609     public void setMaxIterations(double maxIterations) {
610         this.maxIterations = maxIterations;
611     }
612     
613     /** Getter for property schedule.
614      * @return Value of property schedule.
615      */
616     public Schedule getSchedule(){
617         return schedule;
618     }
619     
620     /** Setter for property schedule.
621      * @param schedule New value of property schedule.
622      */
623     public void setSchedule(Schedule schedule) {
624         this.schedule = schedule;
625     }
626     
627   /**
628    * @return
629    */
630   public RunningBasicStatistics getDispersalStatistics() {
631     return dispersalStatistics;
632   }
633     
634     /** PairFactor is a place to store instances of the Pair object, this way we don't
635      * need to keep createing and destroying them, which can be an expensive task. It
636      * is probibly important to get the number in the pool relatively close to that of
637      * the pairs in your simulation,this value is currently hard coded in the setup()
638      * method.
639      */    
640     public class PairFactory extends org.apache.commons.pool.BasePoolableObjectFactory  {
641         
642         /** Holds value of property model. */
643         protected CagnModel model;
644         
645         /** Constructs a Pair Factory for the current model and landscape.
646          * @param model the model for which this PAir Factory will be used.
647          */        
648         public PairFactory(CagnModel model){
649             super();
650             this.model = model;
651         }
652         
653         /** Either gets a Pair from the pool or creates a new one.
654          * @throws Exception If anything goes wrong getting or creating the Pair.
655          * @return A Pair.
656          */        
657         public Object makeObject() throws java.lang.Exception {
658             
659             Pair pair = new Pair(model,landscape);
660             pair.setClutchSize(pairClutchSize);
661             pair.setSearchTime(pairSearchTime);
662             pair.setCurrentAge(0);
663             pair.setSurvivalGenerator(survival_generator);
664             pair.setReproductionGenerator(rep_generator);
665             pair.setDispersalDistance(pairMeanDispersalDistance,disp_generator);
666             pair.setDispersalAngleGenerator(disp_generator);
667             return pair;
668             
669         }
670         
671         /** Uninitialize an instance to be returned to the pool. Setup the defaults for
672          * when it is used again
673          * @param obj the instance to be passivated
674          * @throws Exception If anything goes wrong
675          */
676         public void passivateObject(Object obj)
677         throws Exception {
678             Pair pair = (Pair)obj;
679             pair.setClutchSize(pairClutchSize);
680             pair.setSearchTime(pairSearchTime);
681             pair.setCurrentAge(0);
682             pair.setStage(Agent.ALIVE);
683             pair.setSurvivalGenerator(survival_generator);
684             pair.setReproductionGenerator(rep_generator);
685             pair.setDispersalDistance(pairMeanDispersalDistance,disp_generator);
686             pair.setDispersalAngleGenerator(disp_generator);
687         }
688     }
689 
690 
691   /**
692    * @return
693    */
694   public double getIterationDispersalSurvival() {
695     return iterationDispersalSurvival;
696   }
697 
698 }