Runnig the first script returns multiple (nine) same functions. -> This turned out to be the kernel's problem. Another bug of replacing function's name left in the comment below: #13 (comment)
original name stan variable name is stock
--------------------------------------------------------------------
Supply Start Rate Desired supply_start_rate_desired
Order Fulfilment Ratio order_fulfilment_ratio
Safety Stock Coverage safety_stock_coverage
Order Fulfillment Rate order_fulfillment_rate
Backlog Adj Rate Desired backlog_adj_rate_desired
Supply Line Desired supply_line_desired
Critical Ratio critical_ratio
Backlog Desired backlog_desired
Max Shipment Rate max_shipment_rate
Shipment Rate shipment_rate
Demand Rate Adj Rate demand_rate_adj_rate
Inventory Safety Time Desired inventory_safety_time_desired
Supply Rate Desired supply_rate_desired
Demand Rate demand_rate
Forecasted Demand Rate forecasted_demand_rate V
Inventory Adj Time inventory_adj_time
Supply Line Adj Time supply_line_adj_time
Shipment Lead Time shipment_lead_time
Backlog Adj Time backlog_adj_time
Inventory Adj Rate inventory_adj_rate
Supply Line Adj Rate supply_line_adj_rate
Backlog backlog V
Order Rate order_rate
Supply Rate supply_rate
Inventory Desired inventory_desired
Demand Adj Time demand_adj_time
Inventory inventory V
Supply Lead Time supply_lead_time
Supply Start Rate supply_start_rate
Supply Line supply_line V
FINAL TIME final_time
INITIAL TIME initial_time
SAVEPER saveper
TIME STEP time_step
functions {
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
real lookupFunc_0(real x){
# x (0, 2) = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.0)
# y (0, 1) = (0.0, 0.2, 0.4, 0.58, 0.73, 0.85, 0.93, 0.97, 0.99, 1.0, 1.0, 1.0)
real slope;
real intercept;
if(x <= 0.2)
intercept = 0.0;
slope = (0.2 - 0.0) / (0.2 - 0.0);
return intercept + slope * (x - 0.0);
else if(x <= 0.4)
intercept = 0.2;
slope = (0.4 - 0.2) / (0.4 - 0.2);
return intercept + slope * (x - 0.2);
else if(x <= 0.6)
intercept = 0.4;
slope = (0.58 - 0.4) / (0.6 - 0.4);
return intercept + slope * (x - 0.4);
else if(x <= 0.8)
intercept = 0.58;
slope = (0.73 - 0.58) / (0.8 - 0.6);
return intercept + slope * (x - 0.6);
else if(x <= 1.0)
intercept = 0.73;
slope = (0.85 - 0.73) / (1.0 - 0.8);
return intercept + slope * (x - 0.8);
else if(x <= 1.2)
intercept = 0.85;
slope = (0.93 - 0.85) / (1.2 - 1.0);
return intercept + slope * (x - 1.0);
else if(x <= 1.4)
intercept = 0.93;
slope = (0.97 - 0.93) / (1.4 - 1.2);
return intercept + slope * (x - 1.2);
else if(x <= 1.6)
intercept = 0.97;
slope = (0.99 - 0.97) / (1.6 - 1.4);
return intercept + slope * (x - 1.4);
else if(x <= 1.8)
intercept = 0.99;
slope = (1.0 - 0.99) / (1.8 - 1.6);
return intercept + slope * (x - 1.6);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 1.8);
return intercept + slope * (x - 1.8);
else if(x <= 2.0)
intercept = 1.0;
slope = (1.0 - 1.0) / (2.0 - 2.0);
return intercept + slope * (x - 2.0);
}
# Begin ODE declaration
vector vensim_func(real time, vector outcome, real demand ){
real forecasted_demand_rate = outcome[1];
real backlog = outcome[2];
real inventory = outcome[3];
real supply_line = outcome[4];
real demand_adj_time = 3;
real inventory_adj_time = 3;
real critical_ratio = 0.8;
real safety_stock_coverage = 3 * critical_ratio;
real shipment_lead_time = 3;
real inventory_safety_time_desired = shipment_lead_time + safety_stock_coverage;
real inventory_desired = forecasted_demand_rate * inventory_safety_time_desired;
real inventory_adj_rate = inventory_desired - inventory / inventory_adj_time;
real supply_rate_desired = forecasted_demand_rate + inventory_adj_rate;
real supply_line_adj_time = 3;
real supply_lead_time = 3;
real supply_line_desired = forecasted_demand_rate * supply_lead_time;
real supply_line_adj_rate = supply_line_desired - supply_line / supply_line_adj_time;
real supply_start_rate_desired = fmax(0,supply_rate_desired + supply_line_adj_rate);
real supply_start_rate = supply_start_rate_desired;
real demand_rate = random_normal(0,200,100,10,1111);
real demand_rate_adj_rate = demand_rate - forecasted_demand_rate / demand_adj_time;
real forecasted_demand_rate_dydt = demand_rate_adj_rate;
real backlog_desired = 0;
real supply_rate = supply_line / supply_lead_time;
real backlog_adj_time = 3;
real backlog_adj_rate_desired = backlog - backlog_desired / backlog_adj_time;
real max_shipment_rate = inventory / shipment_lead_time;
real order_fulfilment_ratio = fmin(1,max_shipment_rate / backlog_adj_rate_desired + 0.001);
real shipment_rate = backlog_adj_rate_desired * order_fulfilment_ratio;
real order_fulfillment_rate = shipment_rate;
real order_rate = demand_rate;
real supply_line_dydt = supply_start_rate - supply_rate;
real backlog_dydt = order_rate - order_fulfillment_rate;
real inventory_dydt = supply_rate - shipment_rate;
return {forecasted_demand_rate_dydt, backlog_dydt, inventory_dydt, supply_line_dydt};
}
}
data{
}
transformed data{
}
parameters{
}
transformed parameters {
real forecasted_demand_rate_initial = random_normal(0,200,100,10,1111);
real backlog_initial = 0;
real inventory_initial = random_normal(0,200,100,10,1111) * 3 + 3 * 0.8;
real supply_line_initial = random_normal(0,200,100,10,1111) * 3;
vector[4] initial_outcome = {forecasted_demand_rate_initial, backlog_initial, inventory_initial, supply_line_initial};
array[] vector integrated_result = integrate_ode_rk45(vensim_func, initial_outcome, initial_time, times, demand);
}
model{
}
generated quantities{
}