## ams_version=1.0 Model Main_Life_Cycle_Consumption_Model { Comment: { "Keywords: Utility Function, Discount Factor, Present Value, Future Value, Nonlinear Programming, Nonlinear Solvers, Curve Object." } Section Model_Section { DeclarationSection Input_Parameters { Set Time { SubsetOf: Integers; Text: "Defines the time elements"; Index: t; Definition: ElementRange(1, TotalTimePeriods+1); } Parameter TotalTimePeriods { Text: "Total number of periods (between 2 and 50)"; Range: { {2..50} } InitialData: 15; } Parameter InterestRate { Text: "Interest rate"; InitialData: 0.10; } Parameter DiscountFactor { Text: "Discount factor"; InitialData: 0.96; } Parameter Wages { IndexDomain: t | t <= TotalTimePeriods; Text: "We use a common parabolic pattern of life cycle earnings"; Definition: [TotalTimePeriods - t] * t / TotalTimePeriods; } Parameter PresentValueWages { Text: "The present value of wages income"; Definition: Sum(t, Wages(t)*(1+InterestRate)^(-t+1)); } } DeclarationSection Lower_Bounds { Parameter ConsumptionLowerBound { Text: "Lower bound on consumption"; Definition: 0.0001; } Parameter LaborLowerBound { Definition: 0.0001; } Parameter MinimumAsset { Definition: { if Allow_Borrowing = 1 then UserMinAsset else 0 endif; } Comment: "A negative amount denotes that borrowing is allowed."; } } DeclarationSection Math_Model { Variable Labor { IndexDomain: t | t <= TotalTimePeriods; Text: "Labor "; Range: [LaborLowerBound, inf); Comment: "Note that the lower bound for Labor is included in the range. It is also possible but less efficient to create an extra constraint for this."; } Variable Assets { IndexDomain: t | t > 1; Text: "Assets"; Range: [MinimumAsset, inf); Definition: (1+InterestRate)*(Assets(t-1) + Wages(t-1)*Labor(t-1) - Consumption(t-1)); } Constraint TerminalAssetsConstraint { Text: "Nonnegative terminal Assets including Labor earnings"; Definition: Assets(TotalTimePeriods + 1) >=0; Comment: { "Terminal Wealth (Assets in the period after TotalTimePeriods) should not be negative: all debts must be re-paid" } } Variable Consumption { IndexDomain: t | t <= TotalTimePeriods; Text: "Consumption "; Range: [ConsumptionLowerBound, inf); Comment: { "Note that the lower bound is included in the range. It is also possible but less efficient to create an extra constraint for this." } } Variable PresentValueConsumption { Text: "Present value of consumption"; Range: [0, PresentValueWages]; Definition: Sum(t, Consumption(t)*(1+InterestRate)^(-t+1)); Comment: "Note that the upper bound (PresentValueWages) is used to set the range for PresentValueConsumption."; } Variable Utility { IndexDomain: t | t <= TotalTimePeriods; Text: "The utility function defined over consumption and labor"; Definition: { if SelectedUtilityFunction='Exp' then -Exp(-Consumption(t)) - Labor(t)^2 else Sqrt(Consumption(t)) - Labor(t)^2 endif } } Variable Life_Cycle_Utility { Text: "The life-cycle utility function objective"; Definition: Sum(t, DiscountFactor^(-1+t) * Utility(t) ); Comment: "Only one Utility variable will have a value"; } MathematicalProgram ConsumptionModel_Exp { Objective: Life_Cycle_Utility; Direction: maximize; Constraints: AllConstraints; Variables: AllVariables; Type: NLP; Comment: { "This is the Mathematical program that ties everything together: - The variable Life_Cycle_Utility is chosen as the objective function to be maximized, - All Constraints and all Variables that are present in the model tree are taken into account." } } } } Section GUI_Part { DeclarationSection GUI_Declaration_Section { Parameter Allow_Borrowing; Set AvailableUtilityFunctions { Definition: { data { 'Sqrt', 'Exp' } } } ElementParameter SelectedUtilityFunction { Range: AvailableUtilityFunctions; InitialData: 'Sqrt'; } Set SubsetTime { SubsetOf: Time; Text: "Defines the time elements to be displayed in the graphs"; Index: ct; Definition: Time- last(time); } Parameter UserMinAsset { InitialData: -0.5; } ElementParameter ACase { Range: AllCases; } } DeclarationSection Solver_Declaration_Section { Set AvailableNLPSolvers { SubsetOf: AllSolvers; Comment: "The performance and solution of the solvers differs in this model"; } ElementParameter SelectedNLPSolver { Range: AvailableNLPSolvers; } } } Procedure MainInitialization { Body: { AvailableNLPSolvers := {IndexSolvers | FindString( FormatString( "%e",IndexSolvers), "CONOPT" ) or FindString( FormatString( "%e",IndexSolvers), "BARON" ) or FindString( FormatString( "%e",IndexSolvers), "KNITRO" ) or FindString( FormatString( "%e",IndexSolvers), "MINOS" ) or FindString( FormatString( "%e",IndexSolvers), "SNOPT" ) }; SelectedNLPSolver := last({IndexSolvers | FindString( FormatString( "%e",IndexSolvers), "BARON" )}); } } Procedure MainExecution { Body: { empty Utility, Assets, Labor; Assets(1):=0; solve ConsumptionModel_Exp where solver = SelectedNLPSolver; } } Procedure MainTermination { Body: { return 1; } } }