src/de/pik/lagom/generic/Foundation.java

00001 
00002 // Copyright 2010 by Carlo Jaeger, Antoine Mandel, Steffen Fuerst and European Climate Forum
00003 // Licensed under the Open Software License version 3.0
00004 // See the file "License-OSL-3.0.txt" in the distribution for more information
00005 // The License text can be also found under http://www.opensource.org/licenses/osl-3.0.php
00007 
00008 package de.pik.lagom.generic;
00009 
00107 import java.util.Collections;
00108 import java.util.HashMap;
00109 import java.util.Iterator;
00110 import java.util.LinkedList;
00111 import java.util.List;
00112 import java.util.Map;
00113 
00114 import net.sf.oval.constraint.NotNegative;
00115 import net.sf.oval.guard.Guarded;
00116 import net.sf.oval.guard.Post;
00117 import net.sf.oval.guard.PostValidateThis;
00118 import net.sf.oval.guard.PreValidateThis;
00119 import de.pik.lagom.annotations.Description;
00120 import de.pik.lagom.annotations.Origin;
00121 import static de.pik.lagom.annotations.Origin.*;
00122 import de.pik.lagom.annotations.NameInUI;
00123 import de.pik.lagom.annotations.WriteToFile;
00124 import de.pik.lagom.exceptions.ParameterParserException;
00125 import de.pik.lagom.exceptions.ValueValidationException;
00126 import de.pik.lagom.framework.FoundationBase;
00127 import de.pik.lagom.generic.StepManagerWithProfiler.Probe;
00128 import de.pik.lagom.generic.consumptiontechnology.ConsumptionTechnologyFactory;
00129 import de.pik.lagom.generic.initvalues.FoundationInitValues;
00130 import de.pik.lagom.generic.initvalues.InitValuesManagerWithSectors;
00131 import de.pik.lagom.generic.productionfunction.ProductionFunctionFactory;
00132 import de.pik.lagom.toolbox.ArrayTools;
00133 import de.pik.lagom.toolbox.ListTools;
00134 import de.pik.lagom.toolbox.ProbeBase;
00135 import de.pik.lagom.toolbox.StepManager;
00136 import de.pik.lagom.toolbox.StepManager.Callback;
00137 import de.pik.lagom.toolbox.io.initvalues.InitValuesManager;
00138 import de.pik.lagom.toolbox.io.probevalues.ProbeManager;
00139 import de.pik.lagom.toolbox.math.DoubleInterval;
00140 import de.pik.lagom.toolbox.math.FloatMath;
00141 import de.pik.lagom.toolbox.math.RandomGenerator;
00142 
00155 @Guarded
00156 public class Foundation extends FoundationBase {
00162   public class EmissionProbe extends ProbeBase {
00164     double globalProduced;
00165     
00173     double globalTraded;
00174     
00182     double consumption;
00183 
00184     void init() {
00185       registerCallbacks(getStepManager());
00186       getProbeManager().addProbe(this);
00187     }
00188 
00189     private void registerCallbacks(StepManager pStepManager) {
00190       pStepManager.registerCallback(EXCHANGE_STEP,
00191                                     StepManager.Timing.POST,
00192                                     2,
00193                                     new Callback() {
00194         @Override
00195         public void postStep() {
00196           globalTraded = 0.d;
00197           consumption = 0.d;
00198           for (final Sector lSector : sectorList) {
00199             globalTraded += getTradeTrace().getOverallQuantitySelledInSector(lSector)
00200                             * lSector.getInitUnitInPetaJoule()
00201                             * lSector.calcCiCoef(getPeriodAsYear());
00202             consumption += getTradeTrace().getOverallQuantityBoughtByHouseholds(lSector)
00203                             * lSector.getInitUnitInPetaJoule()
00204                             * lSector.calcCiCoef(getPeriodAsYear());
00205           }
00206         }
00207 
00208         @Override
00209         public Object getOwner() {
00210           return Foundation.EmissionProbe.this;
00211         }
00212       }
00213       );
00214 
00215       pStepManager.registerCallback(PRODUCTION_STEP,
00216                                     StepManager.Timing.POST,
00217                                     2,
00218                                     new Callback() {
00219         @Override
00220         public void postStep() {
00221           globalProduced = 0.d;
00222           for (final Sector lSector : sectorList) {
00223             globalProduced += lSector.getProbe().getCO2Produced();
00224           }
00225         }
00226 
00227         @Override
00228         public Object getOwner() {
00229           return Foundation.EmissionProbe.this;
00230         }
00231       }
00232       );
00233     }
00234 
00235     @Override
00236     public String toString() {
00237       return "Emission";
00238     }
00239 
00240     @WriteToFile
00241     @NameInUI("CO2 from Production")
00242     @Description("The amount of CO2 created by the production process")
00243     public double getGlobalProduced() {
00244       return globalProduced;
00245     }
00246 
00247     @WriteToFile
00248     @NameInUI("Traded CO2")
00249     @Description("The amount of CO2 caused by goods that firms and households has bought " + 
00250                  "(the CO2 was already created in the production process)")
00251     public double getGlobalTradedInclConsumption() {
00252       return globalTraded;
00253     }
00254 
00255     @WriteToFile
00256     @NameInUI("Consumed CO2")
00257     @Description("The amount of CO2 caused by goods that households has bought " + 
00258                  "(the CO2 was already created in the production process)")
00259     public double getConsumption() {
00260       return consumption;
00261     }
00262   }
00263 
00269   class HouseholdSet implements Iterable<Household> {
00270     private final LinkedList<Household> householdList = new LinkedList<Household>();
00271     private boolean workAmountListIsNotSorted = true;
00272 
00273     private void workAmountSort() {
00274       if (workAmountListIsNotSorted) {
00275         Collections.sort(householdList, new Household.WorkAmountComparator());
00276         workAmountListIsNotSorted = false;
00277       }
00278     }
00279 
00280     public void clear() {
00281       householdList.clear();
00282     }
00283 
00284     public void add(Household pHousehold) {
00285       householdList.add(pHousehold);
00286     }
00287 
00288     public Household getRandomHousehold() {
00289       return householdList.get(random.nextInt(householdList.size()));
00290     }
00291 
00292     public int size() {
00293       return householdList.size();
00294     }
00295 
00296     public void workContractsChanged(Household pHousehold) {
00297       workAmountListIsNotSorted = true;
00298     }
00299 
00300     public LinkedList<Household> getCopyAsLinkedList() {
00301       return new LinkedList<Household>(householdList);
00302     }
00303 
00304     public Iterator<Household> iterator() {
00305       return householdList.iterator();
00306     }
00307 
00308     public Iterator<Household> workAmountSortedIterator() {
00309       workAmountSort();
00310       return iterator();
00311     }
00312   }
00313 
00314   // The identifier of the single steps for the StepManager. The String is the name of the 
00315   // method that is invoked when executeStep(STEP) is called
00316   public static final String PREPARATORY_STEP = "preparatoryStep";
00317   public static final String EXCHANGE_STEP = "exchangeStep";
00318   public static final String UPDATE_BENCHMARK_WAGE_STEP = "updateBenchmarkWage";
00319   public static final String HOUSEHOLDS_ADJUST_EMPLOYMENT_STEP = "householdsAdjustEmployment";
00320   public static final String FIRMS_ADJUST_WORKFORCE_STEP = "firmsAdjustWorkforce";
00321   public static final String PRODUCTION_STEP = "production";
00322   public static final String CONSUMPTION_STEP = "consumption";
00323   public static final String FIRM_ACCOUNTING_STEP = "firmAccounting";
00324   public static final String HOUSEHOLD_ACCOUNTING_STEP = "householdsAccounting";
00325   public static final String IMPORTEXPORT_ACCOUNTING_STEP = "importExportAccounting";
00326   public static final String FIRMS_PRICE_UPDATING_STEP = "firmsPriceUpdating";
00327   public static final String FIRMS_DESIRED_PRODUCTION_UPDATING_STEP = 
00328                                                               "firmsDesiredProductionUpdating";
00329   public static final String UPDATE_LABOR_PRODUCTIVITY_STEP = "updateLaborProductivity";
00330   public static final String SETTING_INTEREST_RATE_STEP = "settingInterestRate";
00331   public static final String FIRMS_ENTRY_AND_EXIT_STEP = "firmsEntryAndExit";
00332   public static final String GENETIC_EVOLUTION_OF_TECHNOLOGIES_STEP = 
00333                                                               "geneticEvolutionOfTechnologies";
00334   public static final String GENETIC_EVOLUTION_OF_PRICES_STEP = "geneticEvolutionOfPrices";
00335   public static final String GENETIC_EVOLUTION_OF_WAGES_STEP = "geneticEvolutionOfWages";
00336 
00340   private static final int NUM_INIT_CONSUMPTION_TECHNOLOGY_MUTATIONS = 10;
00341   
00346   @Origin(TECHNICAL)
00347   private static final boolean USE_PROFILER = false;
00348 
00350   @Origin(TECHNICAL)
00351   private static RandomGenerator random;
00352 
00354   @Description("Statistics about the CO2 emission caused by production and trading.")
00355   private final EmissionProbe emissionProbe = new EmissionProbe();
00356 
00358   @Description("List of all trades in a single period")
00359   @Origin(TECHNICAL)
00360   private TradeTrace tradeTrace = new TradeTrace(Foundation.this);
00361 
00363   @SuppressWarnings("unused")
00364   @Origin(TECHNICAL)
00365   private static ProductionFunctionFactory productionFunctionFactory =
00366       new ProductionFunctionFactory();
00367 
00369   @SuppressWarnings("unused")
00370   @Origin(TECHNICAL)
00371   private static ConsumptionTechnologyFactory consumptionTechnologyFactory =
00372       new ConsumptionTechnologyFactory();
00373 
00375   private Government government;
00376 
00378   private Financial financial;
00379 
00384   private final LinkedList<Sector> sectorList = new LinkedList<Sector>();
00385 
00387   private static FoundationInitValues initValues;
00388 
00390   @NotNegative
00391   private int period;
00392 
00397   private final HouseholdSet households = new HouseholdSet();
00398 
00405   public Foundation(int pSeed, ProbeManager pProbeManager) {
00406     super(pSeed, pProbeManager);
00407   }
00408 
00409   @Override
00410   protected InitValuesManager createInitValues() {
00411     final InitValuesManager lIVM = new InitValuesManagerWithSectors();
00412     initValues = new FoundationInitValues(lIVM);
00413     initValues.setSeed(seed);
00414     return lIVM;
00415   }
00416 
00417   @Override
00418   protected StepManager createStepManager() {
00419     if (useProfiler()) {
00420       return (new StepManagerWithProfiler("de.pik.lagom.generic"));
00421     } else {
00422       return (new StepManager("de.pik.lagom.generic"));
00423     }
00424   }
00425 
00426   @Override
00427   @PostValidateThis
00428   protected void initModel() throws ParameterParserException, ValueValidationException {
00429     random = new RandomGenerator(initValues.getSeed());
00430     period = 0;
00431     Household.resetId();
00432 
00433     registerSteps(); // must be done before the first init call
00434     registerCallbacks(stepManager);
00435 
00436     government = new Government(this, initValues.governmentInitValues());
00437     financial = new Financial(this, initValues.financialInitValues());
00438     constructSectors();
00439 
00440     government.init();
00441     financial.init();
00442     initHouseholds();
00443     initSectors();
00444     initTradeNetwork();
00445 
00446     emissionProbe.init();
00447     tradeTrace.init();
00448 
00449 
00450     if (stepManager instanceof StepManagerWithProfiler) {
00451       probeManager.addProbe(((StepManagerWithProfiler) stepManager).getProbe());
00452     }
00453 
00454     stepManager.initFinished();
00455   }
00456   
00457   private void registerCallbacks(StepManager pStepManager) {
00458     // reset the TradeTrace before the exchange step
00459     pStepManager.registerCallback(EXCHANGE_STEP,
00460                                   StepManager.Timing.PRE,
00461                                   1,
00462                                   new Callback() {
00463       @Override
00464       public void preStep() {
00465         tradeTrace.clear();
00466       }
00467 
00468       @Override
00469       public Object getOwner() {
00470         return Foundation.this;
00471       }
00472     }
00473     );
00474   } 
00475 
00477   private void initHouseholds() throws ParameterParserException {
00478     households.clear();
00479 
00480     final int lNumHouseholds = getNumHouseholdsTotal();
00481     for (int i = 0; i < lNumHouseholds; i++)
00482     {
00483       final Household lHousehold = new Household(this, initValues.householdInitValues());
00484       households.add(lHousehold);
00485     }
00486 
00487     for (final Household lHousehold : households) {
00488       lHousehold.init();
00489     }
00490 
00491     initMutateConsumptionTechnology();
00492   }
00493 
00501   void initMutateConsumptionTechnology() {
00502     final int lNumSectors = getNumSectors();
00503 
00504     // The map contains the consumption technology coefficients of all household of a
00505     // single mutation pass.
00506     final Map<Household, double[]> lPassVariatorResults = new HashMap<Household, double[]>();
00507     // This map contains the mutation that has the lowest difference to the original consumption
00508     Map<Household, double[]> lBestVariatorResults = new HashMap<Household, double[]>();
00509 
00510     final DoubleInterval[] lTechnologyMutation = new DoubleInterval[lNumSectors];
00511     final double[] lPrices = ArrayTools.createArray(lNumSectors, 1.d);
00512 
00513     double lMinimalDifference = Double.MAX_VALUE;
00514     final double lMutationLevel = initValues.householdInitValues().
00515                                              getInitialConsumptionTechnologyMutation();
00516 
00517     // mutate the households NUM_INIT_CONSUMPTION_TECHNOLOGY_MUTATIONS times
00518     for (int iPass = 0; iPass < NUM_INIT_CONSUMPTION_TECHNOLOGY_MUTATIONS; iPass++) {
00519       // init mutation intervals for the iPass-th pass. They are modified after a households
00520       // coefficients were mutated for a better approximation of the orignal consumption   
00521       for (int iSector = 0; iSector < lNumSectors; iSector++) {
00522         lTechnologyMutation[iSector] = new DoubleInterval(-lMutationLevel, lMutationLevel);
00523       }
00524 
00525       double lSumMutatedConsumption[] = new double[lNumSectors];
00526       int lNumHouseholdsMutated = 0;
00527 
00528       // mutate the single households
00529       for (final Household lHousehold : households) {
00530         lNumHouseholdsMutated++;
00531 
00532         final double[] lMutatedResults =
00533                 lHousehold.getConsumptionTechnology().mutateCoefficients(lTechnologyMutation,
00534                                                                          getNumSectors());
00535 
00536         // store the result of the mutation
00537         lPassVariatorResults.put(lHousehold, lMutatedResults);
00538 
00539         // add the consumption of the mutated household to the consumption of all mutated
00540         // households
00541         lSumMutatedConsumption = ArrayTools.addArrays(lSumMutatedConsumption, 
00542                                                    lHousehold.calcDemand(lHousehold.getMoney(),
00543                                                                          lPrices,
00544                                                                          lMutatedResults));
00545 
00546         // compare for each sector the average of the mutated consumption with the average
00547         // of the original consumption. If it's higher, mutate the coefficients of the following
00548         // household only to higher values (with will lower the demand), if it's lower, lower
00549         // the coefficients.
00550         for (int iSector = 0; iSector < lNumSectors; iSector++) {
00551           if (lSumMutatedConsumption[iSector] < 
00552                                 initValues.sectorInitValues().getConsumptionArray()[iSector] *
00553                                               lNumHouseholdsMutated / getNumHouseholdsTotal()) {
00554             lTechnologyMutation[iSector].set(0.d, lMutationLevel);
00555           } else {
00556             lTechnologyMutation[iSector].set(-lMutationLevel, 0.d);
00557           }
00558         }
00559       }
00560 
00561       // check the consumption difference between the mutated and original consumption and
00562       // store the mutation with the lowest difference.
00563       if (lMinimalDifference > calcDifference(lSumMutatedConsumption)) {
00564         lBestVariatorResults = new HashMap<Household, double[]>(lPassVariatorResults);
00565         lMinimalDifference = calcDifference(lSumMutatedConsumption);
00566       }
00567     }
00568 
00569     // after all passes take the best mutation and set the consumption technology coefficients
00570     // of the households to the values of this mutation
00571     for (final Household lHousehold : lBestVariatorResults.keySet()) {
00572       final double[] lVariatorResults = lBestVariatorResults.get(lHousehold);
00573       lHousehold.setConsumptionTechnologyCoefficients(lVariatorResults);
00574     }
00575   }
00576 
00581   private double calcDifference(double[] pConsumption) {
00582     double lDifference = 0;
00583     for (final Sector lSector : sectorList) {
00584       lDifference += Math.abs(pConsumption[lSector.getArrayIndex()] -
00585                   initValues.sectorInitValues().getConsumptionArray()[lSector.getArrayIndex()]);
00586     }
00587     return lDifference;
00588   }
00589 
00590   @Override
00591   public void deinitModel() {
00592     stepManager.reset();
00593     probeManager.removeAllProbes();
00594   }
00595 
00596   private void registerSteps() {
00597     stepManager.reset();
00598     registerStep(PREPARATORY_STEP, true);
00599     registerStep(EXCHANGE_STEP, true);
00600     registerStep(UPDATE_BENCHMARK_WAGE_STEP,true);
00601     registerStep(HOUSEHOLDS_ADJUST_EMPLOYMENT_STEP, true);
00602     registerStep(FIRMS_ADJUST_WORKFORCE_STEP, true);
00603     registerStep(PRODUCTION_STEP, true);
00604     registerStep(CONSUMPTION_STEP, true);
00605     registerStep(FIRM_ACCOUNTING_STEP, true);
00606     registerStep(HOUSEHOLD_ACCOUNTING_STEP, true);
00607     registerStep(IMPORTEXPORT_ACCOUNTING_STEP, true);
00608     registerStep(FIRMS_DESIRED_PRODUCTION_UPDATING_STEP, initValues.isFirmsBeliefUpdating());
00609     registerStep(FIRMS_PRICE_UPDATING_STEP, initValues.isFirmsBeliefUpdating());
00610     registerStep(UPDATE_LABOR_PRODUCTIVITY_STEP, true);
00611     registerStep(SETTING_INTEREST_RATE_STEP, initValues.isFinancialSettingTheInterestRate());
00612     registerStep(FIRMS_ENTRY_AND_EXIT_STEP, initValues.isFirmEntryAndExit());
00613     registerStep(GENETIC_EVOLUTION_OF_TECHNOLOGIES_STEP,
00614                  initValues.isGeneticEvolutionTechnologies());
00615     registerStep(GENETIC_EVOLUTION_OF_PRICES_STEP, initValues.isGeneticEvolutionPrices());
00616     registerStep(GENETIC_EVOLUTION_OF_WAGES_STEP, initValues.isGeneticEvolutionWages());
00617   }
00618 
00619   private void registerStep(String pStepName, boolean pActive) {
00620     try {
00621       stepManager.registerStep("Foundation", pStepName, this,
00622                                pActive ? StepManager.Status.ENABLED
00623                                        : StepManager.Status.DISABLED);
00624     } catch (final Exception e) {
00625       e.printStackTrace();
00626     }
00627   }
00628 
00637   private void constructSectors() {
00638     sectorList.clear();
00639     final int lNumSectors = initValues.sectorInitValues().getNumSectors();
00640     assert (lNumSectors > 0): "There must be at least one Sector";
00641     for (int i = 0; i < lNumSectors; i++)
00642     {
00643       final Sector lSector = new Sector(this, initValues.sectorInitValues(), i);
00644       sectorList.add(lSector);
00645     }
00646   }
00647 
00653   private void initSectors() throws ValueValidationException, ParameterParserException {
00654     for (final Sector lSector : sectorList) {
00655       lSector.init();
00656     }
00657   }
00658 
00659   
00663   private void initTradeNetwork(){
00664     for (final Sector lSector : sectorList) {
00665       // construct a list of all buyers
00666       final List<IBuyer> lBuyersList = new LinkedList<IBuyer>();
00667       final List<Firm> lFirms = generateFirmList();
00668       final List<Household> lHouseholds = households.getCopyAsLinkedList();
00669       lBuyersList.addAll(lFirms);
00670       lBuyersList.addAll(lHouseholds);
00671       lBuyersList.add(lSector.getImportExport());
00672       // construct a list of all sellers
00673       final List<ISeller> lSellersList= new LinkedList<ISeller>();
00674       lSellersList.addAll(lSector.getFirmList());
00675       lSellersList.add(lSector.getImportExport());
00676       // compute total demand
00677       double lTotalDemand =0;
00678       for (final IBuyer lBuyer : lBuyersList){
00679         lTotalDemand += lBuyer.getBenchmarkDemand(lSector);
00680       }
00681       // compute total supply
00682       double lTotalSupply =0;
00683       for (final ISeller lSeller : lSellersList){
00684         lTotalSupply += lSeller.getBenchmarkSupply();
00685       }
00686       // the demand/supply ratio 
00687       final double lDemandSupplyRatio= lTotalDemand/lTotalSupply;
00688       
00689       random.shuffle(lBuyersList);
00690       final Iterator<ISeller> iterSellers= lSellersList.iterator();
00691       ISeller lSeller=iterSellers.next();
00692       double lSupply = lDemandSupplyRatio*lSeller.getBenchmarkSupply();
00693       for (final IBuyer lBuyer : lBuyersList){
00694         lBuyer.getSuppliers(lSector).getAvailableSuppliers().addAll(lSellersList);
00695         assert(lBuyer.getSuppliers(lSector).getAvailableSuppliers().contains(lSeller));
00696         double lDemand = lBuyer.getBenchmarkDemand(lSector);
00697         while(!FloatMath.lowerOrApproxZero(lDemand) && lBuyer.getSuppliers(lSector).canExtraSuppliers() &&
00698             (lSupply>0 || iterSellers.hasNext())){
00699           assert(lBuyer.getSuppliers(lSector).getAvailableSuppliers().contains(lSeller));
00700           double lMin =Math.min(lDemand, lSupply);
00701           lDemand-= lMin;
00702           lSupply-=lMin;
00703           lBuyer.getSuppliers(lSector).addSeller(lSeller);
00704           if(FloatMath.lowerOrApproxZero(lSupply) && iterSellers.hasNext()){
00705             lSeller=iterSellers.next();
00706             lSupply=  lDemandSupplyRatio*lSeller.getBenchmarkSupply();
00707           }
00708         }
00709         if ( lBuyer.getBenchmarkDemand(lSector)>0){
00710         assert(lBuyer.getSuppliers(lSector).getNumFoundSuppliers()>0);
00711         }
00712         assert(!iterSellers.hasNext() || FloatMath.lowerOrApproxZero(lDemand)); 
00713         
00714     }
00715 
00716 
00717     }   
00718 
00719   } 
00720   
00722   @Override
00723   @PreValidateThis
00724   synchronized public void advanceOnePeriod() {
00725     if (!isInitialized) {
00726       assert(false) : "Initialize the model via start()";
00727     }
00728 
00729     period++;
00730 
00731     stepManager.executeStep(PREPARATORY_STEP);
00732     stepManager.executeStep(EXCHANGE_STEP);
00733     stepManager.executeStep(UPDATE_BENCHMARK_WAGE_STEP);
00734     stepManager.executeStep(HOUSEHOLDS_ADJUST_EMPLOYMENT_STEP);
00735     stepManager.executeStep(FIRMS_ADJUST_WORKFORCE_STEP);
00736     stepManager.executeStep(UPDATE_LABOR_PRODUCTIVITY_STEP);
00737     stepManager.executeStep(PRODUCTION_STEP);
00738     stepManager.executeStep(CONSUMPTION_STEP);
00739     stepManager.executeStep(FIRM_ACCOUNTING_STEP);
00740     stepManager.executeStep(HOUSEHOLD_ACCOUNTING_STEP);
00741     stepManager.executeStep(IMPORTEXPORT_ACCOUNTING_STEP);
00742     stepManager.executeStep(FIRMS_PRICE_UPDATING_STEP);
00743     stepManager.executeStep(FIRMS_DESIRED_PRODUCTION_UPDATING_STEP);
00744     stepManager.executeStep(SETTING_INTEREST_RATE_STEP);
00745     stepManager.executeStep(GENETIC_EVOLUTION_OF_TECHNOLOGIES_STEP);
00746     stepManager.executeStep(GENETIC_EVOLUTION_OF_PRICES_STEP);
00747     stepManager.executeStep(GENETIC_EVOLUTION_OF_WAGES_STEP);
00748     stepManager.executeStep(FIRMS_ENTRY_AND_EXIT_STEP);
00749   }
00750 
00754   public void preparatoryStep() {
00755     for (final Firm lFirm : generateFirmList()) {
00756       lFirm.setProfit(0.d);
00757       lFirm.setSoldQuantity(0.d);
00758       lFirm.setCosts(0.d);
00759       lFirm.setSalesValue(0.d);
00760       lFirm.setIntermediaryConsumptionValue(0.d);
00761       lFirm.setInvestmentValue(0.d);
00762       assert (lFirm.getOwner() != null);
00763     }
00764     
00765     for (final Household lHousehold : getHouseholds()) {
00766       lHousehold.setEmploymentIncome(0.d);
00767     }
00768   }
00769 
00775   public void exchangeStep() {
00776     final List<IBuyer> lFirmAndHouseholds = new LinkedList<IBuyer>();
00777     final List<Firm> lFirms = generateFirmList();
00778     final List<Household> lHouseholds = households.getCopyAsLinkedList();
00779     // bring the collection into a random order
00780     if (initValues.isRandomTradeOrder()) {
00781       lFirmAndHouseholds.addAll(lFirms);
00782       lFirmAndHouseholds.addAll(lHouseholds);
00783       random.shuffle(lFirmAndHouseholds);
00784     } else { // first the firms, then the households
00785       random.shuffle(lFirms);
00786       lFirmAndHouseholds.addAll(lFirms);
00787       random.shuffle(lHouseholds);
00788       lFirmAndHouseholds.addAll(lHouseholds);
00789     }
00790 
00791     for (final IBuyer lTrader : lFirmAndHouseholds) {
00792       lTrader.trade();
00793     }
00794 
00795     for (final Sector lSector : getSectorList()) {
00796       lSector.getImportExport().trade();
00797     }
00798 
00799     financial.updateInflationRate();
00800 
00801     // Each firm stores the state of its inventory
00802     for (final Firm lFirm : generateFirmList()) {
00803       lFirm.storeInventoryAfterTrade();
00804     }
00805   }
00806 
00812   public void updateBenchmarkWage() {
00813     if ((period % initValues.getBenchmarkWageInterval()) == 0) {
00814       for (final Sector lSector : sectorList) {
00815         lSector.updateBenchmarkWage();
00816       }
00817     }
00818   }
00819   
00826   public void householdsAdjustEmployment() {
00827 
00828     if ((period % initValues.getAdjustEmploymentInterval()) == 0) {
00829       final List<Household> lHouseholds = households.getCopyAsLinkedList();
00830       random.shuffle(lHouseholds);
00831       for (final Household lHousehold : lHouseholds) {
00832         lHousehold.adjustEmploymentStatus();
00833       }
00834     }
00835   }
00836 
00843   public void firmsAdjustWorkforce() {
00844     if ((period % initValues.getAdjustEmploymentInterval()) == 0) {
00845       final List<Firm> lFirms = generateFirmList();
00846       random.shuffle(lFirms);
00847 
00848       for (final Firm lFirm : lFirms) {
00849         lFirm.adjustEmployees();
00850       }
00851     }
00852   }
00853 
00859   public void updateLaborProductivity() {
00860     if (initValues.isLaborProductivityUpdating()) {
00861       for (final Sector lSector : sectorList) {
00862         lSector.updateLaborProductivity();
00863       }
00864     }
00865     else{
00866       double lRate= initValues.getExogenousLaborProductivityGrowthRate();
00867       for (final Sector lSector : sectorList) {
00868         double lLaborProductivity = lSector.getLaborProductivity() ;
00869         lSector.setLaborProductivity(lLaborProductivity*(1+lRate));
00870       }
00871     }
00872   }
00873 
00879   public void production() {
00880     for (final Firm lFirm : generateFirmList()) {
00881       lFirm.productionStep();
00882     }
00883   }
00884 
00890   public void consumption() {
00891     for (final Household lHousehold : getHouseholds()) {
00892       lHousehold.consume();
00893     }
00894   }
00895 
00901   public void firmAccounting() {
00902     for (final Firm lFirm : generateFirmList()) {
00903       lFirm.account();
00904     }
00905   }
00906 
00914   public void householdsAccounting() {
00915     government.calcWage();
00916 
00917     for (final Household lHousehold : getHouseholds()) {
00918       lHousehold.account();
00919     }
00920   }
00921 
00927   public void importExportAccounting() {
00928     for (final Sector lSector : getSectorList()) {
00929       lSector.getImportExport().account();
00930     }
00931   }
00932 
00938   public void firmsPriceUpdating() {
00939     if ((period % initValues.getPriceInterval()) == 0) {
00940       for (final Firm lFirm : generateFirmList()) {
00941         lFirm.updatePrice();
00942       }
00943     }
00944   }
00945   
00951   public void firmsDesiredProductionUpdating() {
00952     for (final Firm lFirm : generateFirmList()) {
00953       lFirm.updateDesiredProduction();
00954     }
00955   } 
00956 
00962   public void settingInterestRate() {
00963     if ((period % initValues.getInterestRateInterval()) == 0) {
00964       financial.updateInterestRate();
00965     }
00966   }
00967 
00977   public void geneticEvolutionOfTechnologies() {
00978     if ((period % initValues.getGeneticEvolutionTechnologiesInterval()) == 0) {
00979       // firms copy technologies
00980       for (final Sector lSector : sectorList) {
00981         lSector.firmsCopyTechnologies();
00982       }
00983 
00984       // firms mutate technologies
00985       for (final Firm lFirm : generateFirmList()) {
00986         if (getRandomGenerator().nextFloat() <
00987             initValues.sectorInitValues().firmInitValues().getMutationRate())
00988         {
00989           lFirm.mutateInputCoefficients();
00990         }
00991       }
00992       
00993       assert (getNumHouseholdsTotal() > 0): "there must be one Household in each sector";
00994       // households copy technologies
00995       // We create the list of copying Households   
00996       List<Household> lCopyingHouseholds = ListTools.sample(households.householdList, 
00997                                                           initValues.calcNumHouseholdsCopying(), 
00998                                                           random);
00999     
01000       // Each copying Household observes a sample of lNumObservedHouseholds Households 
01001       for (Household lHousehold : lCopyingHouseholds) {
01002         LinkedList<Household> lObservedHouseholds = 
01003                                         ListTools.sample(households.householdList, 
01004                                                          initValues.calcNumHouseholdsObserved(), 
01005                                                          random);
01006 
01007         // We add the observing household to the list, so that it "imitate" itself, if it has
01008         // already a better policy then the observed households
01009         lObservedHouseholds.add(lHousehold);
01010 
01011         // We sort the lObservedHouseholds according to the efficiency of their pricing policy 
01012         Household.UtilityComparator lUtilityComparator = lHousehold.new UtilityComparator();
01013         Collections.sort(lObservedHouseholds, lUtilityComparator);
01014       
01015         // and copy if one of the Household has a better policy
01016         lHousehold.imitate(lObservedHouseholds.getLast().getConsumptionTechnologyCoefficients());
01017       }
01018 
01019       // households mutate technologies
01020       for (final Household lHousehold : getHouseholds()) {
01021         lHousehold.mutateTechnologies();
01022       }
01023     }
01024   }
01032   public void firmsEntryAndExit() {
01033     for (final Sector lSector : sectorList) {
01034       lSector.dropUnproductiveFirms();
01035     }
01036 
01037     if ((period % initValues.getFirmEntryAndExitInterval()) == 0) {
01038       for (final Sector lSector : sectorList) {
01039         lSector.createNextFirmGeneration();
01040       }
01041     }
01042   }
01043 
01051   public void geneticEvolutionOfPrices() {
01052     if ((period % initValues.getGeneticEvolutionPricesInterval()) == 0) {
01053       // firms copy prices (mark-ups and wage references)
01054       for (final Sector lSector : sectorList) {
01055         lSector.firmsCopyPrices();
01056       }
01057       
01058     // firms mutate prices (mark-ups and wage references)
01059       for (final Firm lFirm : generateFirmList()) {
01060 
01061         if (getRandomGenerator().nextFloat() <
01062             initValues.sectorInitValues().firmInitValues().getMutationRate())
01063         {
01064           lFirm.mutatePrice();
01065         }
01066       }
01067     }
01068   }
01069   
01077   public void geneticEvolutionOfWages() {
01078     if ((period % initValues.getGeneticEvolutionWagesInterval()) == 0) {
01079       // firms copy prices (mark-ups and wage references)
01080       for (final Sector lSector : sectorList) {
01081         lSector.firmsCopyWages();
01082       }
01083       
01084     // firms mutate prices (mark-ups and wage references)
01085       for (final Firm lFirm : generateFirmList()) {
01086 
01087         if (getRandomGenerator().nextFloat() <
01088             initValues.sectorInitValues().firmInitValues().getMutationRate())
01089         {
01090           lFirm.mutateWageReference();
01091         }
01092       }
01093     }
01094   }
01095 
01097   double initialDesiredWage() {
01098     double lSum = 0d;
01099     for (final Sector lSector : sectorList) {
01100       lSum += lSector.getInitConsumption();
01101     }
01102     return lSum / getNumHouseholdsTotal();
01103   }
01104 
01106   @Post(expr = "_returns >= 0 && " +
01107         "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual(_returns, 1)", lang = "groovy")
01108   double calcUnemploymentRate() {
01109     return (1.d - (calcNumHouseholdsEmployed() / getNumHouseholdsTotal()));
01110   }
01111 
01113   @Post(expr = "_returns >= 0 && de.pik.lagom.toolbox.math." +
01114         "FloatMath.lowerOrApproxEqual(_returns, _this.getNumHouseholdsTotal())",
01115         lang = "groovy")
01116   double calcNumHouseholdsEmployed() {
01117     double lSumEmployment = 0.d;
01118 
01119     for (final Household lHousehold : getHouseholds()) {
01120       lSumEmployment += lHousehold.calcWorkAmount();
01121     }
01122 
01123     return lSumEmployment;
01124   }
01125 
01127   LinkedList<Firm> generateFirmList() {
01128     final LinkedList<Firm> lFirms = new LinkedList<Firm>();
01129     for (final Sector lSector : sectorList) {
01130       lFirms.addAll(lSector.getFirmList());
01131     }
01132     return lFirms;
01133   }
01134 
01136   public List<Household.Probe> generateHouseholdProbeList() {
01137     final List<Household.Probe> lProbeList = new LinkedList<Household.Probe>();
01138 
01139     for (final Household lHousehold : getHouseholds()) {
01140       lProbeList.add(lHousehold.getProbe());
01141     }
01142 
01143     return lProbeList;
01144   }
01145 
01147   public List<Sector.Probe> generateSectorProbeList() {
01148     final List<Sector.Probe> lProbeList = new LinkedList<Sector.Probe>();
01149 
01150     for (final Sector lSector : getSectorList()) {
01151       lProbeList.add(lSector.getProbe());
01152     }
01153 
01154     return lProbeList;
01155   }
01156 
01158   public List<ImportExport.Probe> generateImportExportProbeList() {
01159     final List<ImportExport.Probe> lProbeList = new LinkedList<ImportExport.Probe>();
01160 
01161     for (final Sector lSector : getSectorList()) {
01162       lProbeList.add(lSector.getImportExport().getProbe());
01163     }
01164 
01165     return lProbeList;
01166   }
01167 
01169   public LinkedList<Firm.Probe> generateFirmProbeList() {
01170     final LinkedList<Firm.Probe> lProbeList = new LinkedList<Firm.Probe>();
01171 
01172     for (final Sector lSector : getSectorList()) {
01173       for (final Firm lFirm : lSector.getFirmList()) {
01174         lProbeList.add(lFirm.getProbe());
01175       }
01176     }
01177 
01178     return lProbeList;
01179   }
01180 
01190   double[] generatePriceVector() {
01191     final double[] lPriceVector = new double[getNumSectors()];
01192 
01193     for (final Sector lSector : sectorList) {
01194       lPriceVector[lSector.getArrayIndex()] = lSector.getStats().getAverageTradePrice();
01195     }
01196 
01197     return lPriceVector;
01198   }
01199 
01200   // getter/setter methods
01201   public static FoundationInitValues getInitValues() {
01202     return initValues;
01203   }
01204 
01205   public Government getGovernment() {
01206     return government;
01207   }
01208 
01209   public Financial getFinancial() {
01210     return financial;
01211   }
01212 
01213   HouseholdSet getHouseholds() {
01214     return households;
01215   }
01216 
01217   List<Sector> getSectorList() {
01218     return sectorList;
01219   }
01220 
01221   Sector getSectorWithIndex(int pIndex) {
01222     for (final Sector lSector : sectorList) {
01223       if (lSector.getArrayIndex() == pIndex) {
01224         return lSector;
01225       }
01226     }
01227 
01228     throw new IllegalArgumentException();
01229   }
01230 
01231   public int getNumHouseholdsTotal() {
01232     return initValues.getNumHouseholds();
01233   }
01234 
01235   public int getNumSectors() {
01236     return sectorList.size();
01237   }
01238 
01239   static public RandomGenerator getRandomGenerator() {
01240     return random;
01241   }
01242 
01243   public void setInitValues(FoundationInitValues pFoundationInitValues) {
01244     initValues = pFoundationInitValues;
01245   }
01246 
01247   int getPeriod() {
01248     return period;
01249   }
01250 
01251   double getPeriodAsYear() {
01252     return initValues.getStartingYear() + (double) getPeriod()
01253             / initValues.getNumPeriodsPerYear();
01254   }
01255 
01256   int getNumFirms() {
01257     int lNumFirms = 0;
01258     for (final Sector lSector : sectorList) {
01259       lNumFirms += lSector.getNumFirms();
01260     }
01261     return lNumFirms;
01262   }
01263 
01264   public ProbeManager getProbeManager() {
01265     return probeManager;
01266   }
01267 
01268   public EmissionProbe getEmissionProbe() {
01269     return emissionProbe;
01270   }
01271 
01272   double getInitOverallProduction() {
01273     return initValues.overallProduction();
01274   }
01275 
01276   double getInitOverallConsumption() {
01277     return initValues.overallConsumption();
01278   }
01279   
01280   boolean isWagesIndexed(){
01281     return initValues.isWagesIndexed();
01282   }
01283   
01284   boolean isInitEquilibrium(){
01285     return initValues.isInitEquilibrium();
01286   }
01287 
01288   double getInitWageVariation() {
01289     return initValues.getWageVariation();
01290   }
01291 
01292   public Probe getProfilerProbe() {
01293     if (stepManager instanceof StepManagerWithProfiler) {
01294       return ((StepManagerWithProfiler) stepManager).getProbe();
01295     }
01296     return null;
01297   }
01298 
01299   @Override
01300   public boolean useProfiler() {
01301     return USE_PROFILER;
01302   }
01303 
01304   @Override
01305   public void setSeed(int pSeed) {
01306     seed = pSeed;
01307     if (initValues != null) {
01308       initValues.setSeed(pSeed);
01309     }
01310   }
01311 
01312   @Override
01313   public int getSeed() {
01314     return initValues.getSeed();
01315   }
01316 
01317   @Override
01318   public double getStartingYear() {
01319     return initValues.getStartingYear();
01320   }
01321 
01322   @Override
01323   public double getPeriodLength() {
01324     return 1. / initValues.getNumPeriodsPerYear();
01325   }
01326 
01327   public TradeTrace getTradeTrace() {
01328     return tradeTrace;
01329   }
01330 
01331   
01332 } // end of class Foundation
01333 
01335 // EOF

Generated on Tue Sep 14 11:11:48 2010 for lagom_generiC by  doxygen 1.5.4