Use POMDPs to solve a simple routine economics problem. #351
-
Beta Was this translation helpful? Give feedback.
Replies: 20 comments 17 replies
-
I am not sure, whether I'm understanding the problem. Maybe you can clarify:
|
Beta Was this translation helpful? Give feedback.
-
@lassepe let me rewrite it w/ different notation: |
Beta Was this translation helpful? Give feedback.
-
I guess that clarified things a little bit for me but still, I feel like this is missing a constraint. Are you maybe implicitly assuming that k must be non-negative for all time? |
Beta Was this translation helpful? Give feedback.
-
Update: Previous comment: Here is how to do this w/ QuantEcon's solver: using QuantEcon, SparseArrays;
α=.65; β=.95; f(k)=k.^α; u_log(x)= x > 0. ? log(x) : -Inf ;
n=500; grid = range(1e-6, 2.0, length = n);
C = f.(grid) .- grid'
#
coord = repeat(collect(1:n), 1, n)
s_indices = coord[:]
a_indices = transpose(coord)[:]
L = length(a_indices)
#
R = u_log.(C[:])
Q = spzeros(L, n) # Q = zeros(L, n)
for i in 1:L
Q[i, a_indices[i]] = 1
end
ddp = DiscreteDP(R, Q, β, s_indices, a_indices)
r_pfi = solve(ddp, PFI)
r_mpfi = solve(ddp, MPFI)
r_vfi = solve(ddp, VFI) Update: here is how to simulate #
k_init = 0.1
k_init_ind = findfirst(collect(grid) .≥ k_init)
k_path_ind = simulate(r_pfi.mc, 25, init=k_init_ind)
k_path = grid[k_path_ind.+1] |
Beta Was this translation helpful? Give feedback.
-
Thanks for posting! It's good to get problems from different fields. It would be great to make this package easier to pick up for economists! I think something like this works: using POMDPs
using QuickPOMDPs: QuickMDP
using POMDPModelTools: Deterministic
using DiscreteValueIteration
const n = 500
const α = 0.65
const β = 0.95
const max_k = 2.0
const states = range(1e-6, max_k, length=n)
ceil_state(k) = states[searchsortedfirst(states, k)] # there is probably a better way, but this minimized thinking
valid_actions() = range(1e-7, max_k^α, length=100) # all of the possible actions
valid_actions(k) = filter(<(k^α), valid_actions()) # all of the valid actions for k
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (k, c) -> Deterministic(ceil_state(k^α - c)),
reward = (k, c) -> log(c),
discount = β
)
solver = SparseValueIterationSolver(verbose=true)
policy = solve(solver, m)
@show value(policy, first(states))
ω = α*β
A1 = α/(1.0-ω)
A0 = ((1-ω)*log(1-ω) + ω*log(ω))/((1-ω)*(1-β))
@show A0 + A1 * log(first(states)) You may be able to do better with GlobalApproximationValueIteration or LocalApproximationValueIteration, but I did not have time to try. (@Shushman this might be an interesting toy problem to try on those) |
Beta Was this translation helpful? Give feedback.
-
@zsunberg thanks it works well!!!
|
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Hi @azev77, did you figure out your questions?
|
Beta Was this translation helpful? Give feedback.
-
Before I forget: |
Beta Was this translation helpful? Give feedback.
-
https://github.com/RoboticExplorationLab/TrajectoryOptimization.jl and related projects might be of interest for continuous control problems. They integrate with IPOpt etc appropriately. |
Beta Was this translation helpful? Give feedback.
-
6: Currently POMDPs.jl does not have any continuous-time solvers :/ I think it would take some serious design work to fit that in, and I think it would probably be worth creating another package. |
Beta Was this translation helpful? Give feedback.
-
@zsunberg I spent a lot trying to figure out the docs w/ no luck on this. Here is the discrete Grid POMDP code: using POMDPs
using QuickPOMDPs: QuickMDP
using POMDPModelTools: Deterministic
using DiscreteValueIteration
α = 0.65;
"states:"
min_s = eps(); max_s = 2.0; n_s = 200;
states = range(min_s, max_s, length=n_s)
ceil_state(s) = states[searchsortedfirst(states, s)]
"Transition:" # ṡ=μ(s,a) ⟺ a=μ_inv(s,ṡ)
μ(s,a;α=α) = (s)^α - a
μ_inv(s,sp;α=α) = (s)^α - sp
"actions:"
min_a = eps(); max_a = μ_inv(max_s,0.0); n_a = 400; # keeps a≥0
valid_actions() = range(min_a, max_a, length=n_a) # possible actions any state.
valid_actions(s) = filter(<(μ_inv(s,0)), valid_actions()) # valid actions @ state=s
"reward:"
r(s,a) = log(a)
"discount:"
β = 0.95
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( ceil_state( μ(s,a) ) ),
reward = (s, a) -> r(s,a),
discount = β
)
solver = SparseValueIterationSolver()
sol = solve(solver, m) To be clear, I have routine parsimonious code that does this, but I'd really like to use POMDPs.jl # 1: discrete VFI
struct MDP γ; S; A; T; R end
BE(P,V,s,a) = P.R(s,a) + P.γ*sum(P.T(s,a,sp)*V[i] for (i,sp) ∈ enumerate(P.S))
policy(s; P, V) = findmax([BE(P, V, s, a) for a in P.A(s)])[end]
function MDP_VFI(P::MDP, k_max::Int64, V)
for k = 1:k_max
Vp = [maximum(BE(P, V, s, a) for a ∈ P.A(s)) for s ∈ P.S]
V = Vp
end
return V
end
γ=0.95;
ns=40; na=40;
S = [range(1e-6, 2.0, length=ns);]
A(s;na=na) = [range(1e-6, (s).^(.67), length=na);]
fsp(s) = S[searchsortedfirst(S, s)] # Closest s' in S
T(s,a,sp) = (sp == fsp(s^(.67) - a)) ? 1.0 : 0.0
R(s,a) = (1-0.95)*log(a);
P1 = MDP(γ, S, A, T, R)
V0 = [0.0 for s in P1.S]
@time V = MDP_VFI(P1, 50, V0)
# 2: Continuous approx VFI
using Interpolations, LinearAlgebra
approx(gr, val0) = LinearInterpolation(gr, val0, extrapolation_bc = Line())
#
struct MDP γ; S; A; T; R end
RHS(P,V,s,a) = P.R(s,a) + P.γ*V(T(s,a))
γ=0.95; ns=100; na=170;
S = [range(1e-2, 2.0, length=ns);]
A(s) = [range(1e-6, (s).^(.67), length=na);]
T(s,a) = s^(.67) - a
R(s,a) = log(abs(a)) # (1-0.95)*log(a)
P1 = MDP(γ, S, A, T, R)
#
function MDP_VFI(P::MDP, k_max::Int64, V)
for k = 1:k_max
v̂ = approx(P.S, V)
rhs = [ [RHS(P,v̂,s,a) for a ∈ P.A(s)] for s ∈ P.S ]
rhs = hcat(rhs...)
Vp = maximum(rhs, dims=1) |> vec
V = Vp
end
return V
end
#
V0 = [log(s) for s in P1.S]
V = MDP_VFI(P1, 50, V0) |
Beta Was this translation helpful? Give feedback.
-
I spent a bunch of time yesterday but couldn't figure out how to apply If we can figure this out I'd love to contribute an econ example like I did here: https://pulsipher.github.io/InfiniteOpt.jl/dev/examples/Optimal%20Control/consumption_savings/ In general I will try to write the doc example using generic optimal control notation & then apply a variety of solvers, both discrete grid & continuous grid. S: state grid I strongly believe an example w/ this kind of notation would make it much easier for new users to jump into POMDPs.jl. |
Beta Was this translation helpful? Give feedback.
-
Hey guys @zsunberg @Shushman. I think I got it to work on my MWE. I tried to further simplify my notation to follow the standard MDP notation: # Parameters for the Neoclassical Growth Model (NGM)
α = 0.65;
f(s;α=α) = (s)^α
a0(s) = f(s)
min_s = eps(); max_s = 2.0; n_s = 100;
min_a = eps(); max_a = a0(max_s); n_a = 100;
"states:"
states = range(min_s, max_s, length=n_s)
ceil_state(s) = states[searchsortedfirst(states, s)] # for discrete VFI
"actions:"
valid_actions() = range(min_a, max_a, length=n_a) # possible actions any state.
valid_actions(s) = filter(<(a0(s)), valid_actions()) # valid actions @ state=s
"Transition:"
μ(s,a) = f(s) - a
"reward:"
r(s,a) = log(a)
"discount:"
β = 0.95
using QuickPOMDPs: QuickMDP #QuickMDP()
using POMDPModelTools: Deterministic
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( ceil_state( μ(s,a) ) ),
reward = (s, a) -> r(s,a),
discount = β
)
# DiscreteValueIteration: Both work fast enough
using DiscreteValueIteration
s1 = DiscreteValueIteration.SparseValueIterationSolver()
s2 = DiscreteValueIteration.ValueIterationSolver()
@time sol1 = solve(s1, m)
@time sol2 = solve(s2, m)
value(sol1, states[2]), action(sol1, states[2])
value(sol2, states[2]), action(sol2, states[2])
#rewrite MDP w/o ceil_state() in transition.
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( μ(s,a) ),
reward = (s, a) -> r(s,a),
discount = β
)
# LocalApproximationValueIteration works, but currently slow!
using GridInterpolations
using LocalFunctionApproximation
using LocalApproximationValueIteration
grid = GridInterpolations.RectangleGrid(states, valid_actions(), ) #[0.0, 1.0])
interp = LocalFunctionApproximation.LocalGIFunctionApproximator(grid)
s4 = LocalApproximationValueIterationSolver(interp)
@time sol4 = solve(s4, m)
#190.477798 seconds (2.37 G allocations: 82.610 GiB, 6.87% gc time, 0.21% compilation time)
value(sol4, states[2]), action(sol4, states[2]) Now let's compare solutions from various MDP solvers w/ closed-forms: using Plots
ω = α*β
A1 = α/(1.0-ω)
A0 = ((1-ω)*log(1-ω) + ω*log(ω))/((1-ω)*(1-β))
# Value
plot(legend=:bottomright, title="Value Functions");
plot!(states[2:end], i->A0 + A1 * log(i), lab="closed form") # way off
plot!(states[2:end], i->value(sol1, i), lab="sol1")
plot!(states[2:end], i->value(sol2, i), lab="sol2")
plot!(states[2:end], i->value(sol4, i), lab="sol4")
# Policy
plot(legend=:bottomright, title="Policy Functions");
plot!(states[2:end], i -> (1-ω)*(i^α), lab="closed form") # way off
plot!(states[2:end], i -> action(sol1, i), lab="sol1")
plot!(states[2:end], i -> action(sol2, i), lab="sol2")
plot!(states[2:end], i -> action(sol4, i), lab="sol4")
# Simulation
Tsim=150; s0=states[2];
simcf = []; push!(simcf, s0);
for tt in 1:Tsim
tt==1 ? s = s0 : nothing
a = (1-ω)*(s^α)
sp = μ(s,a)
#sp = ceil_state(sp)
push!(simcf, sp)
s = sp
end
sim1 = []; push!(sim1, s0);
for tt in 1:Tsim
tt==1 ? s = s0 : nothing
#a = valid_actions()[sol1.policy[searchsortedfirst(states, s)]]
a = action(sol1, s)
sp = μ(s,a)
sp = ceil_state(sp)
push!(sim1, sp)
s = sp
end
sim4 = []; push!(sim4, s0);
for tt in 1:Tsim
tt==1 ? s = s0 : nothing
a = action(sol4, s)
sp = μ(s,a)
push!(sim4, sp)
s = sp
end
plot(legend=:bottomright, title="Simulation");
plot!(simcf, lab="closed form")
plot!(sim1, lab="sol1")
plot!(sim4, lab="sol4") Looks about right. Btw, I think I was able to solve using using MCTS
s3 = MCTS.MCTSSolver()
@time sol3 = solve(s3, m)
julia> value(sol3, states[4])
ERROR: State 0.06060606060606082 not present in MCTS tree.
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:33
[2] value(tr::MCTS.MCTSTree{Float64, Float64}, s::Float64)
@ MCTS C:\Users\azevelev\.julia\packages\MCTS\ww2qH\src\vanilla.jl:217
[3] value(planner::MCTSPlanner{QuickMDP{UUID("08e2dc8f-88bd-4faf-8290-5a9f3830c278"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#73#75", var"#74#76", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}}, Float64, Float64, MCTS.SolvedRolloutEstimator{POMDPPolicies.RandomPolicy{Random._GLOBAL_RNG, QuickMDP{UUID("08e2dc8f-88bd-4faf-8290-5a9f3830c278"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#73#75", var"#74#76", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}}, BeliefUpdaters.NothingUpdater}, Random._GLOBAL_RNG}, Random._GLOBAL_RNG}, s::Float64)
@ MCTS C:\Users\azevelev\.julia\packages\MCTS\ww2qH\src\vanilla.jl:211
[4] top-level scope
@ REPL[312]:1 Finally, I wasn't able to install julia>
(@v1.6) pkg> add GlobalApproximationValueIteration
Updating registry at `C:\Users\azevelev\.julia\registries\General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Resolving package versions...
ERROR: Unsatisfiable requirements detected for package CUDAapi [3895d2a7]:
CUDAapi [3895d2a7] log:
├─possible versions are: 0.5.0-4.0.0 or uninstalled
├─restricted by julia compatibility requirements to versions: uninstalled
└─restricted by compatibility requirements with Flux [587475ba] to versions: 1.1.0-1.2.0 — no versions left
└─Flux [587475ba] log:
├─possible versions are: 0.4.1-0.12.6 or uninstalled
├─restricted to versions * by an explicit requirement, leaving only versions 0.4.1-0.12.6
└─restricted by compatibility requirements with GlobalApproximationValueIteration [277f244e] to versions: 0.9.0
└─GlobalApproximationValueIteration [277f244e] log:
├─possible versions are: 0.2.2 or uninstalled
└─restricted to versions * by an explicit requirement, leaving only versions 0.2.2 To dos:
|
Beta Was this translation helpful? Give feedback.
-
I was actually trying to do the same. We solve a lot of very similar problem in economics and having a way of mapping the problem to POMDPs.jl would be great.
It works beautifully and implementing continuous states is very easy:
What I've been struggling with is with the stochastic case in which the problem is: It is the same thing but with an AR(1) process z multplying the production function in the constraint. In this case, the actions are deterministic and z is an exogenous stochastic variable. I am struggling to define the transition function. Ideally, I wanted to write something like:
Where I approximated the AR(1) by a Markov Matrix |
Beta Was this translation helpful? Give feedback.
-
I'll give it a try this week, it seems that the discrete solvers at least
do not yet handle multivariate distributions.
I tried a case in which the transition function would return a multivariate
Normal of 2 random variables and it would crash because of the pdf
function. I haven't checked yet the ImplicitDistribution from POMDPModelTools,
but it might be what I've been missing!
What I am really interested in is to use the deep learning solvers for a
bigger model, but first I am testing the basic cases to make sure I
understand what is going on.
Thanks!
…On Sat, Nov 20, 2021 at 6:50 PM Zachary Sunberg ***@***.***> wrote:
Depending on what solver you're using, you might just be able to use
ImplicitDistiribution. That will work, for example, if you're using
LocalApproximationValueIterationSolver for instance.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#351 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC7ILYYMG374VSJUHRK6MEDUNA66TANCNFSM5BR4IXMQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
It turns out that POMDPModelTools SparseCat function is precisely what I
needed.
Thanks!
On Sat, Nov 20, 2021 at 7:06 PM João Guilherme Santos Lazzaro <
***@***.***> wrote:
… I'll give it a try this week, it seems that the discrete solvers at least
do not yet handle multivariate distributions.
I tried a case in which the transition function would return a
multivariate Normal of 2 random variables and it would crash because of the
pdf function. I haven't checked yet the ImplicitDistribution from POMDPModelTools,
but it might be what I've been missing!
What I am really interested in is to use the deep learning solvers for a
bigger model, but first I am testing the basic cases to make sure I
understand what is going on.
Thanks!
On Sat, Nov 20, 2021 at 6:50 PM Zachary Sunberg ***@***.***>
wrote:
> Depending on what solver you're using, you might just be able to use
> ImplicitDistiribution. That will work, for example, if you're using
> LocalApproximationValueIterationSolver for instance.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <#351 (reply in thread)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AC7ILYYMG374VSJUHRK6MEDUNA66TANCNFSM5BR4IXMQ>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>
|
Beta Was this translation helpful? Give feedback.
-
Hi all, I'm solving a simple investment problem but not getting the correct solution. a_0(s;δ=δ) = δ*s
min_s = eps(); max_s = 2.0*K_SS; n_s = 200;
min_a = eps(); max_a = a_0(max_s); n_a = 400; # keeps a≥0
"states:"
states = range(min_s, max_s, length=n_s)
ceil_state(s) = states[searchsortedfirst(states, s)]
"actions:"
valid_actions() = range(min_a, max_a, length=n_a) # possible actions any state.
valid_actions(s) = filter(<(a_0(s)), valid_actions()) # valid actions @ state=s
"Transition:"
μ(s,a;δ=δ) = a - δ*s
"reward:"
r(s,a;z=z) = z*s -a -0.5*(a^2)
"discount:"
β = 1/(1+ρ);
using QuickPOMDPs: QuickMDP #QuickMDP()
using POMDPModelTools: Deterministic
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( ceil_state( μ(s,a) ) ),
reward = (s, a) -> r(s,a),
discount = β
)
# DiscreteValueIteration: Both work fast!
using DiscreteValueIteration
s1 = DiscreteValueIteration.SparseValueIterationSolver()
s2 = DiscreteValueIteration.ValueIterationSolver()
@time sol1 = solve(s1, m) #
@time sol2 = solve(s2, m) #
# value(sol1, states[2]), action(sol1, states[2])
# value(sol2, states[2]), action(sol2, states[2])
value(sol1, states[end])
using Plots
# Value
plot(legend=:bottomright, title="Value Functions");
#plot!(states[2:end], i->A0 + A1 * log(i), lab="closed form")
plot!(states[2:end], i->value(sol1, i), lab="sol1")
plot!(states[2:end], i->value(sol2, i), lab="sol2")
# plot!(states[2:end], i->value(sol4, i), lab="sol4")
# plot!(states[2:end], i->value(sol3, i), lab="sol3")
# Simulation
Tsim=150; s0=states[170]; # s0=0.5*K_SS; #
sim1 = []; push!(sim1, s0);
for tt in 1:Tsim
println(tt)
tt==1 ? s = s0 : nothing
#a = valid_actions()[sol1.policy[searchsortedfirst(states, s)]]
a = action(sol1, s)
sp = μ(s,a)
sp = ceil_state(sp)
push!(sim1, sp)
s = sp
println(s)
end I think I need to fiddle w/ the min_a, min_s but not sure how. |
Beta Was this translation helpful? Give feedback.
-
Sorry here's the correct code: δ=0.10; ρ=0.15; # Param
z= ρ + δ +.02 # Need: z > ρ + δ
I_SS = (z-ρ-δ)/(ρ+δ)
K_SS = I_SS/δ
if 1==1
a_0(s;δ=δ) = δ*s
min_s = eps(); max_s = 2.0*K_SS; n_s = 200;
min_a = eps(); max_a = a_0(max_s); n_a = 400; # keeps a≥0
"states:"
states = range(min_s, max_s, length=n_s)
ceil_state(s) = states[searchsortedfirst(states, s)]
"actions:"
valid_actions() = range(min_a, max_a, length=n_a) # possible actions any state.
valid_actions(s) = filter(<(a0(s)), valid_actions()) # valid actions @ state=s
"Transition:"
μ(s,a;δ=δ) = a - δ*s
"reward:"
r(s,a;z=z) = z*s -a -0.5*(a^2)
"discount:"
β = 1/(1+ρ);
using QuickPOMDPs: QuickMDP #QuickMDP()
using POMDPModelTools: Deterministic
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( ceil_state( μ(s,a) ) ),
reward = (s, a) -> r(s,a),
discount = β
)
# DiscreteValueIteration: Both work fast!
using DiscreteValueIteration
s1 = DiscreteValueIteration.SparseValueIterationSolver()
s2 = DiscreteValueIteration.ValueIterationSolver()
@time sol1 = solve(s1, m) #
@time sol2 = solve(s2, m) #
# value(sol1, states[2]), action(sol1, states[2])
# value(sol2, states[2]), action(sol2, states[2])
value(sol1, states[end])
using Plots
# Value
plot(legend=:bottomright, title="Value Functions");
#plot!(states[2:end], i->A0 + A1 * log(i), lab="closed form")
plot!(states[2:end], i->value(sol1, i), lab="sol1")
plot!(states[2:end], i->value(sol2, i), lab="sol2")
plot!(states[2:end], i->value(sol4, i), lab="sol4")
plot!(states[2:end], i->value(sol3, i), lab="sol3")
# Simulation
Tsim=150; s0=states[2];
sim1 = []; push!(sim1, s0);
for tt in 1:Tsim
tt==1 ? s = s0 : nothing
#a = valid_actions()[sol1.policy[searchsortedfirst(states, s)]]
a = action(sol1, s)
sp = μ(s,a)
sp = ceil_state(sp)
push!(sim1, sp)
s = sp
end
sim4 = []; push!(sim4, s0);
for tt in 1:Tsim
tt==1 ? s = s0 : nothing
a = action(sol4, s)
sp = μ(s,a)
push!(sim4, sp)
s = sp
end
plot(legend=:bottomright, title="Simulation");
#plot!(simcf, lab="closed form")
plot!(sim1, lab="sol1")
plot!(sim4, lab="sol4")
end The discourse discussion & closed form solution is here. |
Beta Was this translation helpful? Give feedback.
-
Your problem is in the search sorted first that can go out of bounds, check
Julia docs for details
…On Thu, Dec 23, 2021, 6:20 PM azev77 ***@***.***> wrote:
@jgslazzaro <https://github.com/jgslazzaro> you're correct. But I still
get errors. I think it might be due to the grid bounds (min_s...)
δ=0.10; ρ=0.15; # Param
z= ρ + δ +.02 # Need: z > ρ + δ
I_SS = (z-ρ-δ)/(ρ+δ)
K_SS = I_SS/δ
min_s = eps(); max_s = 2.0*K_SS; n_s = 200;
min_a = eps(); max_a = K_SS; n_a = 400;
states = range(min_s, max_s, length=n_s)
ceil_state(s) = states[searchsortedfirst(states, s)]
valid_actions() = range(min_a, max_a, length=n_a)
valid_actions(s) = filter(>(-(1-δ)*s), valid_actions())
μ(s,a;δ=δ) = a +(1-δ)*s
r(s,a;z=z) = z*s -a -0.5*(a^2)
β = 1/(1+ρ);
using QuickPOMDPs: QuickMDP #QuickMDP()
using POMDPModelTools: Deterministic
m = QuickMDP(
states = states,
actions = valid_actions,
transition = (s, a) -> Deterministic( ceil_state( μ(s,a) ) ),
reward = (s, a) -> r(s,a),
discount = β
)
using DiscreteValueIteration
s1 = DiscreteValueIteration.SparseValueIterationSolver()
s2 = DiscreteValueIteration.ValueIterationSolver()
@time sol1 = solve(s1, m) #
@time sol2 = solve(s2, m) #
solve() gives the following error:
ERROR: LoadError: BoundsError: attempt to access 200-element StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}} at index [201]
Stacktrace:
[1] throw_boundserror(A::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, I::Tuple{Int64})
@ Base .\abstractarray.jl:651
[2] checkbounds
@ .\abstractarray.jl:616 [inlined]
[3] getindex(r::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, i::Int64)
@ Base .\range.jl:718
[4] ceil_state(s::Float64)
@ Main c:\Users\azevelev\Dropbox\Computation\Julia\4prob\3a_Firm_Invest\Invest\main_Invest.jl:178
[5] (::var"#36#38")(s::Float64, a::Float64)
@ Main c:\Users\azevelev\Dropbox\Computation\Julia\4prob\3a_Firm_Invest\Invest\main_Invest.jl:195
[6] transition(m::QuickMDP{UUID("c4169b2e-f906-4ac2-9a72-ab9bbdebde92"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#36#38", var"#37#39", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}}, s::Float64, a::Float64)
@ QuickPOMDPs C:\Users\azevelev\.julia\packages\QuickPOMDPs\mIT3P\src\quick.jl:217
[7] transition_matrix_a_s_sp(mdp::QuickMDP{UUID("c4169b2e-f906-4ac2-9a72-ab9bbdebde92"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#36#38", var"#37#39", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}})
@ POMDPModelTools C:\Users\azevelev\.julia\packages\POMDPModelTools\SycBB\src\sparse_tabular.jl:179
[8] POMDPModelTools.SparseTabularMDP(mdp::QuickMDP{UUID("c4169b2e-f906-4ac2-9a72-ab9bbdebde92"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#36#38", var"#37#39", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}})
@ POMDPModelTools C:\Users\azevelev\.julia\packages\POMDPModelTools\SycBB\src\sparse_tabular.jl:30
[9] solve(solver::SparseValueIterationSolver, mdp::QuickMDP{UUID("c4169b2e-f906-4ac2-9a72-ab9bbdebde92"), Float64, Float64, NamedTuple{(:stateindex, :isterminal, :actionindex, :transition, :reward, :states, :actions, :discount), Tuple{Dict{Float64, Int64}, Bool, Dict{Float64, Int64}, var"#36#38", var"#37#39", StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, typeof(valid_actions), Float64}}})
@ DiscreteValueIteration C:\Users\azevelev\.julia\packages\DiscreteValueIteration\FjeJj\src\sparse.jl:91
[10] top-level scope
@ Untitled-1:36
in expression starting at Untitled-1:36
julia>
—
Reply to this email directly, view it on GitHub
<#351 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC7ILYYJTEDQP775QCZMZCLUSOHDHANCNFSM5BR4IXMQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
Thanks for posting! It's good to get problems from different fields. It would be great to make this package easier to pick up for economists!
I think something like this works: