src/de/pik/lagom/generic/Sector.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 
00010 import java.util.Collections;
00011 import java.util.HashMap;
00012 import java.util.Iterator;
00013 import java.util.LinkedList;
00014 import java.util.List;
00015 import java.util.Map;
00016 import java.util.NoSuchElementException;
00017 
00018 import net.sf.oval.constraint.GreaterOrApproxZero;
00019 import net.sf.oval.constraint.NotNull;
00020 import net.sf.oval.guard.Guarded;
00021 import net.sf.oval.guard.Post;
00022 import net.sf.oval.guard.PostValidateThis;
00023 import de.pik.lagom.annotations.Description;
00024 import de.pik.lagom.annotations.Initialization;
00025 import static de.pik.lagom.annotations.Initialization.*;
00026 import de.pik.lagom.annotations.NameInUI;
00027 import de.pik.lagom.annotations.Variability;
00028 import static de.pik.lagom.annotations.Variability.*;
00029 import de.pik.lagom.annotations.WriteToFile;
00030 import de.pik.lagom.exceptions.ParameterParserException;
00031 import de.pik.lagom.exceptions.ValueValidationException;
00032 import de.pik.lagom.generic.initvalues.SectorInitValues;
00033 import de.pik.lagom.generic.productionfunction.ProductionFunction;
00034 import de.pik.lagom.toolbox.ArrayTools;
00035 import de.pik.lagom.toolbox.ListTools;
00036 import de.pik.lagom.toolbox.ProbeBase;
00037 import de.pik.lagom.toolbox.StepManager;
00038 import de.pik.lagom.toolbox.StepManager.Callback;
00039 import de.pik.lagom.toolbox.math.DoubleInterval;
00040 import de.pik.lagom.toolbox.math.FloatMath;
00041 import de.pik.lagom.toolbox.math.RandomGenerator;
00042 import de.pik.lagom.toolbox.math.ValueMemory;
00043 
00050 @Guarded
00051 public class Sector  {
00052   public class Probe extends ProbeBase {
00053     public class StepCallback extends Callback {
00054       @Override
00055       public Object getOwner() {
00056         return Sector.Probe.this;
00057       }
00058     }
00059 
00060     public void init() {
00061       registerCallbacks(foundation.getStepManager());
00062     }
00063 
00064     private void registerCallbacks(StepManager pStepManager) {
00065       pStepManager.registerCallback(Foundation.EXCHANGE_STEP,
00066                                     StepManager.Timing.POST,
00067                                     1,
00068                                     new StepCallback() {
00069         @Override
00070         public void postStep() {
00071           inventoryAfterTrade = 0.d;
00072           for (final Firm lFirm : firmList) {
00073             inventoryAfterTrade += lFirm.getInventory();
00074           }
00075         }
00076       }
00077       );
00078 
00079       pStepManager.registerCallback(Foundation.CONSUMPTION_STEP,
00080                                     StepManager.Timing.PRE,
00081                                     1,
00082                                     new StepCallback() {
00083         @Override
00084         public void preStep() {
00085           overallConsumption = 0.d;
00086         }
00087       }
00088       );
00089     }
00090 
00095     private double overallConsumption = 0.d;
00100     private double inventoryAfterTrade = 0.d;
00101 
00102     @Override
00103     public String toString() {
00104       return Sector.this.toString();
00105     }
00106 
00107     @Override
00108     public String portrayalName() {
00109       return name;
00110     }
00111 
00116     public LinkedList<Firm.Probe> generateFirmProbeList() {
00117       final LinkedList<Firm.Probe> lProbeList = new LinkedList<Firm.Probe>();
00118 
00119       for (final Firm lFirm : getFirmList()) {
00120         lProbeList.add(lFirm.getProbe());
00121       }
00122 
00123       return lProbeList;
00124     }
00125 
00130     void reportConsumption(double pAmount) {
00131       overallConsumption += pAmount;
00132     }
00133 
00134     @WriteToFile
00135     @NameInUI("Inventory Before Trade")
00136     @Description("The inventory of the produced good before the trading process")
00137     public double getInventory() {
00138       double lSum = 0d;
00139       for (final Firm lFirm : firmList) {
00140         lSum += lFirm.getInventory();
00141       }
00142       return lSum;
00143     }
00144 
00145     @WriteToFile
00146     @NameInUI("Inventory After Trade")
00147     @Description("The sum of the inventory of produced goods after the trading process")
00148     public double getInventoryAfterTrade() {
00149       return inventoryAfterTrade;
00150     }
00151 
00152     @WriteToFile
00153     @NameInUI("Benchmark Wage")
00154     public double getBenchmarkWage() {
00155       return benchmarkWage;
00156     }
00157 
00158     @WriteToFile
00159     @NameInUI("Production")
00160     @Description("The total production in the sector")
00161     public double getProductionUnits() {
00162       return stats.getOverallProduction();
00163     }
00164     
00165     @WriteToFile
00166     @NameInUI("Production Capacity")
00167     public double getProductionCapacity() {
00168       double lSum=0;
00169       for(final Firm lFirm : firmList){
00170         lSum+=lFirm.getMaxProductionFromFixed();
00171         
00172       }
00173       return lSum;
00174     }
00175     
00176     @WriteToFile
00177     @NameInUI("Capacity Utilization Rate")
00178     public double getCapacityUtilizationRate() {
00179       double lSum=0;
00180       for(final Firm lFirm : firmList){
00181         lSum+=lFirm.getMaxProductionFromFixed();
00182         
00183       }
00184       return stats.getOverallProduction()/lSum;
00185     }
00186     
00187     
00188     @WriteToFile
00189     @NameInUI("Production Gap")
00190     public double getProductionGap() {
00191       double lSum=0;
00192       for(final Firm lFirm : firmList){
00193         lSum+=lFirm.getProductionGap();
00194         
00195       }
00196       return lSum;
00197     }
00198     
00199     @NameInUI("Rationing Households")
00200     public double getRationingHouseholds() {
00201       double lSum=0;
00202 
00203       for (final Household lHousehold : foundation.getHouseholds()) {
00204         lSum+=lHousehold.getRationing()[arrayIndex];
00205       }     
00206       return lSum;
00207     }
00208     
00209     @NameInUI("Rationing Firms")
00210     public double getRationingFirms() {
00211       double lSum=0;
00212       for(final Firm lFirm : firmList){
00213         lSum+=lFirm.getRationing()[arrayIndex];
00214         
00215       }
00216       return lSum;
00217     }
00218     
00219     
00220     @NameInUI("Number of Suppliers")
00221     public double getNumSuppliers() {
00222       double lSum=0;
00223       for(final Firm lFirm : firmList){
00224         lSum+=lFirm.getSuppliers()[arrayIndex].getNumFoundSuppliers();
00225         
00226       }
00227       for (final Household lHousehold : foundation.getHouseholds()) {
00228         lSum+=lHousehold.getSuppliers()[arrayIndex].getNumFoundSuppliers();
00229       }     
00230       return lSum/(foundation.getNumFirms()+foundation.getNumHouseholdsTotal());
00231     }
00232     
00233     
00234     @NameInUI("Consumption coefficient")
00235     public double getConsumptionCoefficient() {
00236       double lCoeff=0;
00237       for (final Household lHousehold : foundation.getHouseholds()) {
00238         lCoeff+=lHousehold.getConsumptionTechnologyCoefficients()[arrayIndex];
00239       }     
00240       return (lCoeff/foundation.getNumHouseholdsTotal());
00241     }   
00242     
00243     
00244     @WriteToFile
00245     @NameInUI("Capital Reserve rate")
00246     public double getCapitalReserveRate() {
00247       return getAverageCapitalReserveRate();
00248     }
00249 
00250     @WriteToFile
00251     @NameInUI("Investment periodicity")
00252     @Description("The average (over firms and over types of goods) periodicity of investment")
00253     public double getAverageInvestmentPeriodicity() {
00254       double lAverage=0;
00255       for (final Sector lSector : foundation.getSectorList()) {
00256         lAverage+= getInvestmentPeriodicity(lSector.getArrayIndex());
00257       }
00258       return (lAverage/foundation.getNumSectors());
00259     }
00260     
00261     @WriteToFile
00262     @NameInUI("Labor Capacity")
00263     @Description("The rate of vacant job filled in the sector")
00264     public double getAverageLaborCapacity() {
00265       return stats.getAverageLaborCapacity();
00266     }
00267 
00268     @WriteToFile
00269     @NameInUI("Production Growth Rate")
00270     @Description("The average growth rate of production in the sector")
00271     public double getAverageGrowthRateProduction() {
00272       return stats.getAverageGrowthRateProduction();
00273     }
00274   /*  
00275     @WriteToFile
00276     @NameInUI("Capital reserve  Rate")
00277     @Description("The average growth rate of production in the sector")
00278     public double getAverageCapitalReserveRate() {
00279       return getAverageCapitalReserveRate() ;
00280     }
00281 */
00282     @WriteToFile
00283     @NameInUI("Number of Firms")
00284     public int getNumFirms() {
00285       return getFirmList().size();
00286     }
00287 
00288     @WriteToFile
00289     @NameInUI("Consumption")
00290     @Description("The total consumption of goods produced in the sector")
00291     public double getConsumptionUnits() {
00292       return overallConsumption+1;
00293     }
00294 
00295     @WriteToFile
00296     @NameInUI("Mark-up")
00297     @Description("The average mark-up over costs of firms in that sector")
00298     public double getAverageMarkUp() {
00299       return stats.getAverageMarkUp();
00300     }
00301     
00302     @WriteToFile
00303     @NameInUI("Mark-up Std Deviation")
00304     @Description("The average mark-up over costs of firms in that sector")
00305     public double getDeviationMarkUp() {
00306       return stats.getDeviationMarkUp();
00307     }
00308 
00309     @WriteToFile
00310     @NameInUI("Average Trade Price")
00311     @Description("The average price of traded goods produced in the sector, incl. imports and exports")
00312     public double getAverageTradePrice() {
00313       return stats.getAverageTradePrice();
00314     }
00315 
00316     @WriteToFile
00317     @NameInUI("Average Trade Price without Import/Export")
00318     @Description("The average price of traded goods produced in the sector, excl. imports and exports")
00319     public double getAverageTradePriceWithoutImportExport() {
00320       return foundation.getTradeTrace().
00321                             getAverageTradePriceSelledInSectorWithoutImportExport(Sector.this);
00322     }
00323 
00324     @WriteToFile
00325     @NameInUI("Trade Value")
00326     public double getTradeValue() {
00327       return stats.getTradeValue();
00328     }
00329     
00330     @WriteToFile
00331     @NameInUI("Sales forecast")
00332     @Description("The sum of firms trade forecast")
00333     public double getSalesForecast() {
00334       double lSum = 0d;
00335       for (final Firm lFirm : firmList) {
00336         lSum += lFirm.getSalesForecast();
00337       }
00338       return lSum;
00339     }
00340     
00341     @WriteToFile
00342     @NameInUI("Trend forecast")
00343     @Description("The sum of firms trade forecast")
00344     public double getTrendForecast() {
00345       double lSum = 0d;
00346       for (final Firm lFirm : firmList) {
00347         lSum += lFirm.getSalesTrendForecast();
00348       }
00349       return lSum;
00350     }
00351 
00352     @WriteToFile
00353     @NameInUI("Labor Productivity")
00354     public double getLaborProductivity() {
00355       return laborProductivity;
00356     }
00357 
00358     @WriteToFile
00359     @NameInUI("Desired Production")
00360     public double getDesiredProduction() {
00361       return stats.getTotalDesiredProduction();
00362     }
00363 
00364     @WriteToFile
00365     @NameInUI("Average Profit")
00366     public double getAverageProfit() {
00367       return stats.getAverageProfit();
00368     }
00369 
00370     @WriteToFile
00371     @NameInUI("Wage Reference")
00372     @Description("The average of wages in new job offers")
00373     public double getAverageWage() {
00374       return stats.getAverageWageReference();
00375     }
00376 
00377     @WriteToFile
00378     @NameInUI("Workforce")
00379     @Description("The number of employees in the sector")
00380     public double getWorkforce() {
00381       double lSum = 0d;
00382       for (final Firm lFirm : firmList) {
00383         lSum += lFirm.calcWorkAmount();
00384       }
00385       return lSum;
00386     }
00387     
00388     @WriteToFile
00389     @NameInUI("Target Workforce")
00390     @Description("The number of employees in the sector")
00391     public double getTargetWorkforce() {
00392       double lSum = 0d;
00393       for (final Firm lFirm : firmList) {
00394         lSum += lFirm.getTargetEmployment();
00395       }
00396       return lSum;
00397     }
00398     
00399     @WriteToFile
00400     @NameInUI("Average Debt")
00401     public double getAverageDebt() {
00402       return stats.getAverageDebt();
00403     }
00404     
00405     @WriteToFile
00406     @NameInUI("Labor input coefficient")
00407     @Description("The average labor input coefficient")
00408     public double getLaborInputCoefficient() {
00409       double lSum = 0d;
00410       for (final Firm lFirm : firmList) {
00411         lSum += lFirm.getLaborInputCoefficient();
00412       }
00413       return lSum/firmList.size();
00414     }
00415     
00416     @WriteToFile
00417     @NameInUI("Labor input coefficient Std Deviation ")
00418     @Description("The average labor input coefficient")
00419     public double getStdDeviationLaborInputCoefficient() {
00420       double lSum = 0d;
00421       double lAverage =getLaborInputCoefficient();
00422       for (final Firm lFirm : firmList) {
00423         lSum += Math.pow(lFirm.getLaborInputCoefficient()-lAverage,2);
00424       }
00425       return Math.sqrt(lSum);
00426     }
00427     
00428     
00429     @WriteToFile
00430     @NameInUI("Circulating input coefficient")
00431     @Description("The average circulating circulating input coefficient")
00432     public double getAverageCirculatingInputCoefficient() {
00433       double lSum=0;
00434       for (final Firm lFirm : firmList) {
00435         for (int iSector=0 ; iSector< foundation.getNumSectors() ; iSector++ )
00436         lSum+= lFirm.getCirculatingInputCoefficients()[iSector];
00437       }
00438       return lSum/firmList.size();
00439     }
00440     
00441     @WriteToFile
00442     @NameInUI("Fixed input coefficient")
00443     @Description("The average fixed capital input coefficient")
00444     public double getAverageFixedInputCoefficient() {
00445       double lSum=0;
00446       for (final Firm lFirm : firmList) {
00447         for (int iSector=0 ; iSector< foundation.getNumSectors() ; iSector++ )
00448         lSum+= lFirm.getFixedInputCoefficients()[iSector];
00449       }
00450       return lSum/firmList.size();
00451     }
00452     
00453     
00454 
00455     @WriteToFile
00456     @NameInUI("Unit Costs")
00457     public double getAverageUnitCost() {
00458       return stats.getAverageCosts()/stats.getAverageProduction();
00459     }
00460     
00461     @WriteToFile
00462     @NameInUI("Benchmark Unit Costs")
00463     public double getAverageBenchmarkUnitCost() {
00464       return stats.getAverageBenchmarkCosts()/stats.getAverageProduction();
00465     }
00466 
00467     @WriteToFile
00468     @NameInUI("ProfitRate")
00469     public double getProfitRate() {
00470       return stats.getProfitRate();
00471     }
00472 
00473     @WriteToFile
00474     @NameInUI("Average Revenue")
00475     public double getAverageRevenue() {
00476       return stats.getAverageRevenue();
00477     }
00478 
00479     @WriteToFile
00480     @NameInUI("Circulation Capital Total")
00481     @Description("The sum of the circulating capital after trade")
00482     public double getAggregateCirculatingCapital() {
00483       return stats.getAggregateCirculatingCapital();
00484     }
00485 
00486     @WriteToFile
00487     @NameInUI("Fixed Capital Total")
00488     @Description("The sum of the fixed capital after trade but before production (so without " +
00489                  "depreciation)")
00490     public double getAggregateFixedCapital() {
00491       return stats.getAggregateFixedCapital();
00492     }
00493 
00494 /*    @WriteToFile
00495     @NameInUI("Capital Reserve Rate")
00496     @Description("The average capital reserve rate")
00497     public double getCapitalReserveRate(){
00498       return getAverageCapitalReserveRate();
00499     }
00500       */
00501     
00502     
00503     @WriteToFile
00504     @NameInUI("Average Price")
00505     @Description("The average demanded price (averaged over firms)")
00506     public double getAverageSupplyPriceWithoutImport() {
00507       return stats.getAverageSupplyPriceWithoutImport();
00508     }
00509 
00510     @WriteToFile
00511     @NameInUI("Traded CO2")
00512     @Description("The amount of CO2 caused by goods that firms has bought (the CO2 was " + 
00513                  "already created in the production process)")
00514     public double getCO2BoughtByFirms() {
00515       return foundation.getTradeTrace().getOverallCO2BoughtByFirmsInSector(Sector.this)
00516                 * calcCiCoef(foundation.getPeriodAsYear());
00517     }
00518 
00519     @WriteToFile
00520     @NameInUI("CO2 from Production")
00521     @Description("The amount of CO2 created by the production process in the sector")
00522     public double getCO2Produced() {
00523       return stats.getOverallProduction() * getInitUnitInPetaJoule() * 
00524                                                     calcCiCoef(foundation.getPeriodAsYear());
00525     }
00526 
00527     @WriteToFile
00528     @NameInUI("Sold Quantity Total")
00529     public double getOverallQuantitySold() {
00530       return foundation.getTradeTrace().getOverallQuantitySelledInSector(Sector.this);
00531     }
00532 
00533     @WriteToFile
00534     @NameInUI("Sold Quantity Total Without Export")
00535     public double getOverallQuantitySoldWithoutImportExport() {
00536       return foundation.getTradeTrace().
00537                               getOverallQuantitySelledInSectorWithoutImportExport(Sector.this);
00538     }
00539   } // end of inner class Probe
00540 
00542   @Guarded
00543   @Variability(PERIOD)
00544   public class Stats {
00545     @Guarded
00546     public class StepCallback extends Callback {
00547       @Override
00548       public Object getOwner() {
00549         return Sector.Stats.this;
00550       }
00551     }
00552 
00554     @GreaterOrApproxZero
00555     @Description("The sum of the capital stock of all firms in the sector after trading.")
00556     private double fixedCapitalStock[];
00557 
00559     @GreaterOrApproxZero
00560     @Description("The sum of the capital stock of all firms in the sector in the last period.")
00561     private double fixedCapitalStockLastPeriod[];
00562 
00564     @GreaterOrApproxZero
00565     @Description("The highest capital stock that existed in a simulation run.")
00566     private double maxFixedCapitalStock[];
00567 
00569     private boolean neverCalcedFixedCapitalStock = true;
00570 
00575     @GreaterOrApproxZero
00576     @Description("The average over the wage reference over all firms in the sector normed by" +
00577                  "the target employment of the firms.")
00578     private double averageWageReference;
00579     
00581     @GreaterOrApproxZero
00582     @Description("The quotient averageEmployment/averageTargetEmployment.")
00583     private double averageLaborCapacity;
00584 
00586     @GreaterOrApproxZero
00587     @Description("The average over the production costs of all firms in the sector.")
00588     private double averageCosts;
00589     
00591     @GreaterOrApproxZero
00592     @Description("The average over the production costs of all firms in the sector.")
00593     private double averageBenchmarkCosts;
00594 
00596     @GreaterOrApproxZero
00597     @Description("The average debt over all firms in the sector.")
00598     private double averageDebt;
00599 
00601     @GreaterOrApproxZero
00602     @Description("The average revenue (sold quantity * price) over all firms in the sector.")
00603     private double averageRevenue;
00604 
00606     @GreaterOrApproxZero
00607     @Description("The average target employment over all firms in the sector.")
00608     private double averageTargetEmployment;
00609 
00611     @GreaterOrApproxZero
00612     @Description("The average realized employment over all firms in the sector.")
00613     private double averageEmployment;
00614 
00616     @GreaterOrApproxZero
00617     @Description("The average firm profit over all firms in the sector.")
00618     private double averageProfit;
00619     
00620     
00625     @Description("The average profit rate over all firms in the sector normed by the " +
00626                  "produced quantities.")
00627     private double sectorProfitRate;
00628 
00630     @GreaterOrApproxZero
00631     @Description("The average supply price over all firms in the sector.")
00632     private double averageSupplyPriceWithoutImport;
00633 
00638     @GreaterOrApproxZero
00639     @Description("The average price of traded goods produced in the sector, " +
00640                  "incl. imports and exports, in the actual period.")
00641     private double averageTradePrice = 1.d;
00642 
00647     @GreaterOrApproxZero
00648     @Description("The average price of traded goods produced in the sector, " +
00649                  "incl. imports and exports, in the last period.")
00650     private double averageTradePriceLastPeriod = 1.d;
00651 
00653     @GreaterOrApproxZero
00654     @Description("The overall trade value (quantity * price) of all in the actual period " +
00655                  "sold goods")
00656     private double tradeValue = 0.d;
00657 
00659     @GreaterOrApproxZero
00660     @Description("The overall trade value (quantity * price) of all in the last period " +
00661                  "sold goods")
00662     private double tradeValueLastPeriod = 0.d;
00663 
00665     @GreaterOrApproxZero
00666     @Description("The highest supply price of a firm in the sector.")
00667     private double maxPrice = 0.d;
00668 
00670     @GreaterOrApproxZero
00671     @Description("The average mark-up over costs of firms in that sector.")
00672     private double averageMarkUp = 0.d;
00673     
00675     @GreaterOrApproxZero
00676     @Description("The average mark-up over costs of firms in that sector.")
00677     private double deviationMarkUp = 0.d;
00678 
00680     @GreaterOrApproxZero
00681     @Description("The total production in the sector.")
00682     double overallProduction = 0.d;
00683 
00685     @Description("The average growth rate of production in the sector.")
00686     double averageGrowthRateProduction = 0.d;
00687 
00689     @GreaterOrApproxZero
00690     @Description("The average desired production over all firms in the sector.")
00691     private double averageDesiredProduction;
00692     
00694     @GreaterOrApproxZero
00695     @Description("The average desired production over all firms in the sector.")
00696     private double totalDesiredProduction;
00697     
00698     // this is used for getFirmEntryAndExit
00702     @Description("The overall profits of the last " +
00703                  "FoundationInitValues::firmEntryAndExitInterval periods.")
00704     private ValueMemory memoryProfit;
00705 
00710     @Description("The sector profit rates of the last " +
00711                  "FoundationInitValues::firmEntryAndExitInterval periods.")
00712     private ValueMemory memoryProfitRate;
00713 
00717     @Description("The sector production of the last " +
00718                  "FoundationInitValues::firmEntryAndExitInterval periods.")
00719     private ValueMemory memoryProduction;
00720 
00725     @Description("The labor productivity growth rates " +
00726                  "FoundationInitValues::benchmarkWageInterval periods.")
00727     private ValueMemory memoryLaborProductivityGrowthRate;    
00728 
00729     void init() {
00730       fixedCapitalStock = new double[foundation.getNumSectors()];
00731       fixedCapitalStockLastPeriod = new double[foundation.getNumSectors()];
00732 
00733       registerCallbacks(foundation.getStepManager());
00734 
00735       calcPrices();
00736       calcDesiredProduction();
00737 
00738       final int lFirmEntryInterval = Foundation.getInitValues().getFirmEntryAndExitInterval();
00739       memoryProfit = new ValueMemory(lFirmEntryInterval);
00740       memoryProfitRate = new ValueMemory(lFirmEntryInterval);
00741       memoryProduction = new ValueMemory(lFirmEntryInterval);
00742 
00743       final int lBenchmarkInterval = Foundation.getInitValues().getBenchmarkWageInterval();
00744       memoryLaborProductivityGrowthRate = new ValueMemory(lBenchmarkInterval);
00745     }
00746 
00747     private void registerCallbacks(StepManager pStepManager) {
00748       pStepManager.registerCallback(Foundation.EXCHANGE_STEP,
00749                                     StepManager.Timing.POST,
00750                                     1,
00751                                     new StepCallback() {
00759         @Override
00760         public void postStep() {
00761           fixedCapitalStockLastPeriod = fixedCapitalStock;
00762           fixedCapitalStock = calcFixedCapitalStock();
00763           if (neverCalcedFixedCapitalStock == true) {
00764             fixedCapitalStockLastPeriod = fixedCapitalStock;
00765             maxFixedCapitalStock = fixedCapitalStock;
00766             neverCalcedFixedCapitalStock = false;
00767           }
00768           
00769           
00770         maxFixedCapitalStock = ArrayTools.maxArrays(maxFixedCapitalStock,
00771                                                       fixedCapitalStockLastPeriod);
00772                   
00773           
00774           updateTradingStats();
00775         }
00776       }
00777       );
00778 
00779       pStepManager.registerCallback(Foundation.PRODUCTION_STEP,
00780                                     StepManager.Timing.POST,
00781                                     1,
00782                                     new StepCallback() {
00783         @Override
00784         public void postStep() {
00785           overallProduction = 0.d;
00786           averageGrowthRateProduction = 0.d;
00787           for (final Firm lFirm : firmList) {
00788             overallProduction += lFirm.getProducedQuantity();
00789             averageGrowthRateProduction += lFirm.getProducedQuantity()
00790                                             * lFirm.getRateProductionUp();
00791           }
00792           memoryProduction.add(overallProduction);
00793           if (overallProduction > 0.d){
00794             averageGrowthRateProduction /= overallProduction;
00795           }
00796         }
00797       }
00798       );
00799 
00800       pStepManager.registerCallback(Foundation.FIRMS_ADJUST_WORKFORCE_STEP,
00801                                     StepManager.Timing.POST,
00802                                     1,
00803                                     new StepCallback() {
00804         @Override
00805         public void postStep() {
00806           averageWageReference = 0.d;
00807           averageLaborCapacity=0;
00808           averageTargetEmployment = 0.d;
00809           averageEmployment = 0.d;
00810           for (final Firm lFirm : firmList) {
00811             averageTargetEmployment += lFirm.getTargetEmployment();
00812             averageEmployment += lFirm.calcWorkAmount();
00813             averageWageReference += lFirm.getTargetEmployment()* lFirm.getWageReference();
00814           }
00815           assert(averageWageReference>0);
00816           assert( averageTargetEmployment>0);
00817           assert (! Double.isNaN(averageWageReference));
00818           averageWageReference /= averageTargetEmployment;
00819           assert (! Double.isNaN(averageWageReference));
00820           averageTargetEmployment /= getNumFirms();
00821           averageEmployment /= getNumFirms();
00822           averageLaborCapacity= averageEmployment/averageTargetEmployment;
00823         }
00824       }
00825       );
00826 
00827       pStepManager.registerCallback(Foundation.FIRMS_DESIRED_PRODUCTION_UPDATING_STEP,
00828                                     StepManager.Timing.POST,
00829                                     1,
00830                                     new StepCallback() {
00831         @Override
00832         public void postStep() {
00833           calcDesiredProduction();
00834         }
00835       }
00836       );
00837 
00838       pStepManager.registerCallback(Foundation.UPDATE_LABOR_PRODUCTIVITY_STEP,
00839                                     StepManager.Timing.POST,
00840                                     1,
00841                                     new StepCallback() {
00842         @Override
00843         public void postStep() {
00844           memoryLaborProductivityGrowthRate.add(laborProductivityGrowthRate);
00845         }
00846       }
00847       );
00848 
00849       pStepManager.registerCallback(Foundation.GENETIC_EVOLUTION_OF_PRICES_STEP,
00850                                     StepManager.Timing.POST,
00851                                     1,
00852                                     new StepCallback() {
00853         @Override
00854         public void postStep() {
00855           calcPrices();
00856         }
00857       }
00858       );
00859 
00860       pStepManager.registerCallback(Foundation.FIRM_ACCOUNTING_STEP,
00861                                     StepManager.Timing.POST,
00862                                     1,
00863                                     new StepCallback() {
00864         @Override
00865         public void postStep() {
00866           averageProfit = 0.d;
00867           sectorProfitRate = 0.d;
00868           averageDebt = 0.d;
00869           averageCosts = 0.d;
00870           averageBenchmarkCosts = 0.d;
00871           averageRevenue = 0.d;
00872           averageMarkUp = 0.d;
00873           deviationMarkUp=0.d;
00874           int nFirm =0;
00875           for (final Firm lFirm : firmList) {
00876             nFirm++;
00877             averageProfit = ((nFirm-1)*averageProfit +lFirm.getProfit())/nFirm;
00878             averageDebt = ((nFirm-1)*averageDebt +lFirm.getDebt())/nFirm;
00879             averageCosts= ((nFirm-1)*averageCosts +lFirm.getCosts())/nFirm;
00880             averageBenchmarkCosts = ((nFirm-1)*averageBenchmarkCosts +lFirm.getBenchmarkCosts())/nFirm;
00881             averageRevenue =  ((nFirm-1)*averageRevenue + lFirm.getPrice() * lFirm.getSoldQuantity())/nFirm;
00882             double lOldAverageMarkUp = averageMarkUp;
00883             averageMarkUp = ((nFirm-1)*averageMarkUp +lFirm.getMarkUp())/nFirm;
00884             deviationMarkUp=((nFirm-1)*deviationMarkUp+
00885                 (lFirm.getMarkUp()-averageMarkUp)*(lFirm.getMarkUp()-lOldAverageMarkUp))/nFirm;
00886             sectorProfitRate += lFirm.getProfitRate() * lFirm.getProducedQuantity();
00887           }
00888           if (overallProduction > 0.d){
00889             sectorProfitRate /= overallProduction;
00890           }
00891           deviationMarkUp=Math.sqrt(deviationMarkUp);
00892           memoryProfit.add(averageProfit);
00893           memoryProfitRate.add(sectorProfitRate);
00894         }
00895       }
00896       );
00897     }
00898 
00900     private void calcPrices() {
00901       averageSupplyPriceWithoutImport = 0.d;
00902       maxPrice = 0.d;
00903       for (final Firm lFirm : firmList) {
00904         averageSupplyPriceWithoutImport += lFirm.getPrice()*lFirm.getProducedQuantity();
00905         maxPrice = Math.max(maxPrice, lFirm.getPrice());
00906       }
00907       averageSupplyPriceWithoutImport /= getOverallProduction();
00908     }
00909     
00911     private void calcDesiredProduction() {
00912       totalDesiredProduction=0;
00913       averageDesiredProduction = 0.d;
00914       for (final Firm lFirm : firmList) {
00915         totalDesiredProduction += lFirm.getDesiredProduction();
00916       }
00917       averageDesiredProduction = totalDesiredProduction/ getNumFirms();
00918     }
00919     
00921     private double[] calcFixedCapitalStock() {
00922       double[] lFCS = new double[foundation.getNumSectors()];
00923       for (final Firm lFirm : firmList) {
00924         lFCS = ArrayTools.addArrays(lFCS, lFirm.getFixedCapital());
00925       }
00926       return lFCS;
00927     }
00928 
00930     private double[] calcCirculatingCapitalStock() {
00931       double[] lCCS = new double[foundation.getNumSectors()];
00932       for (final Firm lFirm : firmList) {
00933         lCCS = ArrayTools.addArrays(lCCS, lFirm.getCirculatingCapital());
00934       }
00935       return lCCS;
00936     }
00937 
00938     @PostValidateThis
00940     private void updateTradingStats() {
00941       final TradeTrace tradeTrace = foundation.getTradeTrace();
00942       averageTradePriceLastPeriod = averageTradePrice;
00943       averageTradePrice = tradeTrace.getAverageTradePriceSelledInSector(Sector.this);
00944       if (Double.isNaN(averageTradePrice)) {
00945         averageTradePrice = averageTradePriceLastPeriod;
00946       }
00947 
00948       tradeValueLastPeriod = tradeValue;
00949       tradeValue = tradeTrace.getOverallTradeValueSelledInSector(Sector.this);
00950     }
00951     
00952     public double getOverallProduction() {
00953       return overallProduction;
00954     }
00955     
00956     public double getAverageProduction() {
00957       return overallProduction/getNumFirms();
00958     }
00959     
00960     double[] getFixedCapitalStock() {
00961       assert (neverCalcedFixedCapitalStock == false);
00962       return fixedCapitalStock;
00963     }
00964 
00965     double[] getMaxFixedCapitalStock() {
00966       assert (neverCalcedFixedCapitalStock == false);
00967       return maxFixedCapitalStock;
00968     }
00969 
00970     double[] getFixedCapitalStockLastPeriod() {
00971       assert (neverCalcedFixedCapitalStock == false);
00972       return fixedCapitalStockLastPeriod;
00973     }
00974 
00975     double getAverageTradePrice() {
00976       return averageTradePrice;
00977     }
00978 
00979     double getAverageMarkUp() {
00980       return averageMarkUp;
00981     }
00982 
00983     public double getDeviationMarkUp() {
00984       return deviationMarkUp;
00985     }
00986 
00987     double getAverageTradePriceLastPeriod() {
00988       return averageTradePriceLastPeriod;
00989     }
00990 
00991     double getTradeValue() {
00992       return tradeValue;
00993     }
00994 
00995     double getTradeValueLastPeriod() {
00996       return tradeValueLastPeriod;
00997     }
00998 
00999     double getAverageProfit() {
01000       return averageProfit;
01001     }
01002 
01003     double getAverageWageReference() {
01004       return averageWageReference;
01005     }
01006 
01007     public double getAverageLaborCapacity() {
01008       return averageLaborCapacity;
01009     }
01010 
01011     public void setAverageLaborCapacity(double pAverageLaborCapacity) {
01012       averageLaborCapacity = pAverageLaborCapacity;
01013     }
01014 
01015     double getAverageCosts() {
01016       return averageCosts;
01017     }
01018     
01019     double getAverageBenchmarkCosts() {
01020       return averageBenchmarkCosts;
01021     }
01022 
01023     double getAverageDebt() {
01024       return averageDebt;
01025     }
01026 
01027     double getAverageRevenue() {
01028       return averageRevenue;
01029     }
01030 
01031     double getAverageSupplyPriceWithoutImport() {
01032       return averageSupplyPriceWithoutImport;
01033     }
01034 
01035     double getAverageDesiredProduction() {
01036       return averageDesiredProduction;
01037     }
01038 
01039     double getAverageTargetEmployment() {
01040       return averageTargetEmployment;
01041     }
01042 
01043     double getAverageEmployment() {
01044       return averageEmployment;
01045     }
01046 
01047     double getMaxPrice() {
01048       return maxPrice;
01049     }
01050 
01051     double getAverageOverPeriodsProfit() {
01052       return memoryProfit.average();
01053     }
01054 
01055     double getAverageOverPeriodsProfitRate() {
01056       return memoryProfitRate.average();
01057     }
01058 
01059     double getProfitRate() {
01060       return memoryProfitRate.last();
01061     }
01062 
01063     double getTotalGrowthFactorLaborProductivity() {
01064       return memoryLaborProductivityGrowthRate.totalGrowthFactor();
01065     }
01066 
01067     double getAverageOverPeriodsProduction() {
01068       return memoryProduction.average();
01069     }
01070 
01071     double getAggregateCirculatingCapital() {
01072       return ArrayTools.sumDouble(calcCirculatingCapitalStock());
01073     }
01074 
01075     double getAggregateFixedCapital() {
01076       return ArrayTools.sumDouble(fixedCapitalStock);
01077     }
01078 
01079     double getAverageGrowthRateProduction(){
01080       return averageGrowthRateProduction;
01081     }
01082 
01083     public double getTotalDesiredProduction() {
01084       return totalDesiredProduction;
01085     }
01086   } // end of inner class Stats
01087 
01112   class FirmsWithInventory implements Iterable<Firm>, Iterator<Firm> {
01113     private static final int NO_FIRM_SELECTED = -1;
01114 
01126     private Firm[] firms;
01128     private int lastFirmToObserveIndex;
01130     private int lastFirmWithInventoryIndex;
01131 
01137     private int nextSelectedFirm = NO_FIRM_SELECTED;
01138 
01144     public void init(StepManager pStepManager) {
01145         pStepManager.registerCallback(Foundation.EXCHANGE_STEP,
01146                                          StepManager.Timing.PRE,
01147                                          1,
01148                                          new StepManager.Callback() {
01149         @Override
01150         public Object getOwner() {
01151           return FirmsWithInventory.this;
01152         }
01153 
01154         @Override
01155         public void preStep() {
01156           createNewFirmArray();
01157         }
01158       });
01159     }
01160 
01165     public Iterator<Firm> iterator() {
01166       lastFirmToObserveIndex = lastFirmWithInventoryIndex;
01167       nextSelectedFirm = NO_FIRM_SELECTED;
01168       return FirmsWithInventory.this;
01169     }
01170 
01172     public boolean hasNext() {
01173       if (nextSelectedFirm != NO_FIRM_SELECTED) {
01174         // a firm is already selected (hasNext was already called), so we know
01175         // that we have an additional firm.
01176         return true;
01177       }
01178 
01179       while (lastFirmToObserveIndex >= 0) {
01180         nextSelectedFirm = random.nextInt(lastFirmToObserveIndex + 1);
01181         // after a firms has selled all of his stock, he is still in the firms array
01182         // because there is no callback to the iterator. So we must check that
01183         // the selected firm has still something to sell
01184         if (firms[nextSelectedFirm].getInventory() == 0) {
01185           // we overwrite the firm without inventory with the last from the
01186           // "left to observe" part of the array ...
01187           firms[nextSelectedFirm] = firms[lastFirmToObserveIndex];
01188           // ... and overwrite this firm with the last from the "firms that have
01189           // still inventory (as far as we know it)" part of the array ...
01190           firms[lastFirmToObserveIndex] = firms[lastFirmWithInventoryIndex];
01191           // ... and decrement the counters (we have one firm less to observe ...
01192           lastFirmToObserveIndex--;
01193           // ... and one firm less with inventory)
01194           lastFirmWithInventoryIndex--;
01195         } else {
01196           // the randomly selected firm has inventory. So it moves to the
01197           // lastFirmToObserveIndex position of the firms array ...
01198           ArrayTools.swap(firms, nextSelectedFirm, lastFirmToObserveIndex);
01199           // ... we store the array position of the selected firm in nextSelectFirm
01200           // which is used in next() ...
01201           nextSelectedFirm = lastFirmToObserveIndex;
01202           // ... and decrement the lastFirmToObserveIndex so that the firm that
01203           // is selected now will not be selected in this iterator again.
01204           lastFirmToObserveIndex--;
01205           return true;
01206         }
01207       }
01208 
01209       // we have no firms left in our firms array, so we return false
01210       return false;
01211     }
01212 
01214     public Firm next() {
01215       if (nextSelectedFirm == NO_FIRM_SELECTED) {
01216         throw new NoSuchElementException();
01217       } else {
01218         final Firm lNextFirm = firms[nextSelectedFirm];
01219         nextSelectedFirm = NO_FIRM_SELECTED;
01220         return lNextFirm;
01221       }
01222     }
01223 
01225     public void remove() {
01226       throw new UnsupportedOperationException();
01227     }
01228 
01233     protected void createNewFirmArray() {
01234       final List<Firm> lFirmsInSector = getFirmList();
01235       // the maximal length of the array for this period is known
01236       firms = new Firm[lFirmsInSector.size()];
01237       lastFirmWithInventoryIndex = -1;
01238 
01239       for (final Firm lFirm : lFirmsInSector) {
01240         if (lFirm.getInventory() > 0.d) {
01241           firms[++lastFirmWithInventoryIndex] = lFirm;
01242         }
01243       }
01244     }
01245   }
01246 
01247 
01272   class FirmsWithExtraSupply implements Iterable<Firm>, Iterator<Firm> {
01273     private static final int NO_FIRM_SELECTED = -1;
01274 
01286     private Firm[] firms;
01287     private int lastFirmToObserveIndex;
01288     private int lastFirmWithExtraSupplyIndex;
01289 
01295     private int nextSelectedFirm = NO_FIRM_SELECTED;
01296 
01302     public void init(StepManager pStepManager) {
01303         pStepManager.registerCallback(Foundation.EXCHANGE_STEP,
01304                                          StepManager.Timing.PRE,
01305                                          1,
01306                                          new StepManager.Callback() {
01307         @Override
01308         public Object getOwner() {
01309           return FirmsWithExtraSupply.this;
01310         }
01311 
01312         @Override
01313         public void preStep() {
01314           createNewFirmArray();
01315         }
01316       });
01317     }
01318 
01323     public Iterator<Firm> iterator() {
01324       lastFirmToObserveIndex = lastFirmWithExtraSupplyIndex;
01325       nextSelectedFirm = NO_FIRM_SELECTED;
01326       return FirmsWithExtraSupply.this;
01327     }
01328 
01329     public boolean hasNext() {
01330       if (nextSelectedFirm != NO_FIRM_SELECTED) {
01331         // a firm is already selected (hasNext was already called), so we know
01332         // that we have an additional firm.
01333         return true;
01334       }
01335 
01336       while (lastFirmToObserveIndex >= 0) {
01337         nextSelectedFirm = random.nextInt(lastFirmToObserveIndex + 1);
01338         // after a firms has selled all of his stock, he is still in the firms array
01339         // because there is no callback to the iterator. So we must check that
01340         // the selected firm has still something to sell
01341         if (firms[nextSelectedFirm].getExtraSupply() <= 0) {
01342           // we overwrite the firm without extraSupply with the last from the
01343           // "left to observe" part of the array ...
01344           firms[nextSelectedFirm] = firms[lastFirmToObserveIndex];
01345           // ... and overwrite this firm with the last from the "firms that have
01346           // still extraSupply (as far as we know it)" part of the array ...
01347           firms[lastFirmToObserveIndex] = firms[lastFirmWithExtraSupplyIndex];
01348           // ... and decrement the counters (we have one firm less to observe ...
01349           lastFirmToObserveIndex--;
01350           // ... and one firm less with extraSupply)
01351           lastFirmWithExtraSupplyIndex--;
01352         } else {
01353           // the randomly selected firm has extraSupply. So it moves to the
01354           // lastFirmToObserveIndex position of the firms array ...
01355           ArrayTools.swap(firms, nextSelectedFirm, lastFirmToObserveIndex);
01356           // ... we store the array position of the selected firm in nextSelectFirm
01357           // which is used in next() ...
01358           nextSelectedFirm = lastFirmToObserveIndex;
01359           // ... and decrement the lastFirmToObserveIndex so that the firm that
01360           // is selected now will not be selected in this iterator again.
01361           lastFirmToObserveIndex--;
01362           return true;
01363         }
01364       }
01365 
01366       // we have no firms left in our firms array, so we return false
01367       return false;
01368     }
01369 
01370     public Firm next() {
01371       if (nextSelectedFirm == NO_FIRM_SELECTED) {
01372         throw new NoSuchElementException();
01373       } else {
01374         final Firm lNextFirm = firms[nextSelectedFirm];
01375         nextSelectedFirm = NO_FIRM_SELECTED;
01376         return lNextFirm;
01377       }
01378     }
01379 
01380     public void remove() {
01381       throw new UnsupportedOperationException();
01382     }
01383 
01388     protected void createNewFirmArray() {
01389       final List<Firm> lFirmsInSector = getFirmList();
01390       // the maximal length of the array for this period is known
01391       firms = new Firm[lFirmsInSector.size()];
01392       lastFirmWithExtraSupplyIndex = -1;
01393 
01394       for (final Firm lFirm : lFirmsInSector) {
01395         if (lFirm.getExtraSupply() > 0.d) {
01396           firms[++lastFirmWithExtraSupplyIndex] = lFirm;
01397         }
01398       }
01399     }
01400   }
01401 
01402   // because of performance reasons, we use some fixed size arrays
01403   public static final int MAX_FIRMS_PER_SECTOR = 1000;
01404 
01405   private static final int NUM_INIT_INPUT_COEFF_MUTATIONS = 10;
01406 
01407   private final Foundation foundation;
01409   private final Stats stats = new Sector.Stats();
01411   private final Sector.Probe probe = new Sector.Probe();
01413   private final LinkedList<Firm> firmList = new LinkedList<Firm>();
01415   private final FirmsWithInventory firmsWithInventory = new FirmsWithInventory();
01417   private final FirmsWithExtraSupply firmsWithExtraSupply = new FirmsWithExtraSupply();
01419   private final ImportExport importExport;
01421   private final SectorInitValues initValues;
01422 
01427   @Description("Benchmark wage of this Sector.")
01428   @Variability(N_PERIODS)
01429   @Initialization(INDIVIDUAL)
01430   private double benchmarkWage;
01431   
01432   @Description("Risk premium for this Sector.")
01433   @Variability(SIMULATION)
01434   @Initialization(INDIVIDUAL)
01435   private double riskPremium;
01436   
01438   @Description("Aggregate capital stock after firms init.")
01439   @Variability(CONSTANT)
01440   @Initialization(INDIVIDUAL)
01441   private double initAggregateFixedCapitalStock;  
01442 
01444   @Description("Labor productivity of this Sector.")
01445   @Variability(PERIOD)
01446   @Initialization(INDIVIDUAL)
01447   private double laborProductivity;
01448   
01450   @Description("Growth rate of the labor productivity of this sector.")
01451   @Variability(PERIOD)
01452   @Initialization(EQUAL)
01453   private double laborProductivityGrowthRate;
01454 
01459   private final String name;
01460 
01462   private final int arrayIndex;
01463 
01464   private RandomGenerator random;
01465 
01467   private int numFirmsCreatedInSector;
01468 
01470   Sector (Foundation pFoundation, SectorInitValues pSectorInitValues, int pIndex) {
01471     foundation = pFoundation;
01472     arrayIndex = pIndex;
01473 
01474     initValues = pSectorInitValues;
01475 
01476     name = initValues.getNameArray()[pIndex];
01477 
01478     importExport = new ImportExport(pFoundation, pSectorInitValues.importExportInitValues());
01479   }
01480   
01481   //-- methods
01482   
01483   @Override
01484   public String toString() {
01485     return "Sector " + name;
01486   }
01487   
01491   void init() throws ValueValidationException, ParameterParserException {
01492     random = Foundation.getRandomGenerator();
01493     foundation.getProbeManager().addProbe(probe);
01494 
01495     laborProductivity = initValues.getLaborProductivityArray()[arrayIndex];
01496     initAggregateFixedCapitalStock =0;
01497     benchmarkWage = calcInitWage();
01498     riskPremium= initValues.getRiskPremiumArray()[arrayIndex];
01499     if (foundation.isInitEquilibrium()){
01500       setRiskPremium(getBenchmarkMarkUp()-foundation.getFinancial().getInterestRate());
01501     }
01502     
01503     probe.init();
01504 
01505     // generate the Firms
01506     firmList.clear();
01507     firmsWithInventory.init(foundation.getStepManager());
01508     firmsWithExtraSupply.init(foundation.getStepManager());
01509 
01510 
01511     final int lNumFirms = getInitNumFirms();
01512 
01513     // calculate the desired production for the firms in this sector
01514     double[] lDesiredProductionArray;
01515     if (Foundation.getInitValues().isFirmsHaveSameSize()) {
01516       lDesiredProductionArray = ArrayTools.createArray(lNumFirms,
01517                                                        getInitProduction() / lNumFirms);
01518     } else {
01519       lDesiredProductionArray = ArrayTools.randomArrayWithSum(random,
01520                                                               lNumFirms,
01521                                                               getInitProduction());
01522     }
01523     
01524     // create and add the firms
01525     for (int i = 0; i < lNumFirms; i++) {
01526       addFirmAtSectorInit(lDesiredProductionArray[i]);
01527     }
01528     initMutateInputCoefficients();
01529 
01530     // register the capital stocks.
01531     for(final Firm lFirm : firmList){
01532       for (int iSector=0; iSector<foundation.getNumSectors();iSector++ ){
01533         initAggregateFixedCapitalStock +=lFirm.getFixedCapital()[iSector];
01534       }
01535     }
01536     
01537     stats.init(); // must be initialized after firms are added and initialized themselves
01538     importExport.init(this);
01539 
01540     validateInitValues();
01541   }
01542 
01550   @PostValidateThis
01551   void initMutateInputCoefficients() {
01552     final int lNumSectors = foundation.getNumSectors();
01553 
01554     final Map<Firm, ProductionFunction.VariatorResults> lPassVariatorResults = 
01555         new HashMap<Firm, ProductionFunction.VariatorResults>();
01556     Map<Firm, ProductionFunction.VariatorResults> lBestVariatorResults = 
01557         new HashMap<Firm, ProductionFunction.VariatorResults>();
01558 
01559     final DoubleInterval[] lCircInCoeffMut = new DoubleInterval[lNumSectors];
01560     final DoubleInterval[] lFixedInCoeffMut = new DoubleInterval[lNumSectors];
01561     DoubleInterval lLaborInCoeffMut;
01562 
01563     double lMinimalDifference = Double.MAX_VALUE;
01564 
01565     for (int iPass = 0; iPass < NUM_INIT_INPUT_COEFF_MUTATIONS; iPass++) {
01566       // init mutation intervals for the iPass-th pass
01567       lLaborInCoeffMut = new DoubleInterval(-getInitLaborMutationRange(),
01568                                              getInitLaborMutationRange());
01569       
01570       for (int iSector = 0; iSector < lNumSectors; iSector++) {
01571         lCircInCoeffMut[iSector] = new DoubleInterval(-getInitCirculatingMutationRange(),
01572                                                        getInitCirculatingMutationRange());
01573         lFixedInCoeffMut[iSector] = new DoubleInterval(-getInitFixedMutationRange(),
01574                                                         getInitFixedMutationRange());
01575       }
01576 
01577       double lNeededCirculating[] = new double[lNumSectors];
01578       double lNeededFixed[] = new double[lNumSectors];
01579       double lSumProduction = 0.d;
01580 
01581       for (final Firm lFirm : firmList) {
01582         final ProductionFunction.VariatorResults lVariatorResults =
01583           lFirm.getProductionFunction().mutateCoefficients(lCircInCoeffMut,
01584                                                            lFixedInCoeffMut, 
01585                                                            lLaborInCoeffMut, 
01586                                                            foundation.getNumSectors());
01587 
01588         lPassVariatorResults.put(lFirm, lVariatorResults);
01589 
01590         lNeededCirculating = ArrayTools.addArrays(lNeededCirculating,
01591                                     lFirm.invProdFuncCirculating(lFirm.getDesiredProduction(),
01592                                     lVariatorResults.circulatingInputCoefficientsVariation));
01593         lNeededFixed = ArrayTools.addArrays(lNeededFixed,
01594                                     lFirm.invProdFuncFixed(lFirm.getDesiredProduction(),
01595                                       lVariatorResults.fixedInputCoefficientsVariation));
01596         lSumProduction += lFirm.getDesiredProduction();
01597 
01598         for (int iSector = 0; iSector < lNumSectors; iSector++) {
01599           if (lNeededCirculating[iSector] < getInitInputOutputCirculating(iSector) *
01600               lSumProduction / getInitProduction()) {
01601             lCircInCoeffMut[iSector].set(0.d, 
01602                                          initValues.getInitialCirculatingInputCoeffMutation());
01603           } else {
01604             lCircInCoeffMut[iSector].set(-initValues.getInitialCirculatingInputCoeffMutation(),
01605                                          0.d);
01606           }
01607 
01608           if (lNeededFixed[iSector] < 
01609                           getInitCapitalStock(iSector) * lSumProduction / getInitProduction()) {
01610             lFixedInCoeffMut[iSector].set(0.d, initValues.getInitialFixedInputCoeffMutation());
01611           } else {
01612             lFixedInCoeffMut[iSector].set(-initValues.getInitialFixedInputCoeffMutation(), 0.d);
01613           }
01614         }
01615       }
01616 
01617       if (lMinimalDifference > calcDifference(lNeededCirculating, lNeededFixed)) {
01618         lBestVariatorResults = 
01619                     new HashMap<Firm, ProductionFunction.VariatorResults>(lPassVariatorResults);
01620         lMinimalDifference = calcDifference(lNeededCirculating, lNeededFixed);
01621       }
01622     }
01623 
01624     for (final Firm lFirm : lBestVariatorResults.keySet()) {
01625       final ProductionFunction.VariatorResults lResults = lBestVariatorResults.get(lFirm);
01626       lFirm.setCirculatingInputCoefficients(lResults.circulatingInputCoefficientsVariation);
01627       lFirm.setFixedInputCoefficients(lResults.fixedInputCoefficientsVariation);
01628       lFirm.setLaborInputCoefficient(lResults.laborInputCoefficientVariation);
01629       lFirm.setInitialCirculatingInputCoefficients(
01630                            ArrayTools.deepCopy(lResults.circulatingInputCoefficientsVariation));
01631       lFirm.setInitialFixedInputCoefficients(
01632                            ArrayTools.deepCopy(lResults.fixedInputCoefficientsVariation));
01633       lFirm.setInitialLaborInputCoefficient(lResults.laborInputCoefficientVariation);
01634 
01635       double lUnitCost =0.0;    
01636       lUnitCost +=lFirm.getLaborInputCoefficient()*calcInitWage();
01637       for (final Sector lSector : foundation.getSectorList()) {
01638         final int lSectorIndex = lSector.getArrayIndex();
01639         lUnitCost += lFirm.getCirculatingInputCoefficients()[lSectorIndex];
01640         lUnitCost += lFirm.getFixedInputCoefficients()[lSectorIndex] * 
01641                                               getInitFixedCapitalDepreciationRate(lSectorIndex);
01642       }
01643       assert (1/lUnitCost-1 >0): "the initial mark-up is negative";
01644       lFirm.setMarkUp(1/lUnitCost-1);
01645       lFirm.setPrice(lUnitCost*(1+lFirm.getMarkUp()));
01646       assert (lFirm.getPrice()>0);
01647     }
01648   }
01649 
01654   private double calcDifference(double[] pNeededCirculating, double[] pNeededFixed) {
01655     double lDifference = 0.d;
01656 
01657     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01658       lDifference += Math.abs(pNeededCirculating[iSector] - getInitInputOutputCirculating(iSector));
01659       lDifference += Math.abs(pNeededFixed[iSector] - getInitCapitalStock(iSector));
01660     }
01661 
01662     return lDifference;
01663   }
01664 
01665   private void validateInitValues() throws ValueValidationException {
01666     double lGoodCosts = 0.d;
01667     for (int iRow = 0; iRow < foundation.getNumSectors(); iRow++) {
01668       lGoodCosts += initValues.getInputOutputCirculatingMatrix()[iRow][arrayIndex];
01669       lGoodCosts += initValues.getInputOutputFixedMatrix()[iRow][arrayIndex];
01670     }
01671     final double lWages = calcInitWage() *
01672         invProdFuncLabor(1.0, initValues.getProductionArray()[arrayIndex]);
01673 
01674     final double lRevenue = initValues.getProductionArray()[arrayIndex];
01675 
01676     if (lGoodCosts + lWages > lRevenue) {
01677       foundation.addToInitializationWarning("The sector " + name +
01678                                          " has an initial negativ profit.\n" +
01679                                          "GoodCosts: " + lGoodCosts + "; Wages: " + lWages +
01680                                          "; Revenue: " + lRevenue);
01681     }
01682   }
01683 
01693   Firm addFirmAtSectorInit(double pDesiredProduction) throws ParameterParserException {
01694     return addFirm(Firm.ADDED_WHILE_INITIALIZE, pDesiredProduction);
01695   }
01696 
01699   void firmsCopyTechnologies() {
01700     // The number of copying Firms and the size of the sample of observations are computed
01701     long lNumCopyFirms = Math.round(getNumFirms() * initValues.getFirmReplacementRate());
01702     if ((lNumCopyFirms == 0) && (getNumFirms() > 1)) {
01703       lNumCopyFirms = 1;
01704     }
01705     long lNumObservedFirms = Math.round(getNumFirms() * initValues.getFirmSamplingRate());
01706     if ((lNumObservedFirms == 0) && (getNumFirms() > 1)) {
01707       lNumObservedFirms = 1;
01708     }
01709           
01710     assert (lNumObservedFirms <= getNumFirms()): "firmObservationRate is too high";
01711     assert (lNumCopyFirms <= getNumFirms()): "firmReplacementRate is too high";
01712     assert (getNumFirms() > 0): "there must be one firm in each sector";
01713         
01714     // We create the list of copying firms    
01715     List<Firm> lCopyingFirms = ListTools.sample(firmList, lNumCopyFirms, random);
01716     
01717     // Each copying firm observes a sample of firms 
01718     final Iterator<Firm> iterFirms = lCopyingFirms.iterator();
01719     for (int iFirm = 0; iFirm < lNumCopyFirms; iFirm++) {
01720       final Firm lFirm = iterFirms.next(); // we don't need to check hasNext
01721       LinkedList<Firm> lObservedFirms = ListTools.sample(firmList, lNumObservedFirms, random);
01722       lObservedFirms.add(lFirm);
01723       // We sort the lObservedFirms according to the unit cost of their technology 
01724       Collections.sort(lObservedFirms, new Firm.CostEfficiencyComparator());
01725       // and copy if one of the firm has a better technology
01726       lFirm.copyTechnologiesFrom(lObservedFirms.getLast());
01727     }
01728   }
01729 
01736   void firmsCopyPrices() {
01737     // The number of copying Firms and the size of the sample of observations are computed
01738     long lNumCopyFirms = Math.round(getNumFirms() * initValues.getFirmReplacementRate());
01739     if ((lNumCopyFirms == 0) && (getNumFirms() > 1)) {
01740       lNumCopyFirms = 1;
01741     }
01742     long lNumObservedFirms = Math.round(getNumFirms() * initValues.getFirmSamplingRate());
01743     if ((lNumObservedFirms == 0) && (getNumFirms() > 1)) {
01744       lNumObservedFirms = 1;
01745     }
01746           
01747     assert (lNumObservedFirms <= getNumFirms()): "firmObservationRate is too high";
01748     assert (lNumCopyFirms <= getNumFirms()): "firmReplacementRate is too high";
01749     assert (getNumFirms() > 0): "there must be one firm in each sector";
01750     
01751     // We create the list of copying firms    
01752     List<Firm> lCopyingFirms = ListTools.sample(firmList, lNumCopyFirms, random);
01753     
01754     // Each copying firm observes a sample of firms 
01755     final Iterator<Firm> iterFirms = lCopyingFirms.iterator();
01756     int lPeriods =foundation.getInitValues().getFirmEntryAndExitInterval();
01757     for (int iFirm = 0; iFirm < lNumCopyFirms; iFirm++) {
01758       final Firm lFirm = iterFirms.next(); // we don't need to check hasNext
01759       LinkedList<Firm> lObservedFirms = ListTools.sample(firmList, lNumObservedFirms, random);
01760 
01761       lObservedFirms.add(lFirm);
01762       // We sort the lObservedFirms according to the efficiency of their pricing policy 
01763 //      Collections.sort(lObservedFirms, new Firm.PricingEfficiencyComparator());
01764       Collections.sort(lObservedFirms, new Firm.PricingEfficiencyComparator());
01765 
01766 /*      final int lMemory= foundation.getInitValues().getFirmEntryAndExitInterval();
01767       Collections.sort(lObservedFirms, new Firm.ProfitRateComparator(1));*/
01768       // and copy if one of the firm has a better policy
01769       lFirm.copyPricesFrom(lObservedFirms.getLast());
01770     }       
01771   }
01772   
01780   void firmsCopyWages() {
01781     // The number of copying Firms and the size of the sample of observations are computed
01782     long lNumCopyFirms = Math.round(getNumFirms() * initValues.getFirmReplacementRate());
01783     if ((lNumCopyFirms == 0) && (getNumFirms() > 1)) {
01784       lNumCopyFirms = 1;
01785     }
01786     long lNumObservedFirms = Math.round(getNumFirms() * initValues.getFirmSamplingRate());
01787     if ((lNumObservedFirms == 0) && (getNumFirms() > 1)) {
01788       lNumObservedFirms = 1;
01789     }
01790           
01791     assert (lNumObservedFirms <= getNumFirms()): "firmObservationRate is too high";
01792     assert (lNumCopyFirms <= getNumFirms()): "firmReplacementRate is too high";
01793     assert (getNumFirms() > 0): "there must be one firm in each sector";
01794     
01795     
01796     // Same operations are executed on a new set of firms for the wageReference
01797         // We create the list of copying firms    
01798     LinkedList<Firm> lCopyingFirmsBis = ListTools.sample(firmList, lNumCopyFirms, random);
01799         
01800     // Each copying firm observes a sample of firms 
01801     final Iterator<Firm> iterFirmsBis = lCopyingFirmsBis.iterator();
01802     for (int iFirm = 0; iFirm < lNumCopyFirms; iFirm++) {
01803       final Firm lFirm = iterFirmsBis.next(); // we don't need to check hasNext
01804       LinkedList<Firm> lObservedFirms = ListTools.sample(firmList, lNumObservedFirms, random);
01805 
01806       lObservedFirms.add(lFirm);
01807       // We sort the lObservedFirms according to the efficiency of their wage policy      
01808       Collections.sort(lObservedFirms, new Firm.RecruitmentEfficiencyComparator());
01809       // and copy if one of the firm has a better policy
01810       lFirm.copyWagesFrom(lObservedFirms.getLast());
01811     }   
01812   }
01813 
01822   void createNextFirmGeneration() {
01823     final long lNumFirms = getNumFirms() ;
01824     final double lProfRate = stats.getAverageOverPeriodsProfitRate();
01825     final double lInterestRate = foundation.getFinancial().getInterestRate();
01826     int lPeriods =foundation.getInitValues().getFirmEntryAndExitInterval();
01827     if (lProfRate < lInterestRate+riskPremium) {
01828       // When the average profit rate is below the interest rate, given the mark-up behavior 
01829       // one can assume that there is over production. The less profitable firms are deleted.
01830       final double lLastSold = 
01831                       foundation.getTradeTrace().getOverallQuantitySelledInSector(Sector.this);
01832       double lProductionTarget = stats.getOverallProduction();
01833       double lMaxNumDestructed = Math.floor(lNumFirms*initValues.getFirmDestructionRate());
01834       int lDestructed = 0;
01835       while (lProductionTarget > lLastSold && lDestructed++ <= lMaxNumDestructed){
01836           // We sort the firmList from lowest to highest profit rate...
01837           Collections.sort(firmList, new Firm.ProfitRateComparator(lPeriods));
01838           // ... aso that the Firm with the lowest profit is the first one
01839           lProductionTarget -= firmList.getFirst().getProducedQuantity();
01840           dropFirm(firmList.getFirst());
01841       }
01842     } else if (lNumFirms<MAX_FIRMS_PER_SECTOR && lProfRate> lInterestRate +riskPremium) {
01843       
01844       // Firms are created proportionally to the difference between profit and interest rates.
01845       final double lCreationRate =Math.min(initValues.getFirmCreationRate(), 
01846                                            lProfRate - lInterestRate);
01847       final long lNumFirmsToCreate = (long) Math.min(MAX_FIRMS_PER_SECTOR-1-lNumFirms,
01848                                                      Math.ceil(lNumFirms*lCreationRate));
01849 
01850       for (int iFirm = 0; iFirm < lNumFirmsToCreate; iFirm++) {
01851         try {
01852           addFirm(Firm.ADDED_WHILE_RUNNING, 
01853                   Math.min(stats.getAverageDesiredProduction(),
01854                            lCreationRate * stats.getAverageOverPeriodsProduction()));
01855         } catch (final ParameterParserException e) {
01856           e.printStackTrace();
01857         }
01858       }
01859       
01860       assert (getNumFirms() > 0): "there must be one firm in each sector";
01861     }
01862 
01863     // In every case, firms whose profit Rate is less than the interest Rate are bankrupted, 
01864     // have their debt cancelled and start anew with optimal characteristics
01865 
01866 
01867     for (final Firm lFirm : firmList) {
01868       if (lFirm.getProfitRate() <= foundation.getFinancial().getInterestRate() &&
01869           lFirm.getPeriodCreated() < foundation.getPeriod()) { 
01870         lFirm.bankrupt();
01871         setBehavioralCharacteristics(lFirm);
01872         final Household lHousehold = foundation.getHouseholds().getRandomHousehold();
01873         lHousehold.addFirmToProperty(lFirm);
01874       }
01875     }
01876   }
01877 
01895   private Firm addFirm(int pPhase, double pDesiredProduction) throws ParameterParserException {
01896     final Firm lFirm = new Firm(foundation, initValues.firmInitValues(), this,
01897         numFirmsCreatedInSector++);
01898 
01899     firmList.add(lFirm);
01900     assert(firmList.size() < MAX_FIRMS_PER_SECTOR);
01901 
01902     // determine the ID of the firm
01903     final int lID = numFirmsCreatedInSector * foundation.getNumSectors() + arrayIndex;
01904     lFirm.init(lID, pPhase, pDesiredProduction);
01905 
01906     // determine a random household which owns the firm
01907     if (pPhase == Firm.ADDED_WHILE_INITIALIZE) {
01908       final Household lHousehold = foundation.getHouseholds().getRandomHousehold();
01909       lHousehold.addFirmToProperty(lFirm);
01910     } else {
01911       // find owner
01912       final LinkedList<Household> lHouseholdList = 
01913                                               foundation.getHouseholds().getCopyAsLinkedList();
01914       Collections.sort(lHouseholdList, new Household.SavingsComparator());
01915       final Household lHousehold = lHouseholdList.getLast();
01916       lHousehold.addFirmToProperty(lFirm);
01917       setBehavioralCharacteristics(lFirm);
01918       
01919       
01920       lFirm.setDebt(0);
01921       lFirm.setWage(lFirm.getWageReference() *getBenchmarkWage());
01922       lFirm.setPrice(Math.min((1+lFirm.getMarkUp())*lFirm.getUnitCost(),stats.getAverageSupplyPriceWithoutImport()));
01923       lFirm.setInventory(0);
01924       // initialize the capital stocks
01925       for  (int iSector=0 ;iSector<foundation.getNumSectors();iSector++) {
01926         lFirm.setFixedCapital(iSector,0);
01927         lFirm.setCirculatingCapital(iSector,0);
01928         lFirm.setIsInvest(iSector,true);
01929       }
01930 
01931       lHousehold.transferSavingsToFirmAndSetProduction(lFirm);
01932       assert lFirm.getWageReference()>0;
01933     }
01934     lFirm.adjustEmployees();
01935     
01936     return lFirm;
01937   }
01938 
01944   void dropUnproductiveFirms() {
01945     final LinkedList<Firm> lListOfFirmsToDelete = new LinkedList<Firm>();
01946 
01947     for (final Firm lFirm : firmList) {
01948       if (lFirm.isUnproductive()){
01949         assert(FloatMath.approxZero(lFirm.getProducedQuantity()));
01950         lListOfFirmsToDelete.add(lFirm);
01951       }
01952     }
01953 
01954     for (final Firm lFirm : lListOfFirmsToDelete) {
01955       dropFirm(lFirm);
01956     }
01957   }
01958 
01967   private boolean dropFirm(Firm pFirm) {
01968     if (firmList.size() <= initValues.getNumFirmMin()) {
01969       return false;
01970     }
01971 
01972     if (pFirm.calcWorkAmount() > 0) {
01973       pFirm.layoffWorkers(pFirm.calcWorkAmount());
01974     }
01975     pFirm.bankrupt();
01976     firmList.remove(pFirm);
01977     pFirm.deInit();
01978     return true;
01979   }
01980   
01981   void setBehavioralCharacteristics(Firm lFirm){
01982     // determine price characteristics
01983     Collections.sort(firmList, new Firm.PricingEfficiencyComparator());
01984     // if the new firm is the best firm, use the characteristics of the second best
01985     final Firm lPriceEfficientFirm = firmList.getLast().equals(lFirm) ?  
01986                                          firmList.get(firmList.size()-1) : firmList.getLast();    
01987   // determine wage characteristics
01988     Collections.sort(firmList, new Firm.RecruitmentEfficiencyComparator());
01989     // if the new firm is the best firm, use the characteristics of the second best
01990     final Firm lWageFirm = firmList.getLast().equals(lFirm) ?  
01991                                          firmList.get(firmList.size()-2) : firmList.getLast();
01992     // determine technology characteristics
01993     Collections.sort(firmList, new Firm.CostEfficiencyComparator());
01994     // if the new firm is the best firm, use the characteristics of the second best
01995     final Firm lCostEfficientFirm = firmList.getLast().equals(lFirm) ?  
01996                                          firmList.get(firmList.size()-2) : firmList.getLast();
01997 
01998                                            
01999                                          
02000     assert (lWageFirm.getWageReference() >0);
02001     lFirm.copyTechnologiesFrom(lCostEfficientFirm);
02002     lFirm.copyWagesFrom(lWageFirm);
02003     lFirm.copyPricesFrom(lPriceEfficientFirm);
02004     lFirm.setMarkUp(foundation.getFinancial().getInterestRate()+riskPremium);
02005             
02006   }
02007 
02019   @GreaterOrApproxZero
02020   public double invProdFuncLabor(double e, @GreaterOrApproxZero double q)
02021   {
02022     final double nWorkers= getInitNumberWorkers();
02023 
02024     return q *nWorkers / (getInitProduction()*getLaborProductivity() * e);
02025   }
02026 
02028   void updateLaborProductivity() {
02029     
02030     double lOldLaborProductivity =laborProductivity;
02031     
02032     if (getInitAggregateCapitalStock()> 0) {
02033       laborProductivity= Math.max(laborProductivity,
02034                      (stats.getAggregateFixedCapital()/getInitAggregateFixedCapitalStock()));
02035     }
02036 
02037     laborProductivityGrowthRate = laborProductivity/lOldLaborProductivity -1;
02038   }
02039   
02040   
02041 /*  
02042   void updateLaborProductivity() {
02043     if (ArrayTools.sumDouble(stats.getFixedCapitalStock()) == 0) {
02044       laborProductivityGrowthRate = 0.d;
02045       return;
02046     }
02047     final double[] lPrice = foundation.generatePriceVector();
02048 
02049     if (ArrayTools.scalarArrays(lPrice, stats.getMaxFixedCapitalStock()) > 0) {
02050       laborProductivityGrowthRate = Math.max(0.d,
02051                      (ArrayTools.scalarArrays(lPrice, stats.getFixedCapitalStock()) /
02052                       ArrayTools.scalarArrays(lPrice, stats.getMaxFixedCapitalStock())) - 1.d);
02053     } else {
02054       laborProductivityGrowthRate = 0.d;
02055     }
02056 
02057     laborProductivity *= 1 + laborProductivityGrowthRate;
02058   }*/
02059 
02060 
02062   void updateBenchmarkWage() {
02063     benchmarkWage *= stats.getTotalGrowthFactorLaborProductivity();
02064     if (foundation.isWagesIndexed()){
02065       benchmarkWage *=(1+Math.max(0,foundation.getFinancial().getInflationRate()));
02066     }
02067   }
02068 
02073   @Post(expr = "_returns >= 0 && de.pik.lagom.toolbox.math.FloatMath." +
02074       "lowerOrApproxEqual(_returns, foundation.getNumHouseholdsTotal())",
02075       lang = "groovy")
02076   double calcWorkAmount() {
02077     double lSumWorkAmount = 0;
02078     for (final Firm lFirm : firmList) {
02079       lSumWorkAmount += lFirm.calcWorkAmount();
02080     }
02081     return lSumWorkAmount;
02082   }
02083 
02084   double calcCiCoef(double pYear) {
02085      return initValues.getCiCoefMaxArray()[arrayIndex] -
02086      (initValues.getCiCoefMaxArray()[arrayIndex] - initValues.getCiCoefMinArray()[arrayIndex])
02087          / (1 + Math.exp(-initValues.getCiCoefSlopeArray()[arrayIndex] *
02088                          (pYear - initValues.getCiCoefTurningYearArray()[arrayIndex])));
02089   }
02090 
02091   public void setLaborProductivity(double pLaborProductivity) {
02092     laborProductivity = pLaborProductivity;
02093   } 
02094   
02096   int getInitNumFirms(){
02097     if (Foundation.getInitValues().isSectorsHaveSameNumberOfFirms()) {
02098       return Foundation.getInitValues().getNumFirms() / foundation.getNumSectors();
02099     } else {
02100       return (int) Math.round(Math.max(initValues.getNumFirmMin(),
02101                                           Foundation.getInitValues().getNumFirms() *
02102                                           getInitProduction() /
02103                                           foundation.getInitOverallProduction()));
02104     }
02105   } 
02106   
02107   //---- getter functions
02108   public Sector.Probe getProbe() {
02109     return probe;
02110   }
02111 
02112   LinkedList<Firm> getFirmList() {
02113     return firmList;
02114   }
02115 
02116   int getNumFirms() {
02117     return firmList.size();
02118   }
02119 
02120   Stats getStats() {
02121     return stats;
02122   }
02123 
02124   int getArrayIndex() {
02125     return arrayIndex;
02126   }
02127 
02128   String getName() {
02129     return name;
02130   }
02131 
02132   double getBenchmarkWage() {
02133     return benchmarkWage;
02134   }
02135 
02136   double getLaborProductivity() {
02137     return laborProductivity;
02138   }
02139 
02140   double getLaborProductivityGrowthRate() {
02141     return laborProductivityGrowthRate;
02142   }
02143   
02144   double getOverallProduction() {
02145     return probe.getProductionUnits();
02146   }
02147 
02148   //---- InitValues access
02149   double getInitInventoryDepreciationRate() {
02150     return initValues.getInventoryDepreciationRateArray()[arrayIndex];
02151   }
02152 
02153   double getInitConsumption() {
02154     return initValues.getConsumptionArray()[arrayIndex];
02155   }
02156 
02157   double getInitWages() {
02158     return initValues.getWagesArray()[arrayIndex];
02159   }
02160   double getInitCalibrationNumWorkers() {
02161     return initValues.getCalibrationNumWorkersArray()[arrayIndex];
02162   }
02163 
02164   double getInitCalibrationTotalNumWorkers() {
02165     // todo: performance improvement: calculate this value only once (in initValues itself)
02166     return ArrayTools.sumDouble(initValues.getCalibrationNumWorkersArray());
02167   }
02168 
02169   double getInitLaborMutationRange(){
02170     return initValues.getInitialLaborCoeffMutation();
02171   }
02172 
02173   double getInitCirculatingMutationRange(){
02174     return initValues.getInitialCirculatingInputCoeffMutation();
02175   }
02176 
02177   double getInitFixedMutationRange(){
02178     return initValues.getInitialFixedInputCoeffMutation();
02179   }
02180 
02187   double getInitInputOutputCirculating(int pIndex) {
02188     return initValues.getInputOutputCirculatingMatrix()[pIndex][arrayIndex];
02189   }
02190 
02197   double getInitInputOutputFixed(int pIndex) {
02198     return initValues.getInputOutputFixedMatrix()[pIndex][arrayIndex];
02199   }
02200 
02201   double getInitProduction() {
02202     return initValues.getProductionArray()[arrayIndex];
02203   }
02204 
02208   double getInitProductionElasticity() {
02209     return initValues.getProductionElasticity();
02210   }
02211 
02222   double getInitCapitalStock(int pIndex) {
02223     return initValues.getCapitalStockMatrix()[pIndex][arrayIndex];
02224   }
02225   
02226   
02230   double getInitAggregateCapitalStock(){
02231     double lSum=0;
02232     for (int iSector=0; iSector < foundation.getNumSectors(); iSector++){
02233       lSum+= initValues.getCapitalStockMatrix()[iSector][arrayIndex];
02234     }
02235     return lSum;
02236   }
02237 
02245   double getInitCapitalStockShare() {
02246     double lTotalValueFixedCapital=0;
02247     double lSectorValueFixedCapital=0;
02248     for(int iSector=0; iSector <foundation.getNumSectors();iSector++){
02249       lSectorValueFixedCapital+=initValues.getCapitalStockMatrix()[iSector][arrayIndex];
02250       for(int jSector=0; jSector <foundation.getNumSectors();jSector++){
02251         lTotalValueFixedCapital+=initValues.getCapitalStockMatrix()[iSector][jSector];
02252       }
02253     }
02254     if(lTotalValueFixedCapital>0){
02255     return lSectorValueFixedCapital/lTotalValueFixedCapital;
02256     }
02257     else{
02258       return (1/foundation.getNumSectors());
02259     }     
02260   }
02261 
02274   @GreaterOrApproxZero
02275   @Post(expr = "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual(_returns, 1)",
02276         lang = "groovy")
02277   public double getInitFixedCapitalDepreciationRate(int pIndex) {
02278     // todo: optimize (is a constant value)
02279     if (getInitCapitalStock(pIndex) > 0) {
02280       double lInv= getInitGrossInvestmentRate(pIndex);
02281       double lGrowth=getInitGrowthRate();
02282       assert (lInv>=lGrowth); 
02283       
02284       return  (lInv-lGrowth)/(1+lGrowth);     
02285     } else {
02286       return 1;
02287     }
02288   }
02289   
02290   // TODO Possibly initialize exogenously  InitGrowthRate
02291   double getInitGrowthRate(){
02292         return initValues.getGrowthRateArray()[arrayIndex];
02293   }
02294   
02295   double getInitGrossInvestmentRate(int lSectorIndex){
02296     double lRate = 0;
02297     if (getInitCapitalStock(lSectorIndex) > 0) {
02298       lRate = getInitInputOutputFixed(lSectorIndex) / getInitCapitalStock(lSectorIndex);
02299 
02300       assert (lRate<1);
02301     }
02302 
02303     return lRate;
02304   }
02305 
02306   
02307 
02308 
02309   
02387   double getInitCapacityUtilizationRate(){
02388   
02389   return initValues.getCapacityUtilizationRate();
02390   }
02391   
02392   
02393   double getCapitalReserveRate(int lSectorIndex){
02394     if (getInitCapitalStock(lSectorIndex) > 0){
02395       double lC =getInitCapacityUtilizationRate();
02396       final double lG= getInitGrowthRate();
02397       final double lD =getInitFixedCapitalDepreciationRate(lSectorIndex);
02398       assert(FloatMath.lowerOrApproxEqual(lC,(1-lD)/((1+lG)*(1+2*lG)))):"too high initial capacity";
02399       double lMin = ((1+lG)*(1+2*lG))/(1-lD)-1;
02400       double lMax =1.0;
02401       int nIter=0;
02402       double lTest;
02403       double lValue;
02404       do{
02405         lTest= (lMin+lMax)/2;
02406         double lJTest = getInvestmentPeriodicity(lSectorIndex,lTest);
02407         lValue= lC*(1+2*lG)*(lG+lD)*(1+lTest)*lJTest -lTest*(1+lG) -2*lG*(1+lG);
02408         if (lValue<0){
02409           lMin= lTest;        
02410         }
02411         else{
02412           lMax =lTest;
02413         }
02414         nIter+=1;
02415       } while (!FloatMath.approxZero(lValue,Math.pow(10, -6)) && nIter<100);
02416       //assert(nIter<99):"check investment data";
02417 
02418       return lTest;}
02419     else{
02420       return 0;
02421     }   
02422     
02423   }
02424   
02425   double getAverageCapitalReserveRate(){
02426     double lRate=0;
02427     int nSectors =0;    
02428     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
02429       if  (getInitInputOutputFixed(iSector) >0){
02430         lRate+=getCapitalReserveRate(iSector) ;
02431         nSectors+=1;      
02432       }
02433     } 
02434     return (nSectors>0)? lRate/nSectors:0; 
02435   }
02436   
02437   
02438   double getInvestmentPeriodicity (int lSectorIndex, double pReserveRate){
02439     final double lGrowthRate = getInitGrowthRate();
02440     final double lDepRate =getInitFixedCapitalDepreciationRate(lSectorIndex);
02441     final double lPeriodicity=Math.log((1+pReserveRate)/(1+2*lGrowthRate))/
02442                              (Math.log(1+lGrowthRate)-Math.log(1-lDepRate));
02443 
02444     assert(lPeriodicity>=1);
02445     return lPeriodicity;
02446   } 
02447   
02448   double getInvestmentPeriodicity (int lSectorIndex){
02449     final double lGrowthRate = getInitGrowthRate();
02450     final double lDepRate =getInitFixedCapitalDepreciationRate(lSectorIndex);
02451     final double lReserveRate =getCapitalReserveRate(lSectorIndex);
02452     final double lPeriodicity=Math.log((1+lReserveRate)/(1+2*lGrowthRate))/
02453                              (Math.log(1+lGrowthRate)-Math.log(1-lDepRate));
02454 //    assert(FloatMath.greaterOrApproxEqual(lPeriodicity,1.0)):"too low initial capacity";
02455     return lPeriodicity;
02456   }
02457     
02458   
02468 /*  double getInitCapacityUtilizationRate(int lSectorIndex){
02469     double lReserveRate =getCapitalReserveRate();
02470     double lPeriodicity = getInvestmentPeriodicity (lSectorIndex);
02471     //assert(lPeriodicity >=1): "growth rate +depreciation rate is too high compared to investment rate";
02472     final double lGrowthRate = getInitGrowthRate();
02473     final double lDepRate =getInitFixedCapitalDepreciationRate(lSectorIndex);
02474     final double lAlpha=(1+lReserveRate)*(1+2*lGrowthRate);
02475     //double lCap =((lDepRate+lGrowthRate)*lPeriodicity)/lReserveRate *(1-lDepRate);
02476     double lCap =(lAlpha-1)*(1+lGrowthRate)/
02477     (lAlpha*(lGrowthRate+lDepRate)*lPeriodicity);
02478     
02479     //final double lFactor = (1+lGrowthRate)*(1+lDepRate);
02480     //final double lCap= lPeriodicity* (1-lFactor)/(1-Math.pow(lFactor,lPeriodicity));
02481     assert (lCap <=1 && lCap>0 );
02482     return lCap;
02483     
02484   }
02485   
02486   
02487   
02488   
02489   double getInvestmentPeriodicity (int lSectorIndex){
02490     final double lGrowthRate = getInitGrowthRate();
02491     final double lDepRate =getInitFixedCapitalDepreciationRate(lSectorIndex);
02492     final double lReserveRate =getCapitalReserveRate();
02493 //    final double lPeriodicity=Math.log(1+lReserveRate)/(Math.log(1+lGrowthRate)+Math.log(1+lDepRate));
02494     final double lPeriodicity=Math.log((1+lReserveRate)*(1+2*lGrowthRate))/
02495                              (Math.log(1+lGrowthRate)-Math.log(1-lDepRate));
02496     assert(lPeriodicity>=0);
02497     final double lAlpha=(1+lReserveRate)*(1+2*lGrowthRate);
02498     double lTest= (lGrowthRate+lDepRate)/(1-lDepRate);
02499     double lTest2=getInitGrossInvestmentRate(lSectorIndex);
02500     //assert (FloatMath.approxEqual(lTest,lTest2));
02501 
02502     assert(lPeriodicity>1);
02503     return lPeriodicity;
02504   }
02505     */
02506 
02507   
02514   // TODO: cache value
02515 
02516   public double getInitNumberWorkers(){
02517     final double lUnemploymentRate = Foundation.getInitValues().governmentInitValues().
02518     getInitUnemploymentRate();
02519 
02520     final double lRealWorldWorkersRatioInSector =
02521       initValues.getCalibrationNumWorkersArray()[arrayIndex]
02522                                                  / ArrayTools.sumDouble(initValues.getCalibrationNumWorkersArray());
02523     final double lModelWorkersInSector = (1 - lUnemploymentRate)* foundation.getNumHouseholdsTotal()
02524                                           * lRealWorldWorkersRatioInSector;
02525 
02526     return  lModelWorkersInSector;
02527     
02528   }
02529   
02530   public double calcInitWage() {
02531     return initValues.getWagesArray()[arrayIndex] / getInitNumberWorkers();
02532   }
02533 
02534 
02535   
02536 
02537   public double getInitUnitInPetaJoule() {
02538     return initValues.getUnitInPetaJouleArray()[arrayIndex];
02539   }
02540 
02541   @NotNull
02542   public ImportExport getImportExport() {
02543     return importExport;
02544   }
02545 
02546   public FirmsWithInventory getFirmsWithInventory() {
02547     return firmsWithInventory;
02548   }
02549   
02550   public FirmsWithExtraSupply getFirmsWithExtraSupply() {
02551     return firmsWithExtraSupply;
02552   }
02553 
02554   public double getRiskPremium() {
02555     return riskPremium;
02556   }
02557 
02558   public void setRiskPremium(double pRiskPremium) {
02559     riskPremium = pRiskPremium;
02560   }
02561   
02562   public double getBenchmarkLaborInputCoefficient(){
02563     return  (getInitNumberWorkers()/ ((1 + getInitGrowthRate())*getInitProduction()));
02564   }
02565   
02566   
02567   public double getBenchmarkCirculatingInputCoefficient (int iSector){
02568     if (getInitInputOutputCirculating(iSector) >0){
02569       return (getInitInputOutputCirculating(iSector) / ((1 + getInitGrowthRate()) * getInitProduction()));
02570       }
02571     else
02572       return 0;
02573     
02574   }
02575 
02576   public double getBenchmarkFixedInputCoefficient (int iSector){
02577     if (getInitCapitalStock(iSector) >0){
02578       return (getInitCapitalStock(iSector) / ((1 + getInitGrowthRate()) * getInitProduction()));
02579       }
02580     else
02581       return 0;
02582     
02583   }
02584   
02585   public double getBenchmarkCost(){
02586     double lCost=getBenchmarkLaborInputCoefficient()*calcInitWage();
02587     for (final Sector lSector : foundation.getSectorList()) {
02588       int iSector=lSector.getArrayIndex();
02589       lCost+=getBenchmarkFixedInputCoefficient(iSector)*getInitFixedCapitalDepreciationRate(iSector)
02590       +getBenchmarkCirculatingInputCoefficient(iSector);
02591     }
02592     return lCost;
02593     
02594   }
02595   
02596   public double getBenchmarkMarkUp(){
02597     double lCost=getBenchmarkCost();
02598     return (1/lCost-1);
02599     
02600   }
02601 
02602   public double getInitAggregateFixedCapitalStock() {
02603     return initAggregateFixedCapitalStock;
02604   }
02605 
02606   public void setInitAggregateFixedCapitalStock(double pInitAggregateFixedCapitalStock) {
02607     initAggregateFixedCapitalStock = pInitAggregateFixedCapitalStock;
02608   }
02609   
02610 
02611 }
02612 
02614 // EOF

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