View Javadoc

1   /*
2    * Copyright 2006 - 2012 Christina Bohk and Roland Ewald
3    *  
4    * Licensed under the Apache License, Version 2.0 (the "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at 
7    *  
8    *  http://www.apache.org/licenses/LICENSE-2.0
9    *  
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License. 
15   */
16  package p3j.pppm;
17  
18  import james.core.model.Model;
19  
20  import java.util.ArrayList;
21  import java.util.Calendar;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import p3j.pppm.parameters.ParameterAssignment;
27  import p3j.pppm.parameters.ParameterAssignmentSet;
28  import p3j.pppm.parameters.ParameterInstance;
29  import p3j.pppm.sets.Set;
30  import p3j.pppm.sets.SetType;
31  import p3j.simulation.calculation.deterministic.Constants;
32  
33  /**
34   * Stores a complete configuration for the PPPM, containing {@link Set} objects
35   * associated with different {@link SetType} instances. Such a scenario can be
36   * used for forecasting, it comprises all information necessary for basic
37   * repeatibility of the Monte-Carlo-simulation. Each scenario holds a list of
38   * all {@link ParameterInstance} objects that need an assignment. Disjunct
39   * subsets of this list will be managed by {@link SetType}.
40   * 
41   * TODO: Store RNG seed to ensure exact reproducibility.
42   * 
43   * Created on January 22, 2007
44   * 
45   * @author Christina Bohk
46   * @author Roland Ewald
47   */
48  public class ProjectionModel extends Model implements IProjectionModel {
49  
50    /** Serialization ID. */
51    private static final long serialVersionUID = -1984182268566219449L;
52  
53    /** The ID of this scenario. */
54    private int id;
55  
56    /** Name of the scenario. */
57    private String name;
58  
59    /** Description of the scenario. */
60    private String description;
61  
62    /**
63     * Default Settype. This will always be there and contain all parameters that
64     * do not belong to specific Settypes.
65     */
66    private SetType defaultType = new SetType("Default Settype",
67        "This is the default Settype.");
68  
69    /** Default set. */
70    private Set defaultSet = defaultType.createSet("Default Set",
71        "This is the default set.", 1);
72  
73    /** List of user defined Settypes. */
74    private List<SetType> userDefinedTypes = new ArrayList<SetType>();
75  
76    /** List of all parameter instances available in this scenario. */
77    private List<ParameterInstance> allParameterInstances = new ArrayList<ParameterInstance>();
78  
79    /** Mapping {@link ParameterInstance} to {@link SetType} that manages it. */
80    private Map<ParameterInstance, SetType> instanceSetTypes = new HashMap<ParameterInstance, SetType>();
81  
82    /**
83     * Number of generations to be taken into account. Is initially set to
84     * {@link Constants#DEFAULT_NUM_GENERATIONS}.
85     */
86    private int generations = Constants.DEFAULT_NUM_GENERATIONS;
87  
88    /**
89     * Number of years to be predicted. Is initially set to
90     * {@link Constants#DEFAULT_NUM_YEARS}.
91     */
92    private int years = Constants.DEFAULT_NUM_YEARS;
93  
94    /**
95     * Maximum age of individual. Is initially set to
96     * {@link Constants#DEFAULT_MAXIMUM_AGE}.
97     */
98    private int maximumAge = Constants.DEFAULT_MAXIMUM_AGE;
99  
100   /** The jump-off year. */
101   private int jumpOffYear = Calendar.getInstance().get(Calendar.YEAR);
102 
103   /**
104    * Constructor for bean compatibility (do NOT use manually!).
105    */
106   public ProjectionModel() {
107 
108   }
109 
110   /**
111    * Default constructor.
112    * 
113    * @param scenName
114    *          name of the scenario
115    * @param desc
116    *          description of the scenario
117    * @param numOfGenerations
118    *          number of generations to be considered
119    * @param predYears
120    *          number of years to be predicted
121    * @param maxAge
122    *          maximum age to be considered
123    * @param jumpOffYear
124    *          the jump off year
125    */
126   public ProjectionModel(String scenName, String desc, int numOfGenerations,
127       int predYears, int maxAge, int jumpOffYear) {
128     this.name = scenName;
129     this.description = desc;
130     this.generations = numOfGenerations;
131     this.years = predYears;
132     this.maximumAge = maxAge;
133     this.jumpOffYear = jumpOffYear;
134   }
135 
136   /**
137    * Initializes projection. Needs to be called after
138    * {@link ProjectionModel#allParameterInstances} has been initialized.
139    */
140   @Override
141   public void init() {
142     for (int i = 0; i < allParameterInstances.size(); i++) {
143       instanceSetTypes.put(allParameterInstances.get(i), defaultType);
144       defaultType.addInstance(allParameterInstances.get(i));
145     }
146   }
147 
148   /**
149    * Defines a new Settype for this scenario.
150    * 
151    * @param stName
152    *          name of the Settype
153    * @param stDesc
154    *          description of the Settype
155    * 
156    * @return newly defined Settype for this scenario
157    */
158   public SetType createSetType(String stName, String stDesc) {
159     SetType setType = new SetType(stName, stDesc);
160     userDefinedTypes.add(setType);
161     return setType;
162   }
163 
164   /**
165    * Get all {@link ParameterInstance} objects that still belong to the default
166    * {@link SetType}. These have not yet been assigned to any custom
167    * {@link SetType}.
168    * 
169    * @return list of all parameter instances that are not yet assigned to user
170    *         defined Settypes
171    */
172   public List<ParameterInstance> getUnassignedParameterInstances() {
173     return this.defaultType.getDefinedParameters();
174   }
175 
176   /**
177    * Assign a {@link ParameterInstance} to a specific {@link SetType}.
178    * 
179    * @param instance
180    *          the parameter instance to be assigned
181    * @param type
182    *          the {@link SetType} that shall manage the
183    *          {@link ParameterInstance} from now on
184    * @param migrate
185    *          flag to switch migration of existing assumption to new Settype
186    *          on/off
187    * 
188    * @return true, if parameter instance could be assigned (i.e., former set
189    *         type is default Settype), otherwise false
190    */
191   public boolean assignParameterInstance(ParameterInstance instance,
192       SetType type, boolean migrate) {
193 
194     if (type.equals(defaultType)) {
195       removeParameterInstanceAssignment(instance);
196     }
197 
198     SetType associatedSetType = instanceSetTypes.get(instance);
199 
200     if (!associatedSetType.equals(defaultType)) {
201       return false;
202     }
203 
204     type.addInstance(instance);
205     if (migrate) {
206       migrateAssignmentsFromDefaultType(instance, type);
207     }
208     defaultType.removeInstance(instance);
209     instanceSetTypes.put(instance, type);
210     return true;
211   }
212 
213   /**
214    * Migrate assignments from default type.
215    * 
216    * @param instance
217    *          the parameter instance of the assignments to be migrated
218    * @param newType
219    *          the destination Settype
220    */
221   private void migrateAssignmentsFromDefaultType(ParameterInstance instance,
222       SetType newType) {
223     ParameterAssignmentSet paramAssignmentSet = getDefaultSet()
224         .getParameterAssignments(instance);
225 
226     // Stop if there is nothing to migrate
227     if (paramAssignmentSet.getAssignments().isEmpty())
228       return;
229 
230     Set set = newType.getNumOfSets() == 0 ? newType.createSet(
231         "Migrated parameter assignments",
232         "Automatically created during Settype definition.", 0.0) : newType
233         .getSets().get(0);
234 
235     for (ParameterAssignment pa : paramAssignmentSet.getAssignments()) {
236       set.addParameterAssignment(pa);
237     }
238   }
239 
240   /**
241    * Removes a {@link ParameterInstance} from a certain {@link SetType}.
242    * 
243    * @param instance
244    *          the instance that should from now on be managed by the default
245    *          {@link SetType}
246    * 
247    * @return true, if instance could be removed from its Settype (i.e., if set
248    *         type is not default Settype)
249    */
250   public boolean removeParameterInstanceAssignment(ParameterInstance instance) {
251     SetType associatedSetType = instanceSetTypes.get(instance);
252 
253     if (associatedSetType.equals(defaultType)) {
254       return false;
255     }
256 
257     associatedSetType.removeInstance(instance);
258     defaultType.addInstance(instance);
259     instanceSetTypes.put(instance, defaultType);
260     return true;
261   }
262 
263   /**
264    * Retrieves a custom {@link SetType}.
265    * 
266    * @param index
267    *          index of the Settype
268    * 
269    * @return Settype with given index
270    */
271   public SetType getSetType(int index) {
272     return userDefinedTypes.get(index);
273   }
274 
275   /**
276    * Removes {@link SetType} with given index from scenario.
277    * 
278    * @param index
279    *          index of the Settype
280    * 
281    * @return true, if operation could be executed
282    */
283   public boolean removeSetType(int index) {
284     SetType removedSetType = userDefinedTypes.remove(index);
285 
286     if (removedSetType == null) {
287       return false;
288     }
289 
290     List<ParameterInstance> parameterInstances = new ArrayList<ParameterInstance>(
291         removedSetType.getDefinedParameters());
292     for (ParameterInstance instance : parameterInstances) {
293       removeParameterInstanceAssignment(instance);
294     }
295     return true;
296   }
297 
298   @Override
299   public List<SetType> getAllSetTypes() {
300     List<SetType> setTypes = new ArrayList<SetType>();
301     setTypes.add(defaultType);
302     setTypes.addAll(userDefinedTypes);
303     return setTypes;
304   }
305 
306   // Getters/Setter to ensure bean compatibility
307 
308   /**
309    * Gets the default set.
310    * 
311    * @return the default set
312    */
313   public Set getDefaultSet() {
314     return defaultSet;
315   }
316 
317   /**
318    * Sets the default set.
319    * 
320    * @param defaultSet
321    *          the new default set
322    */
323   public void setDefaultSet(Set defaultSet) {
324     this.defaultSet = defaultSet;
325   }
326 
327   /**
328    * Gets the default type.
329    * 
330    * @return the default type
331    */
332   public SetType getDefaultType() {
333     return defaultType;
334   }
335 
336   /**
337    * Sets the default type.
338    * 
339    * @param defaultType
340    *          the new default type
341    */
342   public void setDefaultType(SetType defaultType) {
343     this.defaultType = defaultType;
344   }
345 
346   /**
347    * Gets the default Settype.
348    * 
349    * @return the default Settype
350    */
351   public SetType getDefaultSetType() {
352     return defaultType;
353   }
354 
355   @Override
356   public int getGenerations() {
357     return generations;
358   }
359 
360   /**
361    * Sets the generations.
362    * 
363    * @param generations
364    *          the new generations
365    */
366   public void setGenerations(int generations) {
367     // TODO: Remove obsolete generations if necessary.
368     this.generations = generations;
369   }
370 
371   @Override
372   public int getMaximumAge() {
373     return maximumAge;
374   }
375 
376   /**
377    * Sets the maximum age.
378    * 
379    * @param maximumAge
380    *          the new maximum age
381    */
382   public void setMaximumAge(int maximumAge) {
383     // TODO: Adjust matrix size if necessary.
384     this.maximumAge = maximumAge;
385   }
386 
387   @Override
388   public int getYears() {
389     return years;
390   }
391 
392   /**
393    * Sets the years.
394    * 
395    * @param years
396    *          the new years
397    */
398   public void setYears(int years) {
399     // TODO: Adjust matrix size if necessary.
400     this.years = years;
401   }
402 
403   /**
404    * Gets the user defined types.
405    * 
406    * @return the user defined types
407    */
408   public List<SetType> getUserDefinedTypes() {
409     return userDefinedTypes;
410   }
411 
412   /**
413    * Sets the user defined types.
414    * 
415    * @param userDefinedTypes
416    *          the new user defined types
417    */
418   public void setUserDefinedTypes(List<SetType> userDefinedTypes) {
419     this.userDefinedTypes = userDefinedTypes;
420   }
421 
422   /**
423    * Gets the all parameter instances.
424    * 
425    * @return the all parameter instances
426    */
427   public List<ParameterInstance> getAllParameterInstances() {
428     return this.allParameterInstances;
429   }
430 
431   /**
432    * Sets the all parameter instances.
433    * 
434    * @param allParameterInstances
435    *          the new all parameter instances
436    */
437   public void setAllParameterInstances(
438       List<ParameterInstance> allParameterInstances) {
439     this.allParameterInstances = allParameterInstances;
440   }
441 
442   @Override
443   public Map<ParameterInstance, SetType> getInstanceSetTypes() {
444     return instanceSetTypes;
445   }
446 
447   /**
448    * Sets the instance Settypes.
449    * 
450    * @param instanceSetTypes
451    *          the instance Settypes
452    */
453   public void setInstanceSetTypes(
454       Map<ParameterInstance, SetType> instanceSetTypes) {
455     this.instanceSetTypes = instanceSetTypes;
456   }
457 
458   /**
459    * Removes the Settype.
460    * 
461    * @param setType
462    *          the Settype
463    * 
464    * @return true, if successful
465    */
466   public boolean removeSetType(SetType setType) {
467     return removeSetType(userDefinedTypes.indexOf(setType));
468   }
469 
470   /**
471    * Gets the number of (user-defined) of Settypes.
472    * 
473    * @return the number of Settypes
474    */
475   public int getNumOfSetTypes() {
476     return userDefinedTypes.size();
477   }
478 
479   /**
480    * Gets the id.
481    * 
482    * @return the id
483    */
484   public int getID() {
485     return id;
486   }
487 
488   /**
489    * Sets the id.
490    * 
491    * @param uniqueID
492    *          the new id
493    */
494   public void setID(int uniqueID) {
495     id = uniqueID;
496   }
497 
498   @Override
499   public String getName() {
500     return name;
501   }
502 
503   @Override
504   public void setName(String name) {
505     this.name = name;
506   }
507 
508   /**
509    * Gets the description.
510    * 
511    * @return the description
512    */
513   public String getDescription() {
514     return description;
515   }
516 
517   /**
518    * Sets the description.
519    * 
520    * @param description
521    *          the new description
522    */
523   public void setDescription(String description) {
524     this.description = description;
525   }
526 
527   /**
528    * Gets the number of age classes. Is calculated by adding 1 to
529    * {@link ProjectionModel#maximumAge}.
530    * 
531    * @return the number of age classes
532    */
533   public int getNumberOfAgeClasses() {
534     return maximumAge + 1;
535   }
536 
537   /**
538    * Gets the jump off year.
539    * 
540    * @return the jump off year
541    */
542   public int getJumpOffYear() {
543     return jumpOffYear;
544   }
545 
546   /**
547    * Sets the jump off year.
548    * 
549    * @param jumpOffYear
550    *          the new jump off year
551    */
552   public void setJumpOffYear(int jumpOffYear) {
553     this.jumpOffYear = jumpOffYear;
554   }
555 
556   /**
557    * Counts the number of parameter assignments contained in this projection.
558    * 
559    * @return the number of parameter assignments
560    */
561   public int countNumberOfParameterAssignments() {
562     int numOfAssignments = 0;
563     for (SetType setType : getAllSetTypes())
564       for (Set set : setType.getSets())
565         for (ParameterAssignmentSet assignSet : set.getSetData().values())
566           numOfAssignments += assignSet.size();
567     return numOfAssignments;
568   }
569 }