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     Set set = newType.getNumOfSets() == 0 ? newType.createSet(
224         "Migrated parameter assignments",
225         "Automatically created during Settype definition.", 0.0) : newType
226         .getSets().get(0);
227     ParameterAssignmentSet paramAssignmentSet = getDefaultSet()
228         .getParameterAssignments(instance);
229     for (ParameterAssignment pa : paramAssignmentSet.getAssignments()) {
230       set.addParameterAssignment(pa);
231     }
232   }
233 
234   /**
235    * Removes a {@link ParameterInstance} from a certain {@link SetType}.
236    * 
237    * @param instance
238    *          the instance that should from now on be managed by the default
239    *          {@link SetType}
240    * 
241    * @return true, if instance could be removed from its Settype (i.e., if set
242    *         type is not default Settype)
243    */
244   public boolean removeParameterInstanceAssignment(ParameterInstance instance) {
245     SetType associatedSetType = instanceSetTypes.get(instance);
246 
247     if (associatedSetType.equals(defaultType)) {
248       return false;
249     }
250 
251     associatedSetType.removeInstance(instance);
252     defaultType.addInstance(instance);
253     instanceSetTypes.put(instance, defaultType);
254     return true;
255   }
256 
257   /**
258    * Retrieves a custom {@link SetType}.
259    * 
260    * @param index
261    *          index of the Settype
262    * 
263    * @return Settype with given index
264    */
265   public SetType getSetType(int index) {
266     return userDefinedTypes.get(index);
267   }
268 
269   /**
270    * Removes {@link SetType} with given index from scenario.
271    * 
272    * @param index
273    *          index of the Settype
274    * 
275    * @return true, if operation could be executed
276    */
277   public boolean removeSetType(int index) {
278     SetType removedSetType = userDefinedTypes.remove(index);
279 
280     if (removedSetType == null) {
281       return false;
282     }
283 
284     List<ParameterInstance> parameterInstances = new ArrayList<ParameterInstance>(
285         removedSetType.getDefinedParameters());
286     for (ParameterInstance instance : parameterInstances) {
287       removeParameterInstanceAssignment(instance);
288     }
289     return true;
290   }
291 
292   @Override
293   public List<SetType> getAllSetTypes() {
294     List<SetType> setTypes = new ArrayList<SetType>();
295     setTypes.add(defaultType);
296     setTypes.addAll(userDefinedTypes);
297     return setTypes;
298   }
299 
300   // Getters/Setter to ensure bean compatibility
301 
302   /**
303    * Gets the default set.
304    * 
305    * @return the default set
306    */
307   public Set getDefaultSet() {
308     return defaultSet;
309   }
310 
311   /**
312    * Sets the default set.
313    * 
314    * @param defaultSet
315    *          the new default set
316    */
317   public void setDefaultSet(Set defaultSet) {
318     this.defaultSet = defaultSet;
319   }
320 
321   /**
322    * Gets the default type.
323    * 
324    * @return the default type
325    */
326   public SetType getDefaultType() {
327     return defaultType;
328   }
329 
330   /**
331    * Sets the default type.
332    * 
333    * @param defaultType
334    *          the new default type
335    */
336   public void setDefaultType(SetType defaultType) {
337     this.defaultType = defaultType;
338   }
339 
340   /**
341    * Gets the default Settype.
342    * 
343    * @return the default Settype
344    */
345   public SetType getDefaultSetType() {
346     return defaultType;
347   }
348 
349   @Override
350   public int getGenerations() {
351     return generations;
352   }
353 
354   /**
355    * Sets the generations.
356    * 
357    * @param generations
358    *          the new generations
359    */
360   public void setGenerations(int generations) {
361     // TODO: Remove obsolete generations if necessary.
362     this.generations = generations;
363   }
364 
365   @Override
366   public int getMaximumAge() {
367     return maximumAge;
368   }
369 
370   /**
371    * Sets the maximum age.
372    * 
373    * @param maximumAge
374    *          the new maximum age
375    */
376   public void setMaximumAge(int maximumAge) {
377     // TODO: Adjust matrix size if necessary.
378     this.maximumAge = maximumAge;
379   }
380 
381   @Override
382   public int getYears() {
383     return years;
384   }
385 
386   /**
387    * Sets the years.
388    * 
389    * @param years
390    *          the new years
391    */
392   public void setYears(int years) {
393     // TODO: Adjust matrix size if necessary.
394     this.years = years;
395   }
396 
397   /**
398    * Gets the user defined types.
399    * 
400    * @return the user defined types
401    */
402   public List<SetType> getUserDefinedTypes() {
403     return userDefinedTypes;
404   }
405 
406   /**
407    * Sets the user defined types.
408    * 
409    * @param userDefinedTypes
410    *          the new user defined types
411    */
412   public void setUserDefinedTypes(List<SetType> userDefinedTypes) {
413     this.userDefinedTypes = userDefinedTypes;
414   }
415 
416   /**
417    * Gets the all parameter instances.
418    * 
419    * @return the all parameter instances
420    */
421   public List<ParameterInstance> getAllParameterInstances() {
422     return this.allParameterInstances;
423   }
424 
425   /**
426    * Sets the all parameter instances.
427    * 
428    * @param allParameterInstances
429    *          the new all parameter instances
430    */
431   public void setAllParameterInstances(
432       List<ParameterInstance> allParameterInstances) {
433     this.allParameterInstances = allParameterInstances;
434   }
435 
436   @Override
437   public Map<ParameterInstance, SetType> getInstanceSetTypes() {
438     return instanceSetTypes;
439   }
440 
441   /**
442    * Sets the instance Settypes.
443    * 
444    * @param instanceSetTypes
445    *          the instance Settypes
446    */
447   public void setInstanceSetTypes(
448       Map<ParameterInstance, SetType> instanceSetTypes) {
449     this.instanceSetTypes = instanceSetTypes;
450   }
451 
452   /**
453    * Removes the Settype.
454    * 
455    * @param setType
456    *          the Settype
457    * 
458    * @return true, if successful
459    */
460   public boolean removeSetType(SetType setType) {
461     return removeSetType(userDefinedTypes.indexOf(setType));
462   }
463 
464   /**
465    * Gets the number of (user-defined) of Settypes.
466    * 
467    * @return the number of Settypes
468    */
469   public int getNumOfSetTypes() {
470     return userDefinedTypes.size();
471   }
472 
473   /**
474    * Gets the id.
475    * 
476    * @return the id
477    */
478   public int getID() {
479     return id;
480   }
481 
482   /**
483    * Sets the id.
484    * 
485    * @param uniqueID
486    *          the new id
487    */
488   public void setID(int uniqueID) {
489     id = uniqueID;
490   }
491 
492   @Override
493   public String getName() {
494     return name;
495   }
496 
497   @Override
498   public void setName(String name) {
499     this.name = name;
500   }
501 
502   /**
503    * Gets the description.
504    * 
505    * @return the description
506    */
507   public String getDescription() {
508     return description;
509   }
510 
511   /**
512    * Sets the description.
513    * 
514    * @param description
515    *          the new description
516    */
517   public void setDescription(String description) {
518     this.description = description;
519   }
520 
521   /**
522    * Gets the number of age classes. Is calculated by adding 1 to
523    * {@link ProjectionModel#maximumAge}.
524    * 
525    * @return the number of age classes
526    */
527   public int getNumberOfAgeClasses() {
528     return maximumAge + 1;
529   }
530 
531   /**
532    * Gets the jump off year.
533    * 
534    * @return the jump off year
535    */
536   public int getJumpOffYear() {
537     return jumpOffYear;
538   }
539 
540   /**
541    * Sets the jump off year.
542    * 
543    * @param jumpOffYear
544    *          the new jump off year
545    */
546   public void setJumpOffYear(int jumpOffYear) {
547     this.jumpOffYear = jumpOffYear;
548   }
549 
550   /**
551    * Counts the number of parameter assignments contained in this projection.
552    * 
553    * @return the number of parameter assignments
554    */
555   public int countNumberOfParameterAssignments() {
556     int numOfAssignments = 0;
557     for (SetType setType : getAllSetTypes())
558       for (Set set : setType.getSets())
559         for (ParameterAssignmentSet assignSet : set.getSetData().values())
560           numOfAssignments += assignSet.size();
561     return numOfAssignments;
562   }
563 }