src/de/pik/lagom/generic/Firm.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 static de.pik.lagom.annotations.Initialization.CLUSTER;
00011 import static de.pik.lagom.annotations.Initialization.EQUAL;
00012 import static de.pik.lagom.annotations.Initialization.INDIVIDUAL;
00013 import static de.pik.lagom.annotations.Origin.TECHNICAL;
00014 import static de.pik.lagom.annotations.Origin.THEORETICAL;
00015 import static de.pik.lagom.annotations.Variability.N_PERIODS;
00016 import static de.pik.lagom.annotations.Variability.PERIOD;
00017 import static de.pik.lagom.annotations.Variability.SIMULATION;
00018 import static de.pik.lagom.annotations.Variability.VOLATILE;
00019 
00020 import java.util.Arrays;
00021 import java.util.Collections;
00022 import java.util.Comparator;
00023 import java.util.Iterator;
00024 import java.util.LinkedHashMap;
00025 import java.util.LinkedList;
00026 import java.util.Map;
00027 
00028 import net.sf.oval.constraint.GreaterOrApproxZero;
00029 import net.sf.oval.constraint.NotNegative;
00030 import net.sf.oval.constraint.NotNull;
00031 import net.sf.oval.constraint.ValidateWithMethod;
00032 import net.sf.oval.guard.Guarded;
00033 import net.sf.oval.guard.Post;
00034 import net.sf.oval.guard.PostValidateThis;
00035 import net.sf.oval.guard.Pre;
00036 import net.sf.oval.guard.PreValidateThis;
00037 import de.pik.lagom.annotations.Description;
00038 import de.pik.lagom.annotations.Initialization;
00039 import de.pik.lagom.annotations.MatrixDescription;
00040 import de.pik.lagom.annotations.NameInUI;
00041 import de.pik.lagom.annotations.Origin;
00042 import de.pik.lagom.annotations.Variability;
00043 import de.pik.lagom.annotations.WriteToFile;
00044 import de.pik.lagom.exceptions.ParameterParserException;
00045 import de.pik.lagom.generic.Household.FallbackComparator;
00046 import de.pik.lagom.generic.Household.InverseFallbackComparator;
00047 import de.pik.lagom.generic.initvalues.FirmInitValues;
00048 import de.pik.lagom.generic.productionfunction.ProductionFunction;
00049 import de.pik.lagom.generic.productionfunction.ProductionFunctionFactory;
00050 import de.pik.lagom.toolbox.ArrayTools;
00051 import de.pik.lagom.toolbox.IIdentifiable;
00052 import de.pik.lagom.toolbox.ProbeBase;
00053 import de.pik.lagom.toolbox.StepManager;
00054 import de.pik.lagom.toolbox.StepManager.Callback;
00055 import de.pik.lagom.toolbox.math.DoubleInterval;
00056 import de.pik.lagom.toolbox.math.FloatMath;
00057 import de.pik.lagom.toolbox.math.RandomGenerator;
00058 import de.pik.lagom.toolbox.math.ValueMemory;
00059 
00061 @Guarded
00062 public class Firm implements IBuyer, ISeller {
00066   static final int ADDED_WHILE_INITIALIZE = 0;
00067 
00071   static final int ADDED_WHILE_RUNNING = 1;
00072 
00074   private static final int MAXPRODUCTION_CAPITAL = 0;
00076   private static final int MAXPRODUCTION_CAPITAL_AND_LABOR = 1;
00078   private static final int MAXPRODUCTION_FIXED_CAPITAL_ONLY = 2;
00079 
00080 
00081   
00082   class Stats {
00083     private ValueMemory profitMemory;
00084     private ValueMemory profitRateMemory;
00085     private ValueMemory costsMemory;
00086     private ValueMemory moneyMemory;
00087     private ValueMemory producedQuantityMemory;
00088     private ValueMemory soldQuantityMemory;
00089     private ValueMemory saleRatioMemory;
00090     private ValueMemory inventoryMemory;
00091     private ValueMemory priceMemory;
00092     final int memoryPeriods=Math.max(Foundation.getInitValues().getGeneticEvolutionPricesInterval(),
00093                                      Foundation.getInitValues().getFirmEntryAndExitInterval());
00094     void init(StepManager pStepManager) {
00095       costsMemory = new ValueMemory(memoryPeriods);
00096       moneyMemory = new ValueMemory(memoryPeriods);
00097       profitMemory = new ValueMemory(memoryPeriods);
00098       profitRateMemory = new ValueMemory(memoryPeriods);
00099       producedQuantityMemory = new ValueMemory(memoryPeriods);
00100       soldQuantityMemory = new ValueMemory(Foundation.getInitValues().getGeneticEvolutionPricesInterval());
00101       saleRatioMemory = new ValueMemory(memoryPeriods);
00102       inventoryMemory = new ValueMemory(memoryPeriods);
00103       priceMemory = new ValueMemory(memoryPeriods);
00104       
00105       pStepManager.registerEndOfPeriodCallback(1, new Callback(){
00106         @Override
00107         public void endOfPeriod() {
00108           costsMemory.add(costs);
00109           moneyMemory.add(money);
00110           profitMemory.add(profit);
00111           profitRateMemory.add(profitRate);
00112           producedQuantityMemory.add(producedQuantity);
00113           soldQuantityMemory.add(soldQuantity);
00114           saleRatioMemory.add(Math.min(1,soldQuantity/producedQuantity));
00115           inventoryMemory.add(inventory);
00116           priceMemory.add(price);
00117         }
00118         @Override
00119         public Object getOwner() {
00120           return Firm.Stats.this;
00121         }}
00122       ); // end of registerEndOfPeriodCallback
00123     }
00124 
00125     public double getAverageProfit(int pNumPeriods) {
00126       return profitMemory.average(pNumPeriods);
00127     }
00128     
00129     public double getPriceMemoryAverage() {
00130       return priceMemory.average(memoryPeriods);
00131     }
00132     
00133     public double getGrowthRateProfit() {
00134       if (profitMemory.first()*profit<=0){
00135         return Math.signum(profit);
00136       }
00137       else{
00138         if (profitMemory.first()>=0){
00139           return profit/profitMemory.first()-1;
00140         }
00141         else{
00142           return profitMemory.first()/profit-1;
00143         }
00144       }
00145     }
00146         
00147     
00148     public double getGrowthRateSales() {
00149       if (soldQuantityMemory.first()==0){
00150         return 0;
00151       }
00152       else{
00153         return soldQuantity/soldQuantityMemory.first()-1;
00154       }
00155     }
00156         
00157     public double getAverageProfitRate(int pNumPeriods) {
00158       return profitRateMemory.average(pNumPeriods);
00159     }
00160 
00161     public double getCostsLastPeriod() {
00162       return costsMemory.last();
00163     }
00164     
00165     public double getMoneyLastPeriod() {
00166       return moneyMemory.last();
00167     }
00168 
00169     public double getAverageProducedQuantity(int pNumPeriods) {
00170       return producedQuantityMemory.average(pNumPeriods);
00171     }
00172 
00173     public double getProducedQuantityLastPeriod() {
00174       return producedQuantityMemory.last();
00175     }
00176 
00177     public double getSoldQuantityLastPeriod() {
00178       return soldQuantityMemory.last();
00179     }
00180 
00181     public double getInventoryLastPeriod() {
00182       return inventoryMemory.last();
00183     }
00184   }
00185 
00186   public class Probe extends ProbeBase implements IIdentifiable {
00187     public class StepCallback extends Callback {
00188       @Override
00189       public Object getOwner() {
00190         return Firm.Probe.this;
00191       }
00192     }
00193 
00195     @Description("The firm is the n-th firm in its sector")
00196     @Variability(SIMULATION)
00197     @Initialization(INDIVIDUAL)
00198     private int indexFirmInSector;
00199 
00200     @Description("A list of supplier probes, one for each sector") 
00201     @Variability(SIMULATION)
00202     @Initialization(INDIVIDUAL)
00203     private Suppliers.Probe[] suppliersProbesArray;
00204 
00205     @Description("The desired production before adjusting the production level")
00206     @Variability(PERIOD)
00207     @Initialization(CLUSTER)
00208     @Origin(THEORETICAL)
00209     private double desiredProductionWhileProducing;
00210 
00211     @Description("The circulating capital after trading but before production")
00212     @Variability(PERIOD)
00213     @Initialization(CLUSTER)
00214     @Origin(THEORETICAL)
00215     private double[] circulatingCapitalBeforeProduction;
00216 
00217     void init() {
00218       suppliersProbesArray = new Suppliers.Probe[suppliers.length];
00219 
00220       for (int iProbe = 0; iProbe < suppliers.length; iProbe++) {
00221         suppliersProbesArray[iProbe] = suppliers[iProbe].getProbe();
00222       }
00223 
00224       registerCallbacks(foundation.getStepManager());
00225 
00226       circulatingCapitalBeforeProduction = new double[foundation.getNumSectors()];
00227     }
00228 
00229     void deInit() {
00230       foundation.getStepManager().unregisterCallbacksOfOwner(Firm.Probe.this);
00231     }
00232 
00233     private void registerCallbacks(StepManager pStepManager) {
00234       pStepManager.registerCallback(Foundation.PRODUCTION_STEP, StepManager.Timing.PRE, 1,
00235           new StepCallback() {
00236         @Override
00237         public void preStep() {
00238           desiredProductionWhileProducing = desiredProduction;
00239           ArrayTools.deepCopyFromTo(circulatingCapital, circulatingCapitalBeforeProduction);
00240         }
00241       }
00242       ); // end of registerCallback
00243     }
00244 
00245     @Override
00246     public String toString() {
00247       return "Firm " + indexFirmInSector + " in Sector " + productionSector.getName();
00248     }
00249 
00250     @Override
00251     public String portrayalName() {
00252       return productionSector.getName();
00253     }
00254 
00255     @Override
00256     public boolean showOnlyPortrayalNameForTheHighestProbe() {
00257       return true;
00258     }
00259 
00260     @NameInUI("Firm produces in Sector")
00261     public String getSectorName() {
00262       return productionSector.toString();
00263     }
00264 
00265     @NameInUI("Suppliers")
00266     public Suppliers.Probe[] getSuppliers() {
00267       return suppliersProbesArray;
00268     }
00269 
00270     @NameInUI("Owner of firm")
00271     public ProbeBase getOwner() {
00272       if (owner != null) {
00273         return owner.getProbe();
00274       } else {
00275         return null;
00276       }
00277     }
00278 
00279     @WriteToFile
00280     @NameInUI("Inventory Before Trade")
00281     @Description("The inventory of the produced good before the trading process")
00282     public double getInventory() {
00283       return inventory;
00284     }
00285 
00286     @WriteToFile
00287     @NameInUI("Inventory After Trade")
00288     @Description("The inventory of the produced good after the trading process")
00289     public double getInventoryAfterTrade() {
00290       return inventoryAfterTrade;
00291     }
00292 
00293     @WriteToFile
00294     @NameInUI("Produced Quantity")
00295     public double getProducedQuantity() {
00296       return producedQuantity;
00297     }
00298 
00299     @WriteToFile
00300     @NameInUI("Sold Quantity")
00301     public double getSoldQuantity() {
00302       return soldQuantity;
00303     }
00304 
00305     @WriteToFile
00306     @NameInUI("Wage")
00307     @Description("The wage paid to workers")
00308     public double getWageForNewOffers() {
00309       return wage;
00310     }
00311 
00312     @WriteToFile
00313     @NameInUI("Labor Input Coefficient")
00314     @Description("The labor Input Coefficient")
00315     public double getLaborInputCoefficient() {
00316       return laborInputCoefficient;
00317     }
00318 
00319 
00320     @WriteToFile
00321     @NameInUI("Wage Reference")
00322     @Description("The share of the benchmark wage used as reference")
00323     public double getWageReference() {
00324       return wageReference;
00325     }
00326 
00327     @WriteToFile
00328     @NameInUI("Average Wage")
00329     @Description("The average wage paid in the actual work contracts")
00330     public double getAverageWage() {
00331       if (workerList.isEmpty()) {
00332         return 0.d;
00333       }
00334 
00335       double lSumWage = 0.d;
00336       double lSumWorkAmount = 0.d;
00337 
00338       for (final WorkContract lWorkContract : workerList.values()) {
00339         lSumWage += lWorkContract.getWageCurrentWorkAmount();
00340         lSumWorkAmount += lWorkContract.getAmount();
00341       }
00342 
00343       return lSumWage / lSumWorkAmount;
00344     }
00345 
00346     @WriteToFile
00347     @NameInUI("Price")
00348     @Description("The demanded price of the produced good")
00349     public double getPrice() {
00350       return price;
00351     }
00352 
00353     @WriteToFile
00354     @NameInUI("Profit")
00355     public double getProfit() {
00356       return profit;
00357     }
00358 
00359     @WriteToFile
00360     @NameInUI("Costs")
00361     public double getCosts() {
00362       return costs;
00363     }
00364 
00365     @WriteToFile
00366     @NameInUI("Debt")
00367     public double getDebt() {
00368       return debt;
00369     }
00370 
00371     @WriteToFile
00372     @NameInUI("Dividend")
00373     @Description("The paid dividend")
00374     public double getDividend() {
00375       return dividend;
00376     }
00377 
00378 
00379     @NameInUI("Created in Period")
00380     public int getPeriodCreated() {
00381       return periodCreated;
00382     }
00383 
00384     @NameInUI("ID")
00385     @Description("The ID is used in the UI to identify the firm")
00386     public int getId() {
00387       return id;
00388     }
00389 
00390     @WriteToFile
00391     @MatrixDescription(rowNames = "sectorNames")
00392     @NameInUI("Fixed Capital")
00393     public double[] getFixedCapital() {
00394       return fixedCapital;
00395     }
00396 
00397     @WriteToFile
00398     @MatrixDescription(rowNames = "sectorNames")
00399     @NameInUI("Circulating Capital Before Production")
00400     @Description("The circulating capital after trading but before production")
00401     public double[] getCirculatingCapitalBeforeProduction() {
00402       return circulatingCapitalBeforeProduction;
00403     }
00404 
00405     @WriteToFile
00406     @MatrixDescription(rowNames = "sectorNames")
00407     @NameInUI("Circulating Capital Remaining")
00408     @Description("The circulating capital after production")
00409     public double[] getCirculatingCapital() {
00410       return circulatingCapital;
00411     }
00412 
00413     @WriteToFile
00414     @MatrixDescription(rowNames = "sectorNames")
00415     @NameInUI("Fixed Input Coefficients")
00416     public double[] getFixedInputCoefficients() {
00417       return fixedInputCoefficients;
00418     }
00419 
00420     @WriteToFile
00421     @MatrixDescription(rowNames = "sectorNames")
00422     @NameInUI("Circulating Input Coefficients")
00423     public double[] getCirculatingInputCoefficients() {
00424       return circulatingInputCoefficients;
00425     }
00426 
00427     @WriteToFile
00428     @NameInUI("Desired Employment")
00429     @Description("The work amount that the firm needs for the desired production")
00430     public double getTargetEmployment() {
00431       return targetEmployment;
00432     }
00433 
00434     @WriteToFile
00435     @NameInUI("Desired Production After Adjusting")
00436     @Description("The desired production after adjusting the production level")
00437     public double getDesiredProduction() {
00438       return desiredProduction;
00439     }
00440 
00441     @WriteToFile
00442     @NameInUI("Desired Production Before Adjusting")
00443     @Description("The desired production before adjusting the production level")
00444     public double getDesiredProductionWhileProducing() {
00445       return desiredProductionWhileProducing;
00446     }
00447 
00448     @WriteToFile
00449     @NameInUI("Money")
00450     @Description("Monetary holdings of the firm")
00451     public double getMoney() {
00452       return money;
00453     }
00454 
00455     @WriteToFile
00456     @NameInUI("Work amount")
00457     @Description("The total work amount of the employed households")
00458     public double getWorkAmount() {
00459       return calcWorkAmount();
00460     }
00461   } // end of class Probe
00462 
00463 
00467   static public class DebtComparator implements Comparator<Firm> {
00468     public int compare(Firm pFirm0, Firm pFirm1) {
00469       // first determine the debt of both firms ...
00470       final double lDebt0 = pFirm0.getDebt();
00471       final double lDebt1 = pFirm1.getDebt();
00472 
00473       // ... then compare it
00474       if (lDebt0 < lDebt1) {
00475         return -1;
00476       } else if (lDebt0 > lDebt1) {
00477         return 1;
00478       } else {
00479         return 0;
00480       }
00481     }
00482   }
00483 
00487   static public class WageReferenceComparator implements Comparator<Firm> {
00488     public int compare(Firm pFirm0, Firm pFirm1) {
00489       // first determine the wage reference of both firms ...
00490       final double lWageReference0 = pFirm0.getWageReference();
00491       final double lWageReference1 = pFirm1.getWageReference();
00492 
00493       // ... then compare it
00494       if (lWageReference0 < lWageReference1) {
00495         return -1;
00496       } else {
00497         return 1;
00498       }
00499     }
00500   }
00501 
00506   static public class RecruitmentEfficiencyComparator implements Comparator<Firm> {
00507     public int compare(Firm pFirm0, Firm pFirm1) {
00508       
00509       final double lEfficiency0 = pFirm0.getLaborCapacity();
00510       final double lEfficiency1 = pFirm1.getLaborCapacity();
00511       final double lWageReference0 = pFirm0.wageReference;
00512       final double lWageReference1 = pFirm1.wageReference;
00513 
00514       if (FloatMath.greaterOrApproxEqual(Math.min(lEfficiency0,lEfficiency1),1)){
00515          return (int) Math.signum(lWageReference1-lWageReference0);
00516         }
00517         else {
00518           return (int) Math.signum(lWageReference0-lWageReference1);
00519         }
00520     }
00521   }
00522   
00526   static public class CostEfficiencyComparator implements Comparator<Firm> {
00527     public int compare(Firm pFirm0, Firm pFirm1) {
00528       // first determine the unit production costs of both firms ...
00529       final double lCost0 = pFirm0.calcUnitProductionCost();
00530       final double lCost1 = pFirm1.calcUnitProductionCost();
00531 
00532       // ... then compare them
00533       if (lCost0 > lCost1) {
00534         return -1;
00535       } else {
00536         return 1;
00537       } 
00538     }
00539   }
00540   
00545   static public class PricingEfficiencyComparator implements Comparator<Firm> {
00546     public int compare(Firm pFirm0, Firm pFirm1) {
00547       // first determine the fitness of both firms ...
00548       final double lNormalizedSalesGrowthRate0 = Math.min(1, pFirm0.stats.getGrowthRateSales());
00549       final double lNormalizedSalesGrowthRate1 = Math.min(1, pFirm1.stats.getGrowthRateSales());    
00550       final double lNormalizedProfitGrowthRate0 = Math.min(1, pFirm0.stats.getGrowthRateProfit());
00551       final double lNormalizedProfitGrowthRate1 = Math.min(1, pFirm1.stats.getGrowthRateProfit());
00552       
00553       final double lFitness0 = 0.5 * (lNormalizedSalesGrowthRate0+lNormalizedProfitGrowthRate0);
00554       final double lFitness1 = 0.5 * (lNormalizedSalesGrowthRate1+lNormalizedProfitGrowthRate1);
00555       
00556       // ... then compare 
00557       if (lFitness0 < lFitness1) {
00558         return -1;
00559       } else {
00560         return 1;
00561       } 
00562     }
00563   } 
00564   
00568   static public class ProfitComparator implements Comparator<Firm> {
00569     public int compare(Firm pFirm0, Firm pFirm1) {
00570       // first determine the profit of both firms ...
00571       final double lProfit0 = pFirm0.getProfit();
00572       final double lProfit1 = pFirm1.getProfit();
00573 
00574       // ... then compare it
00575       if (lProfit0 < lProfit1) {
00576         return -1;
00577       } else if (lProfit0 > lProfit1) {
00578         return 1;
00579       } else {
00580         return 0;
00581       }
00582     }
00583   }
00584 
00588   static public class ProfitRateComparator implements Comparator<Firm> {
00589     private final int numPeriods;
00590     ProfitRateComparator(int pNumPeriods) {
00591       numPeriods = pNumPeriods;
00592     }
00593 
00594     public int compare(Firm pFirm0, Firm pFirm1) {
00595       // first determine the profit and production of both firms ...
00596       final double lProfit0 = pFirm0.stats.getAverageProfit(numPeriods);
00597       final double lProfit1 = pFirm1.stats.getAverageProfit(numPeriods);
00598       final double lProduction0 = pFirm0.stats.getAverageProducedQuantity(numPeriods);
00599       final double lProduction1 = pFirm1.stats.getAverageProducedQuantity(numPeriods);
00600 
00601       if ( (lProduction0 == 0) || (lProduction1 == 0)) {
00602       // in the case that one firm didn't produce anything compare the profits
00603         if (lProfit0 < lProfit1) {
00604           return -1;
00605         } else if (lProfit0 > lProfit1) {
00606           return 1;
00607         } else {
00608           return 0;
00609         }
00610       } else {
00611       // else compare rates of profits
00612         if ((lProfit0 / lProduction0) < (lProfit1 / lProduction1)) {
00613           return -1;
00614         } else if ((lProfit0 / lProduction0) > (lProfit1 / lProduction1)) {
00615           return 1;
00616         } else {
00617           return 0;
00618         }
00619       }
00620     }
00621   }
00622   
00627   static public class MarkUpComparator implements Comparator<Firm> {
00628     public int compare(Firm pFirm0, Firm pFirm1) {
00629       // first determine the unit production costs of both firms ...
00630       final double lMarkUp0 = pFirm0.getMarkUp();
00631       final double lMarkUp1 = pFirm1.getMarkUp();
00632 
00633       // ... then compare them
00634       if (lMarkUp0 > lMarkUp1) {
00635         return -1;
00636       } else {
00637         return 1;
00638       } 
00639     }
00640   }
00641   
00646   static public class InventoryComparator implements Comparator<Firm> {
00647     public int compare(Firm pFirm0, Firm pFirm1) {
00648       // first determine the inventory to production ratios of both firms ...
00649       final double lInventory0 = pFirm0.getInventory()/pFirm0.getProducedQuantity();
00650       final double lInventory1 = pFirm1.getInventory()/pFirm1.getProducedQuantity();
00651 
00652       // ... then compare them
00653       if (lInventory0 < lInventory1) {
00654         return -1;
00655       } else {
00656         return 1;
00657       } 
00658     }
00659   }
00660   
00665   static public class GrowthRateSalesComparator implements Comparator<Firm> {
00666     public int compare(Firm pFirm0, Firm pFirm1) {
00667       // first determine the growth rate of sales of both firms ...
00668       final double lRate0 = pFirm0.stats.getGrowthRateSales();
00669       final double lRate1 =  pFirm1.stats.getGrowthRateSales();
00670       
00671       // ... then compare them
00672       if (lRate0 < lRate1) {
00673         return -1;
00674       } else {
00675         return 1;
00676       } 
00677     }
00678   }
00679   
00680   
00681   
00682   //end of all Comparators 
00683 
00684   @Description("The foundation of the model")
00685   @Variability(SIMULATION)
00686   @Initialization(EQUAL)
00687   private static Foundation foundation;
00688   
00690   @Description("The id of the firm")
00691   @Variability(SIMULATION)
00692   @Initialization(INDIVIDUAL)
00693   private int id; 
00694 
00695   @Description("Statistics of the firm, collected in each period")
00696   @Variability(PERIOD)
00697   @Initialization(INDIVIDUAL)
00698   private final Stats stats = new Stats();
00699 
00700   @Description("Probe of the firm, outputs information to the UI")
00701   @Variability(VOLATILE) 
00702   @Initialization(INDIVIDUAL)
00703   private final Firm.Probe probe = new Firm.Probe();
00704 
00706   @Description("The initialization Values of the Firms")
00707   @Variability(SIMULATION)
00708   @Initialization(EQUAL)
00709   private final FirmInitValues initValues;
00710 
00712   @Description("The Sector in which the firm produces")
00713   @Variability(SIMULATION)
00714   @Initialization(CLUSTER)
00715   @Origin(TECHNICAL)
00716   private final Sector productionSector;
00717 
00719   @Description("The owner of the firm")
00720   @Variability(SIMULATION)
00721   @Initialization(INDIVIDUAL)
00722   @Origin(TECHNICAL)
00723   private Household owner;
00724 
00729   @Description("The list of the Households on the payroll of this firm including their" +
00730       " WorkContract")
00731   @Variability(VOLATILE)
00732   @Initialization(INDIVIDUAL)
00733   @Origin(TECHNICAL)
00734   @ValidateWithMethod(methodName = "isValidWorkerList", parameterType = LinkedHashMap.class)
00735   protected Map<Household, WorkContract > workerList = 
00736                                                 new LinkedHashMap<Household, WorkContract>();
00737 
00738   // A helper function that validates the correctness of the workerList. It is called
00739   // from OVal (due to the @ValidateWithMethod above), so it is used when OVal is active.
00740   @SuppressWarnings("unused")
00741   private boolean isValidWorkerList(LinkedHashMap<Household, WorkContract> pWorkerListToTest) {
00742     // a firm can't employ more households than those that exist in the simulation
00743     if (pWorkerListToTest.size() > foundation.getNumHouseholdsTotal()) {
00744       return false;
00745     }
00746 
00747     for (final Household lHousehold : workerList.keySet()) {
00748       // check that the firm and the household have the same WorkContract
00749       final WorkContract lWorkContract = workerList.get(lHousehold);
00750       lWorkContract.getEmployer().equals(this);
00751       if (!lWorkContract.equals(lHousehold.getWorkContractForFirm(this))) {
00752         return false;
00753       }
00754 
00755       // and check the status of the work contract
00756       if (lWorkContract.getStatus() != WorkContract.Status.ACCEPTED) {
00757         return false;
00758       }
00759     }
00760     return true;
00761   }
00762 
00767   @GreaterOrApproxZero
00768   @Description("The current offered wage of new work contracts")
00769   @Variability(VOLATILE)
00770   @Initialization(CLUSTER)
00771   @Origin(TECHNICAL)
00772   private double wage;
00773 
00775   @GreaterOrApproxZero
00776   @Description("The share of the benchmark wage used as reference")
00777   @Variability(VOLATILE)
00778   @Initialization(EQUAL)
00779   @Origin(TECHNICAL)
00780   private double wageReference;
00781 
00783   @Description("The price currently demanded for the produced good")
00784   @Variability(N_PERIODS) 
00785   @Initialization(CLUSTER) 
00786   @Origin(TECHNICAL)
00787   private double price = 1.d;
00788 
00790   @GreaterOrApproxZero
00791   @Description("The inventory of the produced good")
00792   @Variability(VOLATILE)
00793   @Initialization(CLUSTER)
00794   @Origin(TECHNICAL)
00795   private double inventory;
00796 
00798   @GreaterOrApproxZero
00799   @Description("The inventory of the produced good registered after trading")
00800   @Variability(VOLATILE)
00801   @Initialization(INDIVIDUAL)
00802   @Origin(TECHNICAL)
00803   private double inventoryAfterTrade;
00804 
00806   @GreaterOrApproxZero
00807   @Description("The quantity of good produced during the period")
00808   @Variability(PERIOD)
00809   @Initialization(INDIVIDUAL)
00810   @Origin(TECHNICAL)
00811   private double producedQuantity;
00812 
00814   @GreaterOrApproxZero
00815   @Description("The rate at which the desired production changes")
00816   @Variability(PERIOD)
00817   @Initialization(CLUSTER)
00818   @Origin(TECHNICAL)
00819   private double rateProductionUp;
00820 
00822   @Description("A marker which assesses whether the conditions to invest are satisfied")
00823   @Variability(VOLATILE)
00824   @Initialization(INDIVIDUAL)
00825   private boolean[] isInvest;
00826 
00828   @GreaterOrApproxZero
00829   @Description("The quantity of good sold during the period")
00830   @Variability(PERIOD)
00831   @Initialization(INDIVIDUAL)
00832   @Origin(TECHNICAL)
00833   private double soldQuantity =0.d;
00834 
00836   @Description("The current profit rate")
00837   @Variability(PERIOD)
00838   @Initialization(INDIVIDUAL)
00839   @Origin(TECHNICAL)
00840   private double profitRate = 0.d;
00841 
00843   @Description("The current profit")
00844   @Variability(PERIOD)
00845   @Initialization(INDIVIDUAL)
00846   @Origin(TECHNICAL)
00847   private double profit = 0.d;
00848 
00850   @Description("The current production costs")
00851   @Variability(VOLATILE)
00852   @Initialization(INDIVIDUAL)
00853   @Origin(TECHNICAL)
00854   private double costs = 0.d;
00855 
00857   @Description("The benchmark production costs")
00858   @Variability(VOLATILE)
00859   @Initialization(INDIVIDUAL)
00860   @Origin(TECHNICAL)
00861   private double benchmarkCosts = 0.d;
00862 
00863   
00870   @Description("The current mark-up over costs (the margin above production cost the producer" +
00871                " uses to set its price)")
00872   @Variability(PERIOD)
00873   @Initialization(CLUSTER)
00874   @Origin(TECHNICAL)
00875   private double markUp = 0.15d;
00876 
00878   @Description("The sum of profits since last copy step")
00879   @Variability(PERIOD)
00880   @Initialization(INDIVIDUAL)
00881   @Origin(TECHNICAL)
00882   private double sumProfitsMemory = 0.d;
00883 
00885   @Description("The money holdings of the Firm")
00886   @Variability(VOLATILE)
00887   @Initialization(INDIVIDUAL)
00888   @Origin(TECHNICAL)
00889   private double money = 0.d;
00890   
00892   @Description("The variation of the money holdings of the Firm")
00893   @Variability(PERIOD)
00894   @Initialization(INDIVIDUAL)
00895   private double moneyVariation = 0.d;
00896   
00898   @Description("The value spent on intermediary consumption")
00899   @Variability(PERIOD)
00900   @Initialization(INDIVIDUAL)
00901   @Origin(TECHNICAL)
00902   private double intermediaryConsumptionValue = 0.d;
00903   
00905   @Description("The value of sales")
00906   @Variability(PERIOD)
00907   @Initialization(INDIVIDUAL)
00908   @Origin(TECHNICAL)
00909   private double salesValue = 0.d;
00910   
00912   @Description("The value spent on investment")
00913   @Variability(PERIOD)
00914   @Initialization(INDIVIDUAL)
00915   @Origin(TECHNICAL)
00916   private double investmentValue = 0.d;
00917 
00919   @Description("The wages paid")
00920   @Variability(PERIOD)
00921   @Initialization(INDIVIDUAL)
00922   @Origin(TECHNICAL)
00923   private double wagesPaid= 0.d;
00924   
00926   @Description("The interest paid on debt")
00927   @Variability(PERIOD)
00928   @Initialization(INDIVIDUAL)
00929   @Origin(TECHNICAL)
00930   private double interestsOnDebt= 0.d;
00931   
00933   @Description("The debt of the Firm")
00934   @Variability(PERIOD)
00935   @Initialization(INDIVIDUAL)
00936   @Origin(TECHNICAL)
00937   private double debt = 0.d;
00938   
00940   @Description("The variation of the debt of the Firm")
00941   @Variability(PERIOD)
00942   @Initialization(INDIVIDUAL)
00943   @Origin(TECHNICAL)
00944   private double debtVariation = 0.d;
00945   
00947   @GreaterOrApproxZero
00948   @Description("The amount of work the Firm needs for the desired production")
00949   @Variability(PERIOD)
00950   @Initialization(CLUSTER)
00951   @Origin(TECHNICAL)
00952   private double targetEmployment;
00953   
00955   @GreaterOrApproxZero
00956   @Description("The percentage of its target employment the firm currently employs")
00957   @Variability(N_PERIODS)
00958   @Initialization(INDIVIDUAL)
00959   @Origin(TECHNICAL)
00960   private double laborCapacity;
00961 
00963   @GreaterOrApproxZero 
00964   @Description("The input coefficient for labor")
00965   @Variability(N_PERIODS)
00966   @Initialization(CLUSTER)
00967   @Origin(TECHNICAL)
00968   private double laborInputCoefficient;
00969 
00970   @Description("The labour input coefficient can mutate at most this much " +
00971                                                           "(positively or negatively)")
00972   @Variability(SIMULATION)
00973   @Initialization(EQUAL)
00974   @Origin(THEORETICAL)
00975   private DoubleInterval laborInputCoeffMutation;
00976 
00978   @GreaterOrApproxZero
00979   @Description("The current stock of goods used as circulating capital")
00980   @Variability(PERIOD)
00981   @Initialization(CLUSTER)
00982   @Origin(TECHNICAL)
00983   private double[] circulatingCapital;
00984 
00986   @GreaterOrApproxZero
00987   @Description("The vector of input coefficients for circulating capital. Coefficients " +
00988       "determine how much of the good from each sector is needed to produce one unit of good.") 
00989   @Variability(N_PERIODS)
00990   @Initialization(CLUSTER)
00991   @Origin(TECHNICAL)
00992   private double[] circulatingInputCoefficients;
00993 
00994   @Description("The input coefficients for circulating capital can mutate at most this much " +
00995   "(positively or negatively)")
00996   @Variability(SIMULATION)
00997   @Initialization(EQUAL)
00998   @Origin(THEORETICAL)
00999   private DoubleInterval[] circulatingInputCoeffMutation;
01000 
01002   @GreaterOrApproxZero
01003   @Description("The current stock of goods used as fixed capital")
01004   @Variability(PERIOD)
01005   @Initialization(INDIVIDUAL)
01006   @Origin(TECHNICAL)
01007   private double[] fixedCapital;
01008 
01010   @GreaterOrApproxZero
01011   @Description("The vector of input coefficients for fixed capital. Coefficients determine " +
01012       "how much of the good from each sector is needed to produce one unit of good.")
01013   @Variability(N_PERIODS)
01014   @Initialization(CLUSTER)
01015   @Origin(TECHNICAL)
01016   private double[] fixedInputCoefficients;
01017 
01018   @Description("The input coefficients for fixed capital can mutate at most this much " +
01019   "(positively or negatively)")
01020   @Variability(SIMULATION)
01021   @Initialization(EQUAL)
01022   @Origin(THEORETICAL)
01023   private DoubleInterval[] fixedInputCoeffMutation;
01024 
01025   @Description("The initial values of the input coefficients for circulating capital")
01026   @Variability(SIMULATION)
01027   @Initialization(CLUSTER)
01028   @Origin(TECHNICAL)
01029   private double[] initialCirculatingInputCoefficients;
01030 
01031   @Description("The initial values of the input coefficients for fixed capital")
01032   @Variability(SIMULATION)
01033   @Initialization(CLUSTER)
01034   @Origin(TECHNICAL)
01035   private double[] initialFixedInputCoefficients;
01036 
01037   @Description("The initial value of the input coefficient for labor")
01038   @Variability(SIMULATION)
01039   @Initialization(CLUSTER)
01040   @Origin(TECHNICAL)
01041   private double initialLaborInputCoefficient;
01042 
01044   @NotNull
01045   @Description("An array of Supplier Objects, one for each Sector")
01046   @Variability(SIMULATION)
01047   @Initialization(EQUAL)
01048   private Suppliers suppliers[];
01049 
01051   @GreaterOrApproxZero
01052   @Description("The desired level of production")
01053   @Variability(PERIOD)
01054   @Initialization(CLUSTER)
01055   @Origin(TECHNICAL)
01056   private double desiredProduction;
01057 
01059   @GreaterOrApproxZero
01060   @Description("The dividend payed by this firm for this period")
01061   @Variability(PERIOD)
01062   @Initialization(INDIVIDUAL)
01063   @Origin(TECHNICAL)
01064   private double dividend;
01065   
01066   @Description("The random generator used")
01067   @Variability(SIMULATION)
01068   @Initialization(EQUAL)
01069   private RandomGenerator random = null;
01070 
01071   @Description("The production function, used when mutation occurs to determine new " +
01072       "coefficients")
01073   @Variability(SIMULATION)
01074   @Initialization(EQUAL)
01075   @Origin(TECHNICAL)
01076   private ProductionFunction productionFunction;
01077   
01079   @Description("The period in which the firm was added to the foundation")
01080   @Variability(SIMULATION)
01081   @Initialization(INDIVIDUAL)
01082   private int periodCreated;
01083   
01085   private double[] rationing;
01086   
01088   @GreaterOrApproxZero
01089   private double salesForecast =0.d;
01090   
01092   @GreaterOrApproxZero
01093   private double salesTrendForecast=0.d;
01094   
01096   @GreaterOrApproxZero
01097   private double[] targetInvestment;
01098   
01100   @GreaterOrApproxZero
01101   private double productionGap=0;
01102   
01111   Firm(Foundation pFoundation, FirmInitValues pInitValues, Sector pSector,
01112       int pIndexFirmInSector) {
01113     foundation = pFoundation;
01114     random = Foundation.getRandomGenerator();
01115     initValues = pInitValues;
01116     productionSector = pSector;
01117 
01118     probe.indexFirmInSector = pIndexFirmInSector;
01119   }
01120 
01121   // class methods
01132   @PostValidateThis void init(int pId, int pPhase, double pDesiredProduction) throws ParameterParserException {
01133     // At initialization no Workers are employed
01134     workerList.clear();
01135     rateProductionUp =productionSector.getInitGrowthRate();
01136     profit=0;
01137     profitRate=0;
01138     producedQuantity =pDesiredProduction;   
01139     desiredProduction = (1+rateProductionUp)*pDesiredProduction;
01140     salesForecast=pDesiredProduction;
01141     salesTrendForecast=rateProductionUp;
01142     rationing= new double[foundation.getNumSectors()]; 
01143 
01144     if (pPhase == ADDED_WHILE_INITIALIZE) {
01145       //wageReference = 1.0 - foundation.getInitWageVariation()*random.inRangeDouble(0,1);      
01146       wageReference = 1.0;
01147       assert(wageReference>0);
01148       wage = wageReference *  productionSector.getBenchmarkWage();
01149       assert(wage>0);
01150       inventory = initValues.getTargetInventoryRatio()*pDesiredProduction;
01151       debt= (pDesiredProduction/productionSector.getInitProduction())*
01152       productionSector.getInitCapitalStockShare()*initValues.getDebts();
01153     } 
01154     // And also initialize the Supplier inner class instances and the capital stocks...
01155     initArraysAndMatrices();
01156     // ... the probe can't initialized before the supplier instances
01157     probe.init();
01158     foundation.getProbeManager().addProbe(probe);
01159 
01160     stats.init(foundation.getStepManager());
01161 
01162     // set productionFunction etc.
01163     productionFunction = ProductionFunctionFactory.buildProductionFunctionWithName(
01164                                                        initValues.getProductionFunctionName(),
01165                                                        this,
01166                                                        foundation.getNumSectors());
01167   }
01168 
01170   private void initArraysAndMatrices() {
01171     final int lNumSectors = foundation.getNumSectors();
01172     final double lMaxNumberSuppliersRatio=0.5;
01173 
01174     // first create ...
01175     suppliers = new Suppliers[lNumSectors];
01176     for (int iSector = 0; iSector < lNumSectors; iSector++) {
01177       suppliers[iSector] = new Suppliers();
01178     }
01179 
01180     //... and initialize the Suppliers
01181     int iSector = 0;
01182     for (final Sector lSector : foundation.getSectorList()) {
01183       suppliers[iSector++].init(foundation, this, lSector, lMaxNumberSuppliersRatio);
01184     }
01185 
01186     // then the capital stock arrays
01187     circulatingCapital = new double[lNumSectors];
01188     fixedCapital = new double[lNumSectors];
01189     targetInvestment = new double[lNumSectors];
01190     isInvest = new boolean[lNumSectors];
01191     Arrays.fill(isInvest, false);
01192     Arrays.fill(circulatingCapital, 0d);
01193     laborInputCoefficient = productionSector.getBenchmarkLaborInputCoefficient();
01194     assert (laborInputCoefficient>ProductionFunction.MIN_COEFF_FOR_NEEDED_LABOR) ;
01195     initialLaborInputCoefficient = laborInputCoefficient;
01196 
01197     circulatingInputCoefficients = new double[lNumSectors];
01198     fixedInputCoefficients = new double[lNumSectors];
01199     Arrays.fill(circulatingInputCoefficients , 0d);
01200     Arrays.fill(fixedInputCoefficients , 0d);
01201     for (final Sector lSector : foundation.getSectorList()) {
01202       final int lSectorIndex=lSector.getArrayIndex();
01203       if (productionSector.getInitInputOutputCirculating(lSector.getArrayIndex()) >0){
01204         circulatingInputCoefficients[lSectorIndex] =productionSector.getBenchmarkCirculatingInputCoefficient(lSectorIndex);
01205 
01206       }
01207 
01208       if (productionSector.getInitCapitalStock(lSector.getArrayIndex()) >0){
01209 
01210       fixedInputCoefficients[lSectorIndex] =productionSector.getBenchmarkFixedInputCoefficient(lSectorIndex);
01211       
01215       final double lGrowthRate = productionSector.getInitGrowthRate();
01216       final double lDepRate= productionSector.getInitFixedCapitalDepreciationRate(lSectorIndex);
01217       final double lFactor = (1+lGrowthRate)/(1-lDepRate);
01218       final double lPeriodicity=productionSector.getInvestmentPeriodicity(lSectorIndex);
01219       final double lInvestTime = Math.floor(random.inRangeDouble(0,lPeriodicity-1));
01220       fixedCapital[lSectorIndex]= Math.pow(lFactor,lInvestTime)*invProdFuncFixed(desiredProduction)[lSectorIndex];
01221       isInvest[lSectorIndex] =(lInvestTime<1);
01222       assert (!Double.isNaN(fixedCapital[lSectorIndex]));
01223       if (isInvest[lSectorIndex]){
01224         fixedCapital[lSectorIndex]= invProdFuncFixed(desiredProduction)[lSectorIndex]/(1-lDepRate);
01225       }
01226 
01227       
01228 /*      final double lFactor = (1+lDepRate)*(1+lGrowthRate);
01229       final double lInitCapacityRate = 1/Math.pow(lFactor, lInvestTime);
01230       fixedCapital[lSectorIndex]= invProdFuncFixed(desiredProduction)[lSectorIndex]/lInitCapacityRate;*/
01231       
01232       }
01233     }
01234       
01235       
01236     initialCirculatingInputCoefficients = ArrayTools.deepCopy(circulatingInputCoefficients);
01237     initialFixedInputCoefficients = ArrayTools.deepCopy(fixedInputCoefficients);
01238     double ls = ArrayTools.sumDouble(circulatingInputCoefficients)+ ArrayTools.sumDouble(fixedInputCoefficients);
01239     assert(ls>0);
01240 
01241     // initialize the target employment
01242     targetEmployment = desiredProduction*laborInputCoefficient;
01243 
01244     // construct the MutationIntervals
01245     laborInputCoeffMutation = new DoubleInterval(-productionSector.getInitLaborMutationRange(),
01246                                                  productionSector.getInitLaborMutationRange());
01247     circulatingInputCoeffMutation = new DoubleInterval[lNumSectors];
01248     fixedInputCoeffMutation = new DoubleInterval[lNumSectors];
01249     for (iSector = 0; iSector < lNumSectors; iSector++) {
01250       circulatingInputCoeffMutation[iSector] = new DoubleInterval(
01251           -productionSector.getInitCirculatingMutationRange(),
01252           productionSector.getInitCirculatingMutationRange());
01253       fixedInputCoeffMutation[iSector] = new DoubleInterval(
01254           -productionSector.getInitFixedMutationRange(),
01255           productionSector.getInitFixedMutationRange());
01256 
01257     }
01258   }
01259 
01260   void deInit() {
01261     foundation.getProbeManager().removeProbe(probe);
01262     probe.deInit();
01263   }
01264 
01270   @PreValidateThis
01271   @PostValidateThis
01272   public void trade() {
01273     // observe the current state of suppliers
01274     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01275       suppliers[iSector].updateSuppliers(Suppliers.SellerSet.INCLUDE_IMPORT);
01276     }
01277     
01278     double[] lDemand= new double[foundation.getNumSectors()];
01279 
01280     // In case of rationing, add new suppliers, compute the level of rationing  
01281     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01282       lDemand[iSector] += getDemandCirculating(desiredProduction)[iSector];
01283       lDemand[iSector] += Math.max(0,(isInvest[iSector]? 1:0)*getDemandFixed(desiredProduction)[iSector]);
01284       suppliers[iSector].addSuppliers(lDemand[iSector],Suppliers.SellerSet.INCLUDE_IMPORT);
01285       rationing[iSector]=Math.max(0,lDemand[iSector]-suppliers[iSector].maxSupply());
01286     }
01287 
01288     
01289     // compute the maximal feasible production
01290     final double lMaxProduction = calcMaxProductionInclSupply();
01291     final double lProduction = Math.min(desiredProduction,lMaxProduction);
01292     if (ArrayTools.allValuesAreLower(rationing,0)){
01293       //assert(FloatMath.greaterOrApproxEqual(lProduction,desiredProduction,0.1));
01294     }
01295 
01296     
01297     // calculate the demand
01298     final double[] acquireCirculating =getDemandCirculating(lProduction);
01299     final double[] acquireFixed = new double[foundation.getNumSectors()];
01300     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01301       acquireFixed[iSector] = (isInvest[iSector] ?1:0)*getDemandFixed(lProduction)[iSector];
01302       assert (  acquireFixed[iSector]>=0);
01303       targetInvestment[iSector]=acquireFixed[iSector];
01304 //      assert (FloatMath.lowerOrApproxEqual(acquireCirculating[iSector], suppliers[iSector].maxSupply()));
01305     }
01306 
01307 
01308     // buy the goods. The Math.min(Suppliers...) is a hack in order to correct the fact that invProdFuncFixed and CalcMaxProd
01309     // are not perfect inverse if one takes into account approximation errors.
01310     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01311       final double lCost = suppliers[iSector].buy(
01312          Math.min(suppliers[iSector].maxSupply(),
01313                   acquireCirculating[iSector]));
01314       money -= lCost;
01315       costs += lCost;
01316       intermediaryConsumptionValue+= lCost;
01317 
01318     }
01319     
01320     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01321       if (suppliers[iSector].maxSupply()>0){
01322         if (ArrayTools.allValuesAreLower(rationing,0) && isInvest[iSector]){
01323           assert(FloatMath.lowerOrApproxEqual(targetInvestment[iSector],suppliers[iSector].maxSupply()));
01324         }
01325         final double lCost = suppliers[iSector].buy(
01326                              Math.min(suppliers[iSector].maxSupply(), acquireFixed[iSector]));
01327         money -= lCost;
01328         investmentValue+= lCost;
01329         isInvest[iSector]=FloatMath.greaterOrApproxEqual(getDemandFixed(desiredProduction)[iSector],
01330                                                          fixedCapital[iSector]);
01331 
01332       }
01333     }
01334     
01335 
01336     // update the stocks
01337     //TODO: check the consistency.
01338     circulatingCapital = ArrayTools.addArrays(circulatingCapital, acquireCirculating);
01339     fixedCapital = ArrayTools.addArrays(fixedCapital, acquireFixed);
01340     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01341       assert (!Double.isNaN(fixedCapital[iSector]));
01342     }
01343 
01344   }
01345 
01346   
01353   double[] getDemandCirculating(double pProduction){
01354     
01355     return ArrayTools.maxArray(0.d,
01356                               ArrayTools.subtractArrays(invProdFuncCirculating(pProduction), circulatingCapital));
01357   }
01358   
01365   double[] getDemandFixed(double pProduction){
01366     double[] lDemand = new double [foundation.getNumSectors()]; 
01367     
01368     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01369       double lAmount= (1+productionSector.getCapitalReserveRate(iSector))*invProdFuncFixed(pProduction)[iSector];
01370             lDemand[iSector]=Math.max(0,lAmount-fixedCapital[iSector]);  
01371             assert (lDemand[iSector]>=0);
01372     }
01373 
01374     return lDemand;
01375   }
01376 
01378   void storeInventoryAfterTrade() {
01379     inventoryAfterTrade = inventory;
01380   }
01381 
01388   @PreValidateThis
01389   @PostValidateThis
01390 void adjustEmployees() {
01391     targetEmployment = calcNewTargetEmployment();
01392     assert (FloatMath.greaterOrApproxEqual(prodFuncLabor(targetEmployment), desiredProduction));
01393     wage = wageReference * productionSector.getBenchmarkWage();
01394 
01395     final double lInitWorkAmount = calcWorkAmount();
01396     if (targetEmployment >= lInitWorkAmount) {
01397       hireWorkers(targetEmployment - lInitWorkAmount);
01398     } else if (targetEmployment < lInitWorkAmount){
01399       layoffWorkers(lInitWorkAmount - targetEmployment);
01400     }
01401     double lWorkforce=calcWorkAmount();   
01402 
01403 //  if (foundation.getGovernment().getUnemploymentRate()>0.03){ 
01404 //    assert(FloatMath.greaterOrApproxEqual(lWorkforce,targetEmployment));
01405 //  }
01406     
01407     if (targetEmployment>0){
01408 laborCapacity=  lWorkforce/targetEmployment;
01409     }
01410     else {
01411       laborCapacity=0;
01412     }
01413   }
01414 
01420   @Post(expr = "_returns >= 0 &&" +
01421       "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual" +
01422       "(_returns, _this.environment.getNumWorkersTotal())",
01423       lang = "groovy")
01424   double calcWorkAmount() {
01425     double lSumAmount = 0.d;
01426     for (final WorkContract lWorkContract : workerList.values()) {
01427       lSumAmount += lWorkContract.getAmount();
01428     }
01429 
01430     return lSumAmount;
01431   }
01432 
01438   @GreaterOrApproxZero
01439   private double calcNewTargetEmployment() {
01440     double lMaxProduction = getMaxProductionFromFixed();
01441     double lBenchmarkProduction =Math.max(desiredProduction,initValues.getMinimumLaborCapacity()*lMaxProduction);
01442     return invProdFuncLabor(lBenchmarkProduction);
01443   }
01444 
01451   @PreValidateThis
01452   @PostValidateThis
01453   @Post(expr = "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual(" +
01454       "_this.productionSector.invProdFuncLabor(_this.demandedEffort, _this.producedQuantity), "
01455       + "_this.calcWorkAmount())",
01456       lang = "groovy")
01457   void productionStep() {
01458     producedQuantity = Math.min(desiredProduction,
01459         calcMaxProduction(MAXPRODUCTION_CAPITAL_AND_LABOR, circulatingCapital, fixedCapital));
01460     productionGap= desiredProduction-producedQuantity;
01461     
01462     //assert (FloatMath.approxEqual(producedQuantity,desiredProduction));
01463 //assert(FloatMath.approxEqual(producedQuantity,desiredProduction));
01464     // depreciate product stock and add production
01465     inventory = (1d - productionSector.getInitInventoryDepreciationRate()) * inventory +
01466         producedQuantity;
01467 
01468     // consume circulating capital
01469     final double[] lUsedCirculating = invProdFuncCirculating(producedQuantity);
01470     for (final Sector lSector : foundation.getSectorList()) {
01471       final int lIndex = lSector.getArrayIndex();
01472       circulatingCapital[lIndex] =
01473           (1d - lSector.getInitInventoryDepreciationRate()) *
01474           (circulatingCapital[lIndex] - lUsedCirculating[lIndex]);
01475     }
01476 
01477     // depreciate fixed capital and add the depreciation to the costs 
01478     final double[] lUsedFixed = invProdFuncFixed(producedQuantity);
01479     for (final Sector lSector : foundation.getSectorList()) {
01480       final double lDepreciation = productionSector.getInitFixedCapitalDepreciationRate(lSector.getArrayIndex());
01481       fixedCapital[lSector.getArrayIndex()] -= lDepreciation*lUsedFixed[lSector.getArrayIndex()];
01482       final double lPrice = lSector.getStats().getAverageTradePrice();
01483       costs += lPrice*lDepreciation*lUsedFixed[lSector.getArrayIndex()];
01484     }
01485     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01486       assert (!Double.isNaN(fixedCapital[iSector]));
01487     }
01488   }
01489 
01513   @PreValidateThis
01514   @Post(expr = "(_returns != Double.MAX_VALUE) && (_returns > 0.0)", lang = "groovy")
01515   private double calcMaxProduction(int pLimitation,
01516                                    double[] pCirculatingCapital,
01517                                    @GreaterOrApproxZero double[] pFixedCapital) {
01518     final int lNumSectors = foundation.getNumSectors();
01519 
01520     double lFactor = Double.MAX_VALUE;
01521     for (int iSector = 0; iSector < lNumSectors; iSector++) {
01522       // first check the fixed capital, this is done always
01523       final double lLimitationFixed = isNeededFixedCapital(iSector)
01524                                       ? pFixedCapital[iSector] / fixedInputCoefficients[iSector]
01525                                       : Double.MAX_VALUE;
01526       lFactor = Math.min(lLimitationFixed, lFactor);
01527 
01528       // the check the circulating capital, in case that this is needed
01529       if (pLimitation != MAXPRODUCTION_FIXED_CAPITAL_ONLY) {
01530         final double lLimitationCirculating = isNeededCirculatingCapital(iSector)
01531                         ? pCirculatingCapital[iSector] /circulatingInputCoefficients[iSector]
01532                         : Double.MAX_VALUE;
01533         lFactor = Math.min(lLimitationCirculating, lFactor);
01534       }
01535     }
01536 
01537     // and also check the labor, if requested
01538     if (pLimitation == MAXPRODUCTION_CAPITAL_AND_LABOR) {
01539       final double lLabor =calcWorkAmount();
01540       final double lLimitationLabor = prodFuncLabor(lLabor);
01541       lFactor = Math.min(lFactor, lLimitationLabor);
01542       assert (!Double.isNaN(lFactor));
01543 
01544     }
01545 
01546     return lFactor;
01547   }
01548 
01559   @PreValidateThis
01560   @GreaterOrApproxZero
01561   private double calcMaxProductionInclSupply() {
01562     final double[] lCirculating = ArrayTools.deepCopy(circulatingCapital);
01563     final double[] lFixed = ArrayTools.deepCopy(fixedCapital);
01564 
01565     // we have one suppliers instance per sector, and the best allocation (between
01566     // fixed and circulating capital) of the goods that the firm can be acquire
01567     // is sector independent, so we iterate over each suppliers instance
01568     for (final Suppliers lSuppliers : suppliers) {
01569       final int iSector = lSuppliers.getInputSector().getArrayIndex();
01570       final double lSupply = lSuppliers.maxSupply();
01571       if (FloatMath.greaterZero(lSupply)) {
01572         double lAlpha;
01573         if (isNeededFixedCapital(iSector)) {
01574           // to find the best distribution, we solve:
01575           // (circCapital + alpha * supply) / circCoef =
01576           //                            (fixedCapital + (1 - alpha) * supply) / fixedCoef
01577           lAlpha =
01578               (circulatingInputCoefficients[iSector] * (fixedCapital[iSector] + lSupply) -
01579                   fixedInputCoefficients[iSector] * circulatingCapital[iSector]) /
01580           ((circulatingInputCoefficients[iSector] + fixedInputCoefficients[iSector]) * lSupply);
01581 
01582           // alpha must be in the interval [0...1], we can't shift existing circulatingCapital
01583           // to fixed or vice versa
01584           lAlpha = Math.min(lAlpha, 1.d);
01585           lAlpha = Math.max(lAlpha, 0.d);
01586         } else {
01587           // the good is not needed as fixed capital, so we add the supply to the
01588           // circulating capital
01589           lAlpha = 1.d;
01590         }
01591 
01592         // and the possible allocation with the found distribution to the current stock
01593         lCirculating[iSector] += lAlpha * lSupply;
01594         lFixed[iSector] += (1 - lAlpha) * lSupply;
01595       }
01596     }
01597     
01598     if (ArrayTools.allValuesAreLower(rationing,0)){
01599       double lTest =calcMaxProduction(MAXPRODUCTION_CAPITAL, lCirculating, lFixed);
01600     //  assert(FloatMath.greaterOrApproxEqual(lTest,desiredProduction,0.1));
01601     }
01602 
01603     return calcMaxProduction(MAXPRODUCTION_CAPITAL, lCirculating, lFixed);
01604   }
01605 
01609   @PreValidateThis
01610   @GreaterOrApproxZero
01611   private double calcMaxProductionFromFixed(@GreaterOrApproxZero double[] pFixedCapital) {
01612     return calcMaxProduction(MAXPRODUCTION_FIXED_CAPITAL_ONLY, null, pFixedCapital);
01613   }
01614 
01615   // inverse production functions @GreaterOrApproxZero
01632   double[] invProdFuncCirculating(double pQuantity, double[] pCirculatingInputCoefficients) {
01633     final double[] lNeeded = new double[foundation.getNumSectors()];
01634     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01635       lNeeded[iSector] = isNeededCirculatingCapital(iSector) ?
01636           pQuantity * pCirculatingInputCoefficients[iSector] : 0d;
01637     }
01638     return lNeeded;
01639   }
01640 
01645   @GreaterOrApproxZero
01646   private double[] invProdFuncCirculating(double pQuantity) {
01647     return invProdFuncCirculating(pQuantity, circulatingInputCoefficients);
01648   }
01649 
01665   @GreaterOrApproxZero
01666   double[] invProdFuncFixed(double pQuantity, double[] pFixedInputCoefficients) {
01667     final double[] lNeeded = new double[foundation.getNumSectors()];
01668     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01669       lNeeded[iSector] = isNeededFixedCapital(iSector) ?
01670           pQuantity * pFixedInputCoefficients[iSector] : 0d;
01671     }
01672     return lNeeded;
01673   }
01674 
01679   @GreaterOrApproxZero
01680   double[] invProdFuncFixed(double pQuantity) {
01681     return invProdFuncFixed(pQuantity, fixedInputCoefficients);
01682   }
01683 
01685   @GreaterOrApproxZero
01686   double prodFuncLabor(double pQuantity) {
01687     double lLimit=  productionSector.getLaborProductivity() * pQuantity / laborInputCoefficient;  
01688     assert(!Double.isNaN(lLimit));
01689   
01690     return lLimit;
01691   }
01692 
01694   @GreaterOrApproxZero
01695   double invProdFuncLabor(double pQuantity) {
01696     return pQuantity * laborInputCoefficient/ productionSector.getLaborProductivity();
01697   }
01698 
01707   public boolean isNeededCirculatingCapital(int pIndex) {
01708     return (circulatingInputCoefficients[pIndex] > 0);
01709   }
01710 
01719   public boolean isNeededFixedCapital(int pIndex) {
01720     return (fixedInputCoefficients[pIndex] > 0);
01721   }
01722 
01730   @PostValidateThis
01731   void account() {
01732     final double lInterestRate = foundation.getFinancial().getInterestRate();
01733     final double lOldInventory =stats.getSoldQuantityLastPeriod();
01734     final double lOldProducedQuantity =stats.getProducedQuantityLastPeriod();
01735     final double lOldSoldQuantity =stats.getSoldQuantityLastPeriod();
01736     final double lOldCosts =stats.getCostsLastPeriod();
01737     
01738 
01739     // pay wages
01740 /*    wagesPaid = 0.d;
01741     for (final WorkContract lWorkContract : workerList.values()) {
01742       wagesPaid += lWorkContract.getWageCurrentWorkAmount();
01743     }*/
01744     wagesPaid=0.d;
01745     double lNormalizedWages=0;
01746     final LinkedList<Household> lWorkers = new LinkedList<Household>(workerList.keySet());
01747     for (final Household lHousehold : lWorkers) {
01748       double lWage = workerList.get(lHousehold).getWageCurrentWorkAmount();
01749       wagesPaid +=lWage;
01750       lNormalizedWages+=lWage/wageReference;
01751       assert (lWage>0);
01752     }
01753     // add wages to the costs for this period.
01754     benchmarkCosts=costs+lNormalizedWages;
01755     costs += wagesPaid;
01756     
01757     interestsOnDebt=lInterestRate * debt;
01758     money -= (wagesPaid + interestsOnDebt);
01759     double lOldDebt= debt; 
01760     if (money < 0) {
01761       if (foundation.getFinancial().askForDebt(this, -money) < -money) {
01762         // we didn't got the needed debt, we are dead!
01763       }
01764     }
01765 
01766     if (money>=debt){
01767       money-=debt;
01768       debt=0;
01769     }
01770     else{
01771      debt-=money;
01772      money=0;
01773     }
01774 
01775     debtVariation= debt -lOldDebt;
01776     
01777     // the income is computed as the sales of last period production  
01778     //profit = Math.min(profit, price * lOldProducedQuantity);  
01779 
01780     /*  plus the increase in inventories if those are low (future sales anticipated) 
01781      * 
01782      */
01783     if (initValues.getTargetInventoryRatio()*lOldSoldQuantity>lOldInventory){
01784       profit += 0;      
01785     }
01786     
01787 
01788             
01789     if (lOldCosts > 0.d){
01790       profit -= lOldCosts;
01791       profitRate = (profit / lOldCosts);
01792       assert (!Double.isNaN(profitRate));
01793     }
01794     // else we are in the first period, and we use the following approximation of costs, based on the 
01795     //assumption that all prices were equal to one.
01796     else if (producedQuantity>0 && markUp<1){
01797       final double lCosts=(1-markUp)*producedQuantity;
01798       profit-=lCosts;
01799       profitRate=profit/lCosts;
01800     }
01801 
01802     sumProfitsMemory += profit;
01803 
01804     // distribute a dividend
01805     if (money > 0) {
01806       dividend = getInitDividendRate() * money;
01807       money -= dividend;
01808     } else {
01809       dividend = 0;
01810     }
01811 /*    if (money > 0 && profit>0) {
01812       dividend = Math.min(profit*getInitDividendRate(), money);
01813       money -= dividend;
01814     } else {
01815       dividend = 0;
01816     }*/
01817 /*    if (profit>0) {
01818       dividend = profit*getInitDividendRate();
01819       money -= dividend;
01820     } else {
01821       dividend = 0;
01822     }
01823     */
01824     
01825     moneyVariation = money - stats.getMoneyLastPeriod();    
01826   }
01827 
01833   @PreValidateThis
01834   @PostValidateThis
01835   
01836   void updateDesiredProduction() {
01837     //ForecastTools.updateHolt(salesForecast, salesTrendForecast, soldQuantity);
01838     double lOldBase=salesForecast;
01839     double lOldTrend=salesTrendForecast;
01840     double lRate=initValues.getSalesForecastUpdateRate();
01841     
01842   /*  double lSoldInSector= foundation.getStats().getTradeTrace().getOverallQuantitySelledInSector(productionSector);
01843     double lDemandInSector= lSoldInSector + productionSector.getStats().getRationing();
01844     assert(lDemandInSector>=lSoldInSector);
01845     double lDemand= soldQuantity*Math.min(lDemandInSector/lSoldInSector,(1+initValues.getMaxRateProdUp()));
01846     assert(lDemand>=soldQuantity);
01847     salesForecast=Math.max(0,(1-lRate)*(lOldBase+lOldTrend)+lRate*lDemand);
01848     salesTrendForecast=(1-lRate)*lOldTrend+lRate*(salesForecast-lOldBase);*/
01849     
01850     salesForecast=Math.max(0,(1-lRate)*(lOldBase+lOldTrend)+lRate*soldQuantity);
01851     salesTrendForecast=Math.max(0,(1-lRate)*lOldTrend+lRate*(salesForecast-lOldBase));
01852     //salesTrendForecast=(1-lRate)*lOldTrend+lRate*(salesForecast-lOldBase);
01853     desiredProduction= Math.max(0,Math.min(getMaxProductionFromFixed(),salesForecast+salesTrendForecast));
01854     for (int iSector = 0; iSector < foundation.getNumSectors(); iSector++) {
01855       isInvest[iSector] = FloatMath.greaterOrApproxEqual((salesTrendForecast+salesForecast)*fixedInputCoefficients[iSector],
01856                                                         fixedCapital[iSector]);
01857     }     
01858     if (producedQuantity>0){
01859       rateProductionUp= (desiredProduction/producedQuantity)-1;
01860     }
01861     assert (!Double.isNaN(desiredProduction));
01862   }
01863   
01864 
01865 
01871   @PreValidateThis
01872   @PostValidateThis
01873   void updatePrice() {
01874     double lOldPrice=price;
01875     if (producedQuantity > 0 && (benchmarkCosts>0)){
01876       price = Math.min((1+markUp)*benchmarkCosts/producedQuantity,productionSector.getStats().getAverageTradePrice()*2);
01877       //price = Math.min((1+markUp)*costs/producedQuantity,productionSector.getStats().getAverageTradePrice()*2);
01878 
01879     } 
01880      price=0.95*lOldPrice+0.05*price; 
01881     
01882     assert (!Double.isNaN(price));
01883     assert(price>0);
01884   }
01885 
01895   @PreValidateThis
01896   @PostValidateThis
01897   @Post(expr = "de.pik.lagom.toolbox.math.FloatMath.approxEqual" +
01898                 "(_this.calcWorkAmount(), _old + pAmountWorkToAdd - _returns)",
01899         old = "_this.calcWorkAmount()",
01900         lang = "groovy")
01901   double hireWorkers(@NotNegative double pAmountWorkToAdd) {
01902     // first try to increase the work amount of already employed workers
01903     final LinkedList<Household> lWorkers = new LinkedList<Household>(workerList.keySet());
01904     Collections.sort(lWorkers, new FallbackComparator());
01905 
01906     final Iterator<Household> iterWorkers = lWorkers.iterator();
01907 
01908     // Iterate over the workers sorted by increasing Fallback and get their actual work amount
01909     while (iterWorkers.hasNext() && (pAmountWorkToAdd > 0.d)) {
01910       final Household lWorker = iterWorkers.next();
01911 
01912       // create and offer a work contract offer with the current operation characteristics
01913       final WorkContract lWorkContract = new WorkContract(this,Math.min(pAmountWorkToAdd, 1.d));
01914       final double lWorkAmountOfWorkerBeforeOffer = workerList.get(lWorker).getAmount();
01915       final WorkContract lAcceptedWorkContract = lWorker.checkWorkContractOffer(lWorkContract);
01916 
01917       // check the response 
01918       if (lAcceptedWorkContract.getStatus() == WorkContract.Status.ACCEPTED) {
01919         // if the household was already employed, the old work amount must be added to the
01920         // searched work amount, because the work amount in the accepted work contract describes
01921         // the new total work amount for this household and not the difference from the old
01922         // to the new one
01923         pAmountWorkToAdd -= lAcceptedWorkContract.getAmount() - lWorkAmountOfWorkerBeforeOffer;
01924 
01925         householdAcceptWorkContract(lWorker, lAcceptedWorkContract);
01926       }
01927     }
01928 
01929     // then try to hire new workers, starting with those with most free time available.
01930     final Iterator<Household> iterWorkers2 = foundation.getHouseholds().
01931                                                             workAmountSortedIterator();
01932     // Iterate over the sorted workers and get their actual work amount
01933     while (iterWorkers2.hasNext() && (pAmountWorkToAdd > 0.d)) {
01934       final Household lWorker = iterWorkers2.next();
01935       // households that already work for the firm are skipped because they got an offer before
01936       if (workerList.containsKey(lWorker)) {
01937         continue;
01938       }
01939 
01940       // create and offer a work contract offer with the current operation characteristics
01941       final WorkContract lWorkContract =
01942         new WorkContract(this,Math.min(pAmountWorkToAdd, 1.d));
01943       final WorkContract lAcceptedWorkContract = lWorker.checkWorkContractOffer(lWorkContract);
01944 
01945       // check the response 
01946       if (lAcceptedWorkContract.getStatus() == WorkContract.Status.ACCEPTED) {
01947         pAmountWorkToAdd -= lAcceptedWorkContract.getAmount();
01948         householdAcceptWorkContract(lWorker, lAcceptedWorkContract);
01949       }
01950     }
01951 
01952     return pAmountWorkToAdd;
01953   }
01954 
01960   @PreValidateThis
01961   @PostValidateThis
01962   @Pre(expr = "_this.workerList.size() > 0 && " +
01963       "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual" +
01964       "(pWorkAmountToReduce, _this.calcWorkAmount())", lang = "groovy")
01965   @Post(expr = "de.pik.lagom.toolbox.math.FloatMath.approxEqual" +
01966       "(_this.calcWorkAmount(), _old - pWorkAmountToReduce)",
01967       old = "_this.calcWorkAmount()", lang = "groovy")
01968   void layoffWorkers(double pWorkAmountToReduce) {
01969     //we sort the workers by their Fallback, from high to low, so that the workers who are 
01970     //"least satisfied" with their wage are layed off first 
01971     final LinkedList<Household> lHouseholds = new LinkedList<Household>(workerList.keySet());
01972     Collections.sort(lHouseholds, new InverseFallbackComparator());
01973 
01974     final Iterator<Household> iterHouseholds = lHouseholds.iterator();
01975     while (FloatMath.greaterZero(pWorkAmountToReduce)) {
01976       final Household lHousehold = iterHouseholds.next();
01977       final WorkContract lWorkContract = workerList.get(lHousehold);
01978 
01979       if (pWorkAmountToReduce >= lWorkContract.getAmount()) {
01980         // When the household works less than the amount the firm wants to reduce, fire
01981         // him completely ...
01982         lHousehold.removeEmployment(this);
01983         workerList.remove(lHousehold);
01984         pWorkAmountToReduce -= lWorkContract.getAmount();
01985       } else {
01986         // ... else just reduce the his amount of work
01987         lWorkContract.setAmount(lWorkContract.getAmount() - pWorkAmountToReduce);
01988         lHousehold.addEmployment(lWorkContract);
01989         workerList.put(lHousehold, lWorkContract);
01990         break;
01991       }
01992     }
01993   }
01994 
01995   // Change the operating characteristics of the firm. 
01997   @PostValidateThis
01998   void mutatePrice() {
01999     markUp += (random.nextBoolean(0.5) ? 1 : -1) * initValues.getPriceMutationScale() * Math.max(0.1,markUp);
02000     markUp = Math.max(markUp, 0.d);
02001   }
02002   
02004   @PostValidateThis
02005   void mutateWageReference() {
02006     wageReference += (random.nextBoolean(0.5) ? 1 : -1) * foundation.getInitWageVariation() * 
02007                        wageReference;
02008     wageReference = Math.max(wageReference, 0.d);
02009     wageReference =Math.min(wageReference, 16);
02010   }
02011 
02013   @PostValidateThis
02014   void mutateInputCoefficients() {
02015     final ProductionFunction.VariatorResults lVariatorResults =
02016         productionFunction.mutateCoefficients(circulatingInputCoeffMutation,
02017                                               fixedInputCoeffMutation,
02018                                               laborInputCoeffMutation,
02019                                               foundation.getNumSectors());
02020 
02021     circulatingInputCoefficients = lVariatorResults.circulatingInputCoefficientsVariation;
02022     fixedInputCoefficients = lVariatorResults.fixedInputCoefficientsVariation;
02023     laborInputCoefficient = lVariatorResults.laborInputCoefficientVariation;
02024   }
02025   //end of changing characteristics of the firm
02026   
02033   @Pre(expr = "de.pik.lagom.toolbox.math.FloatMath.lowerOrApproxEqual(" +
02034                 "pContract.getAmount() - (_this.workerList.get(pHousehold)?.amount ?: 0)," +
02035                 "_this.targetEmployment - _this.calcWorkAmount()) &&" +
02036               "pContract.getAmount() >= (_this.workerList.get(pHousehold)?.amount ?: 0) && " +
02037               "pContract.getStatus() == de.pik.lagom.generic.WorkContract.Status.ACCEPTED",
02038        lang = "groovy")
02039   void householdAcceptWorkContract(Household pHousehold, WorkContract pContract) {
02040     workerList.put(pHousehold, pContract);
02041   }
02042 
02048   @Pre(expr = "_this.workerList.containsKey(pWorker)", lang = "groovy")
02049   void workerQuitJob(@NotNull Household pWorker) {
02050     workerList.remove(pWorker);
02051   }
02052 
02060   @PostValidateThis
02061   public void sell(@GreaterOrApproxZero double pTraded) {
02062     assert(FloatMath.lowerOrApproxEqual(pTraded, inventory)) :
02063       "Firm can't sell more units then it has in the inventory";
02064 
02065     inventory -= pTraded;
02066     money += price * pTraded;
02067     profit += price * pTraded;
02068     salesValue += price * pTraded;
02069     soldQuantity += pTraded;
02070   }
02071 
02079   WorkContract constructActualWorkContract() {
02080     final double lWorkAmountMissing = targetEmployment - calcWorkAmount();
02081     final WorkContract lActualWorkContract = new WorkContract(this,
02082                                                             Math.max(0.d, lWorkAmountMissing));
02083 
02084     if (FloatMath.approxZero(lWorkAmountMissing)) {
02085       lActualWorkContract.setStatus(WorkContract.Status.NO_OFFER);
02086     }
02087 
02088     return lActualWorkContract;
02089   }
02090 
02096   void copyTechnologiesFrom(Firm pArchetype) {
02097     double lOldValue=productionFunction.compute(circulatingInputCoefficients, fixedInputCoefficients,laborInputCoefficient,
02098                                                 foundation.getNumSectors());
02099     laborInputCoefficient = pArchetype.getLaborInputCoefficient();
02100     ArrayTools.deepCopyFromTo(pArchetype.getFixedInputCoefficients(), fixedInputCoefficients);
02101     ArrayTools.deepCopyFromTo(pArchetype.getCirculatingInputCoefficients(), 
02102                                   circulatingInputCoefficients);
02103 
02104     double lNormalize=productionFunction.compute(circulatingInputCoefficients, fixedInputCoefficients,laborInputCoefficient,
02105                                                 foundation.getNumSectors());
02106     
02107     ArrayTools.deepCopyFromTo(ArrayTools.multiplyArray(lOldValue/lNormalize,circulatingInputCoefficients),circulatingInputCoefficients);
02108     ArrayTools.deepCopyFromTo(ArrayTools.multiplyArray(lOldValue/lNormalize,fixedInputCoefficients),fixedInputCoefficients);
02109     laborInputCoefficient*=lOldValue/lNormalize;
02110 
02111     
02112     double lNewValue=productionFunction.compute(circulatingInputCoefficients, fixedInputCoefficients,laborInputCoefficient,
02113                                                 foundation.getNumSectors());
02114     
02115     assert(FloatMath.approxEqual(lOldValue, lNewValue, 0.1));
02116 
02117   }
02118 
02124   void copyPricesFrom(Firm pArchetype) {
02125     markUp = pArchetype.getMarkUp();
02126   }
02127   
02133   void copyWagesFrom(Firm pArchetype) {
02134     wageReference = pArchetype.getWageReference();
02135     wage = wageReference *  productionSector.getBenchmarkWage();
02136   }
02137 
02147   double calcNeededMoneyForProduction(double pProductionLevel) {
02148     final double[] lNeededFixedCapital = ArrayTools.maxArray(0.d,
02149        ArrayTools.subtractArrays(invProdFuncFixed(pProductionLevel), fixedCapital));
02150     final double[] lNeededCirculatingCapital = ArrayTools.maxArray(0.d,
02151        ArrayTools.subtractArrays(invProdFuncCirculating(pProductionLevel), circulatingCapital));
02152 
02153     double lNeededMoney = 0.d;
02154     for (final Sector lSector : foundation.getSectorList()) {
02155       lNeededMoney += lSector.getStats().getAverageSupplyPriceWithoutImport() *
02156                         (lNeededFixedCapital[lSector.getArrayIndex()] +
02157                           lNeededCirculatingCapital[lSector.getArrayIndex()]);
02158     }
02159 
02160     lNeededMoney +=  pProductionLevel* laborInputCoefficient * wage;
02161 
02162     return lNeededMoney;
02163   }
02164 
02168   double calcUnitProductionCost() {
02169     double lUnitCost = 0.d;
02170     for (final Sector lSector : foundation.getSectorList()) {
02171       int iSector=lSector.getArrayIndex();
02172       lUnitCost += lSector.getStats().getAverageSupplyPriceWithoutImport() *
02173                     (circulatingInputCoefficients[iSector] +
02174                           productionSector.getInitFixedCapitalDepreciationRate(iSector) * 
02175                                                               fixedInputCoefficients[iSector]);
02176     }
02177 
02178     lUnitCost += laborInputCoefficient * wage/productionSector.getLaborProductivity();
02179     return lUnitCost;
02180   } 
02181   
02187   public void bankrupt(){
02188     if (money >= debt){
02189       debt = 0;
02190       money -= debt;
02191       getOwner().setMoney(getOwner().getMoney() + money);
02192       money = 0;
02193     }
02194     else{
02195       debt -= money;
02196       money = 0;
02197       foundation.getFinancial().addToLiquidationMissingDebts(debt);
02198       debt = 0;
02199     }
02200     getOwner().removeFirmFromProperty(this);
02201   }
02202   
02204   public boolean isUnproductive(){
02205     return 
02206     (FloatMath.approxZero(stats.getAverageProducedQuantity(10))
02207      && (FloatMath.approxZero(producedQuantity)));
02208   }
02209  
02210   //getter/setter methods
02211   // initValues access
02212   private double getInitDividendRate() {
02213     return initValues.getDividendRate();
02214   }
02215   
02216   // from ISeller interface
02217   public double getInventory() {
02218     return inventory;
02219   }
02220   // from ISeller interface
02221   public double getBenchmarkSupply() {
02222     return producedQuantity;
02223   }
02224   
02228   public double getBAUSupply() {
02229     double lMaxProduction= Math.max(producedQuantity,getMaxProductionFromFixed());  
02230     return  Math.min(inventory,Math.max(0, lMaxProduction-soldQuantity));
02231     //return inventory;
02232   }
02233   
02238   public double getExtraSupply() {
02239     double lMaxProduction= Math.max(producedQuantity,getMaxProductionFromFixed());
02240     return Math.min(getBAUSupply(),lMaxProduction-producedQuantity);
02241     //return inventory;
02242 
02243   }
02244   
02245   public double getPrice() {
02246     return price;
02247   }
02248 
02249   public Sector getProductionSector() {
02250     return productionSector;
02251   }
02252 
02253   //others
02254   void setSoldQuantity(double pQ) {
02255     soldQuantity = pQ;
02256   }
02257 
02258   void setProfit(double pD) {
02259     profit = pD;
02260   }
02261 
02262   double getProfit() {
02263     return profit;
02264   }
02265 
02266   @Pre(expr = "de.pik.lagom.toolbox.math.FloatMath.approxZero(_this.money)", lang = "groovy")
02267   void setMoney(double pMoney) {
02268     money = pMoney;
02269   }
02270 
02271   public double getTargetEmployment() {
02272     return targetEmployment;
02273   }
02274 
02275   public double getLaborCapacity() {
02276     return laborCapacity;
02277   }
02278 
02279   public void setLaborCapacity(double pRecruitmentEfficiency) {
02280     laborCapacity = pRecruitmentEfficiency;
02281   }
02282 
02283   Suppliers[] getSuppliers() {
02284     return suppliers;
02285   }
02286 
02287   void setOwner(Household pOwner) {
02288     owner = pOwner;
02289   }
02290 
02291   Household getOwner() {
02292     return owner;
02293   }
02294 
02295   double getDesiredProduction() {
02296     return desiredProduction;
02297   }
02298 
02299   void setDesiredProduction(double dQ) {
02300     desiredProduction = dQ;
02301   }
02302 
02303   double getDividend() {
02304     return dividend;
02305   }
02306 
02307   double[] getFixedCapital() {
02308     return fixedCapital;
02309   }
02310 
02311   double getWage() {
02312     return wage;
02313   }
02314 
02315   public Firm.Probe getProbe() {
02316     return probe;
02317   }
02318 
02319   WorkContract getWorkContractForWorker(Household pWorker) {
02320     return workerList.get(pWorker);
02321   }
02322 
02323   boolean hasWorkContract(WorkContract pWorkContract) {
02324     return workerList.containsValue(pWorkContract);
02325   }
02326 
02327   public double[] getCirculatingInputCoefficients() {
02328     return circulatingInputCoefficients;
02329   }
02330 
02331   public double[] getFixedInputCoefficients() {
02332     return fixedInputCoefficients;
02333   }
02334 
02335   public double[] getInitialCirculatingInputCoefficients() {
02336     return initialCirculatingInputCoefficients;
02337   }
02338 
02339   public double[] getInitialFixedInputCoefficients() {
02340     return initialFixedInputCoefficients;
02341   }
02342 
02343   public double getProducedQuantity() {
02344     return producedQuantity;
02345   }
02346 
02347   public double getMaxProductionFromFixed() {
02348     return calcMaxProductionFromFixed(fixedCapital);
02349   }
02350 
02351   public double getMoney() {
02352     return money;
02353   }
02354 
02355   public double getDebt() {
02356     return debt;
02357   }
02358 
02359   public double getIntermediaryConsumptionValue() {
02360     return intermediaryConsumptionValue;
02361   }
02362 
02363   public double getSalesValue() {
02364     return salesValue;
02365   }
02366 
02367   public void setSalesValue(double pSalesValue) {
02368     salesValue = pSalesValue;
02369   }
02370 
02371   public double getInvestmentValue() {
02372     return investmentValue;
02373   }
02374 
02375   public double getWagesPaid() {
02376     return wagesPaid;
02377   }
02378 
02379   public double getInterestsOnDebt() {
02380     return interestsOnDebt;
02381   }
02382 
02383   public double getDebtVariation() {
02384     return debtVariation;
02385   }
02386 
02387   public FirmInitValues getInitValues() {
02388     return initValues;
02389   }
02390 
02391   public double getCosts() {
02392     return costs;
02393   }
02394 
02395   public double getMoneyVariation() {
02396     return moneyVariation;
02397   }
02398 
02399   public void setCosts(double pCosts) {
02400     costs = pCosts;
02401   }
02402 
02403   public void setIntermediaryConsumptionValue(double pIntermediaryConsumptionValue) {
02404     intermediaryConsumptionValue = pIntermediaryConsumptionValue;
02405   }
02406 
02407   public void setInvestmentValue(double pInvestmentValue) {
02408     investmentValue = pInvestmentValue;
02409   }
02410 
02411   public ProductionFunction getProductionFunction() {
02412     return productionFunction;
02413   }
02414 
02415   public void setCirculatingInputCoefficients(double[] pCirculatingInputCoefficients) {
02416     circulatingInputCoefficients = pCirculatingInputCoefficients;
02417   }
02418 
02419   public void setFixedInputCoefficients(double[] pFixedInputCoefficients) {
02420     fixedInputCoefficients = pFixedInputCoefficients;
02421   }
02422 
02423   public double getSoldQuantity() {
02424       return soldQuantity;
02425   }
02426 
02427   public double[] getCirculatingCapital() {
02428     return circulatingCapital;
02429   }
02430 
02431   public double getProfitRate() {
02432     return profitRate;
02433   }
02434 
02435   public double getLaborInputCoefficient() {
02436     return laborInputCoefficient;
02437   }
02438 
02439   public void setLaborInputCoefficient(double pLaborInputCoefficient) {
02440     laborInputCoefficient = pLaborInputCoefficient;
02441   }
02442 
02443   public double getInitialLaborInputCoefficient() {
02444     return initialLaborInputCoefficient;
02445   }
02446 
02447   public void setInitialCirculatingInputCoefficients(double[] pInitialCirculatingInputCoefficients) {
02448     initialCirculatingInputCoefficients = pInitialCirculatingInputCoefficients;
02449   }
02450 
02451   public void setInitialFixedInputCoefficients(double[] pInitialFixedInputCoefficients) {
02452     initialFixedInputCoefficients = pInitialFixedInputCoefficients;
02453   }
02454 
02455   public void setInitialLaborInputCoefficient(double pInitialLaborInputCoefficient) {
02456     initialLaborInputCoefficient = pInitialLaborInputCoefficient;
02457   }
02458 
02459   public double getElasticity(){
02460     return productionSector.getInitProductionElasticity();
02461   }
02462   
02463   public double getWageReference() {
02464     return wageReference;
02465   }
02466 
02467   public double getMarkUp() {
02468     return markUp;
02469   }
02470 
02471   public void setMarkUp(double pMarkUp) {
02472     markUp = pMarkUp;
02473   }
02474 
02475   public void setPrice(double pPrice) {
02476     price = pPrice;
02477   }
02478 
02479   public double getRateProductionUp() {
02480     return rateProductionUp;
02481   }
02482   
02483   public int getId() {
02484     return id;
02485   }
02486 
02487   public int getPeriodCreated() {
02488     return periodCreated;
02489   }
02490     
02491   public double getBenchmarkDemand(Sector lSector){
02492     return (getDemandCirculating(desiredProduction)[lSector.getArrayIndex()]+
02493         getDemandFixed(desiredProduction)[lSector.getArrayIndex()]);
02494   }
02495 
02496   public Suppliers getSuppliers(Sector lSector) {
02497     return suppliers[lSector.getArrayIndex()];
02498   }
02499   
02500   public double[] getRationing() {
02501     return rationing;
02502   }
02503 
02504   public boolean[] getIsInvest() {
02505     return isInvest;
02506   }
02507 
02508   public void setIsInvest(int pIndex, boolean pIsInvest) {
02509     isInvest[pIndex] = pIsInvest;
02510   }
02511 
02512 
02513   public void setDebt(double pDebt) {
02514     debt = pDebt;
02515   }
02516 
02517   public void setWage(double pWage) {
02518     wage = pWage;
02519   }
02520 
02521   public void setInventory(double pInventory) {
02522     inventory = pInventory;
02523   }
02524 
02525   public void setCirculatingCapital(int pIndex,double pCirculatingCapital) {
02526     circulatingCapital[pIndex] = pCirculatingCapital;
02527   }
02528 
02529   public void setFixedCapital(int pIndex,double pFixedCapital) {
02530     fixedCapital[pIndex] = pFixedCapital;
02531   }
02532   
02533   
02534   public double getUnitCost(){
02535     double lUnitCost =0.0;    
02536     lUnitCost +=wage*laborInputCoefficient/productionSector.getLaborProductivity();
02537     for (final Sector lSector : foundation.getSectorList()) {
02538       final int lSectorIndex = lSector.getArrayIndex();
02539       final double lPrice = lSector.getStats().getAverageTradePrice();
02540       lUnitCost += lPrice* circulatingInputCoefficients[lSectorIndex];
02541       lUnitCost +=lPrice*fixedInputCoefficients[lSectorIndex]*
02542       productionSector.getInitFixedCapitalDepreciationRate(lSectorIndex);
02543     }
02544     return lUnitCost;
02545   }
02546 
02547   public double getSalesTrendForecast() {
02548     return salesTrendForecast;
02549   }
02550 
02551   public void setSalesTrendForecast(double pSalesTrendForecast) {
02552     salesTrendForecast = pSalesTrendForecast;
02553   }
02554 
02555   public double getSalesForecast() {
02556     return salesForecast;
02557   }
02558 
02559   public void setSalesForecast(double pSalesForecast) {
02560     salesForecast = pSalesForecast;
02561   }
02562 
02563   public double getProductionGap() {
02564     return productionGap;
02565   }
02566 
02567   public void setProductionGap(double pProductionGap) {
02568     productionGap = pProductionGap;
02569   }
02570 
02571   public double getBenchmarkCosts() {
02572     return benchmarkCosts;
02573   }
02574 
02575   public double getInitMinimalCapacity(){
02576     double[] lFixed = new double[foundation.getNumSectors()];
02577     final double lGrowthRate = productionSector.getInitGrowthRate();
02578     for (int iSector=0; iSector<foundation.getNumSectors(); iSector++){
02579       if (productionSector.getInitCapitalStock(iSector) >0){
02580         final double lDepRate= productionSector.getInitFixedCapitalDepreciationRate( iSector);
02581         final double lFactor = (1+lGrowthRate)/(1-lDepRate);
02582         final double lPeriodicity=productionSector.getInvestmentPeriodicity( iSector);
02583         lFixed[iSector]= Math.pow(lFactor,lPeriodicity)*invProdFuncFixed(desiredProduction)[ iSector];
02584       }
02585       else{
02586         lFixed[iSector]=0;
02587       }
02588     }
02589     final double lMinCapacity=1/calcMaxProductionFromFixed(lFixed);
02590     return lMinCapacity;
02591   }
02592   
02593   public double getObservedSuppliersQuotient(){
02594     return initValues.getObservedFirmsQuotient();
02595   }
02596   
02597 }
02598 
02600 // EOF

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