Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Parameters class in solver #1389

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
104 changes: 71 additions & 33 deletions HARK/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1219,47 +1219,85 @@
A list of one period solutions for one "cycle" of the AgentType's
microeconomic model.
"""
# Calculate number of periods per cycle, defaults to 1 if all variables are time invariant
if len(agent.time_vary) > 0:
# name = agent.time_vary[0]
# T = len(eval('agent.' + name))
T = len(agent.__dict__[agent.time_vary[0]])
else:
T = 1

solve_dict = {parameter: agent.__dict__[parameter] for parameter in agent.time_inv}
solve_dict.update({parameter: None for parameter in agent.time_vary})
# Check if the agent has a 'Parameters' attribute of the 'Parameters' class
# if so, take advantage of it. Else, use the old method
if hasattr(agent, "params") and isinstance(agent.params, Parameters):
T = agent.params._length

Check warning on line 1226 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1226

Added line #L1226 was not covered by tests

# Initialize the solution for this cycle, then iterate on periods
solution_cycle = []
solution_next = solution_last
# Initialize the solution for this cycle, then iterate on periods
solution_cycle = []
solution_next = solution_last

Check warning on line 1230 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1229-L1230

Added lines #L1229 - L1230 were not covered by tests

cycles_range = [0] + list(range(T - 1, 0, -1))
for k in range(T - 1, -1, -1) if agent.cycles == 1 else cycles_range:
# Update which single period solver to use (if it depends on time)
if hasattr(agent.solve_one_period, "__getitem__"):
solve_one_period = agent.solve_one_period[k]
else:
solve_one_period = agent.solve_one_period
cycles_range = [0] + list(range(T - 1, 0, -1))
for k in range(T - 1, -1, -1) if agent.cycles == 1 else cycles_range:

Check warning on line 1233 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1232-L1233

Added lines #L1232 - L1233 were not covered by tests
# Update which single period solver to use (if it depends on time)
if hasattr(agent.solve_one_period, "__getitem__"):
solve_one_period = agent.solve_one_period[k]

Check warning on line 1236 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1235-L1236

Added lines #L1235 - L1236 were not covered by tests
else:
solve_one_period = agent.solve_one_period

Check warning on line 1238 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1238

Added line #L1238 was not covered by tests

if hasattr(solve_one_period, "solver_args"):
these_args = solve_one_period.solver_args

Check warning on line 1241 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1240-L1241

Added lines #L1240 - L1241 were not covered by tests
else:
these_args = get_arg_names(solve_one_period)

Check warning on line 1243 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1243

Added line #L1243 was not covered by tests

# Make a temporary dictionary for this period
temp_pars = agent.params[k]
temp_dict = {

Check warning on line 1247 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1246-L1247

Added lines #L1246 - L1247 were not covered by tests
name: solution_next if name == "solution_next" else temp_pars[name]
for name in these_args
}

if hasattr(solve_one_period, "solver_args"):
these_args = solve_one_period.solver_args
# Solve one period, add it to the solution, and move to the next period
solution_t = solve_one_period(**temp_dict)
solution_cycle.insert(0, solution_t)
solution_next = solution_t

Check warning on line 1255 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1253-L1255

Added lines #L1253 - L1255 were not covered by tests

else:
# Calculate number of periods per cycle, defaults to 1 if all variables are time invariant
if len(agent.time_vary) > 0:
# name = agent.time_vary[0]
# T = len(eval('agent.' + name))
T = len(agent.__dict__[agent.time_vary[0]])
else:
these_args = get_arg_names(solve_one_period)
T = 1

solve_dict = {
parameter: agent.__dict__[parameter] for parameter in agent.time_inv
}
solve_dict.update({parameter: None for parameter in agent.time_vary})

# Initialize the solution for this cycle, then iterate on periods
solution_cycle = []
solution_next = solution_last

cycles_range = [0] + list(range(T - 1, 0, -1))
for k in range(T - 1, -1, -1) if agent.cycles == 1 else cycles_range:
# Update which single period solver to use (if it depends on time)
if hasattr(agent.solve_one_period, "__getitem__"):
solve_one_period = agent.solve_one_period[k]

Check warning on line 1279 in HARK/core.py

View check run for this annotation

Codecov / codecov/patch

HARK/core.py#L1279

Added line #L1279 was not covered by tests
else:
solve_one_period = agent.solve_one_period

if hasattr(solve_one_period, "solver_args"):
these_args = solve_one_period.solver_args
else:
these_args = get_arg_names(solve_one_period)

# Update time-varying single period inputs
for name in agent.time_vary:
if name in these_args:
solve_dict[name] = agent.__dict__[name][k]
solve_dict["solution_next"] = solution_next
# Update time-varying single period inputs
for name in agent.time_vary:
if name in these_args:
solve_dict[name] = agent.__dict__[name][k]
solve_dict["solution_next"] = solution_next

# Make a temporary dictionary for this period
temp_dict = {name: solve_dict[name] for name in these_args}
# Make a temporary dictionary for this period
temp_dict = {name: solve_dict[name] for name in these_args}

# Solve one period, add it to the solution, and move to the next period
solution_t = solve_one_period(**temp_dict)
solution_cycle.insert(0, solution_t)
solution_next = solution_t
# Solve one period, add it to the solution, and move to the next period
solution_t = solve_one_period(**temp_dict)
solution_cycle.insert(0, solution_t)
solution_next = solution_t

# Return the list of per-period solutions
return solution_cycle
Expand Down