00001
00002
00003
00004
00005
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
00315
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();
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
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
00505
00506 final Map<Household, double[]> lPassVariatorResults = new HashMap<Household, double[]>();
00507
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
00518 for (int iPass = 0; iPass < NUM_INIT_CONSUMPTION_TECHNOLOGY_MUTATIONS; iPass++) {
00519
00520
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
00529 for (final Household lHousehold : households) {
00530 lNumHouseholdsMutated++;
00531
00532 final double[] lMutatedResults =
00533 lHousehold.getConsumptionTechnology().mutateCoefficients(lTechnologyMutation,
00534 getNumSectors());
00535
00536
00537 lPassVariatorResults.put(lHousehold, lMutatedResults);
00538
00539
00540
00541 lSumMutatedConsumption = ArrayTools.addArrays(lSumMutatedConsumption,
00542 lHousehold.calcDemand(lHousehold.getMoney(),
00543 lPrices,
00544 lMutatedResults));
00545
00546
00547
00548
00549
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
00562
00563 if (lMinimalDifference > calcDifference(lSumMutatedConsumption)) {
00564 lBestVariatorResults = new HashMap<Household, double[]>(lPassVariatorResults);
00565 lMinimalDifference = calcDifference(lSumMutatedConsumption);
00566 }
00567 }
00568
00569
00570
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
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
00673 final List<ISeller> lSellersList= new LinkedList<ISeller>();
00674 lSellersList.addAll(lSector.getFirmList());
00675 lSellersList.add(lSector.getImportExport());
00676
00677 double lTotalDemand =0;
00678 for (final IBuyer lBuyer : lBuyersList){
00679 lTotalDemand += lBuyer.getBenchmarkDemand(lSector);
00680 }
00681
00682 double lTotalSupply =0;
00683 for (final ISeller lSeller : lSellersList){
00684 lTotalSupply += lSeller.getBenchmarkSupply();
00685 }
00686
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
00780 if (initValues.isRandomTradeOrder()) {
00781 lFirmAndHouseholds.addAll(lFirms);
00782 lFirmAndHouseholds.addAll(lHouseholds);
00783 random.shuffle(lFirmAndHouseholds);
00784 } else {
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
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
00980 for (final Sector lSector : sectorList) {
00981 lSector.firmsCopyTechnologies();
00982 }
00983
00984
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
00995
00996 List<Household> lCopyingHouseholds = ListTools.sample(households.householdList,
00997 initValues.calcNumHouseholdsCopying(),
00998 random);
00999
01000
01001 for (Household lHousehold : lCopyingHouseholds) {
01002 LinkedList<Household> lObservedHouseholds =
01003 ListTools.sample(households.householdList,
01004 initValues.calcNumHouseholdsObserved(),
01005 random);
01006
01007
01008
01009 lObservedHouseholds.add(lHousehold);
01010
01011
01012 Household.UtilityComparator lUtilityComparator = lHousehold.new UtilityComparator();
01013 Collections.sort(lObservedHouseholds, lUtilityComparator);
01014
01015
01016 lHousehold.imitate(lObservedHouseholds.getLast().getConsumptionTechnologyCoefficients());
01017 }
01018
01019
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
01054 for (final Sector lSector : sectorList) {
01055 lSector.firmsCopyPrices();
01056 }
01057
01058
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
01080 for (final Sector lSector : sectorList) {
01081 lSector.firmsCopyWages();
01082 }
01083
01084
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
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 }
01333
01335