/// <summary> /// Records the outcome of implementing a decision, observing reported costs, and /// updating the original decision. Repeats this process until a terminal outcome /// results. See remarks. /// </summary> /// <param name="costsys"></param> /// <param name="firmID"></param> /// <param name="costSysID"></param> /// <param name="startingDecision"></param> /// <param name="endingDecision"></param> /// <param name="stopCode"></param> /// <remarks>Assume the firm implements the decision startingDecision. Upon /// doing so, it will observe total resource consumption.It will then /// allocate resources to cost pools, as per the B parameter of the cost /// system, choose drivers as per the D parameter of the cost system, /// and then allocate resources to cost objects and compute reported costs. /// The reported costs are returned as PC_R. Upon observing the /// reported costs, the firm may wish to update its original decision.When /// it implements the updated decision, costs will change again.The outcome /// of this process will either be an equilibrium decision (fixed point), or /// a cycle of decisions.</remarks> public static void LogCostSysLoop( CostSys costsys, int firmID, int costSysID, RowVector startingDecision, RowVector endingDecision, CostSystemOutcomes stopCode) { sb_CostSys_LOOP.AppendFormat( "{0},{1},{2},{3},{4},{5},{6},{7},{8}", firmID, costSysID, costsys.P, costsys.A, costsys.R, startingDecision.ToCSVString(false), endingDecision.ToCSVString(false), stopCode, Environment.NewLine ); }
/// <summary> /// Assuming the firm implements decision DECF0, this method computes /// reported costs for this cost system, which are used to compute the firm's updated decision. /// It iterates using the updated decision as the new starting decision until a terminal outcome /// (e.g. equilibrium, cycle) is reached. /// </summary> /// <param name="ip">The current InputParameters object</param> /// <param name="DECF0">The starting decision.</param> /// <returns>Returns the outcome of iterations and the final decision.</returns> public (CostSystemOutcomes stopCode, RowVector DECF1) EquilibriumCheck(InputParameters ip, RowVector DECF0) { #region Make local copies of firm-level variables ColumnVector MXQ = this.firm.MXQ; RowVector SP = this.firm.SP; #endregion // The initial vector of production quantities, given // starting decision DECF0 ColumnVector q0 = MXQ.ewMultiply(DECF0); // A list of past decisions made during the iteration process. // If a decision appears twice on this list, then a cycle exists. List <RowVector> pastDecisions = new List <RowVector> { DECF0 }; // The "next" decision that the firm would make. Assume the firm // starts with DECF0, computes resulting resource consumption, // and reported costs (through the cost system). Given reported // costs, it updates its decision to DECF1. RowVector DECF1; bool foundThisDecisionBefore; double MAR_DROP = 1.0 - ip.HYSTERESIS; double MAR_MAKE = 1.0 + ip.HYSTERESIS; CostSystemOutcomes stopCode = CostSystemOutcomes.Unassigned; bool done; do { RowVector PC_R = CalcReportedCosts(ip, DECF0); if (PC_R.Contains(double.NaN)) { DECF1 = PC_R.Map(x => double.NaN); } else { double[] MAR = PC_R.Zip(SP, (pc_r, sp) => sp / pc_r).ToArray(); var decf1 = MAR.Zip(q0, (mar, q) => (q > 0.0) ? ((mar <= MAR_DROP) ? 0.0 : 1.0) : ((mar > MAR_MAKE) ? 1.0 : 0.0)); DECF1 = new RowVector(decf1.ToList()); } ColumnVector q1 = MXQ.ewMultiply(DECF1); if (!(foundThisDecisionBefore = pastDecisions.Contains(DECF1))) { pastDecisions.Add(DECF1); } //double ExpectedCosts = PC_R * q1; //double TCF0 = this.firm.CalcTotCosts(q1); done = true; //if (q1 == q0) { if (DECF1 == DECF0) { stopCode = CostSystemOutcomes.Equilibrium; } else if (q1.TrueForAll(qty => qty == 0.0)) { stopCode = CostSystemOutcomes.ZeroMix; } else if (foundThisDecisionBefore) { stopCode = CostSystemOutcomes.Cycle; } else if (DECF1.Contains(double.NaN)) { stopCode = CostSystemOutcomes.NaN; } else { done = false; } if (!done) { DECF0 = DECF1; q0 = q1; } } while (!done); return(stopCode, DECF1); }