using InstantiateFromURL github_project("QuantEcon/quantecon-notebooks-julia", version = "0.2.0") using LinearAlgebra, Statistics using Distributions, Plots, Printf, QuantEcon, Random gr(fmt = :png); d = Categorical([0.5, 0.3, 0.2]) # 3 discrete states @show rand(d, 5) @show supertype(typeof(d)) @show pdf(d, 1) # the probability to be in state 1 @show support(d) @show pdf.(d, support(d)); # broadcast the pdf over the whole support function mc_sample_path(P; init = 1, sample_size = 1000) @assert size(P)[1] == size(P)[2] # square required N = size(P)[1] # should be square # create vector of discrete RVs for each row dists = [Categorical(P[i, :]) for i in 1:N] # setup the simulation X = fill(0, sample_size) # allocate memory, or zeros(Int64, sample_size) X[1] = init # set the initial state for t in 2:sample_size dist = dists[X[t-1]] # get discrete RV from last state's transition distribution X[t] = rand(dist) # draw new value end return X end P = [0.4 0.6; 0.2 0.8] X = mc_sample_path(P, sample_size = 100_000); # note 100_000 = 100000 μ_1 = count(X .== 1)/length(X) # .== broadcasts test for equality. Could use mean(X .== 1) P = [0.4 0.6; 0.2 0.8]; mc = MarkovChain(P) X = simulate(mc, 100_000); μ_2 = count(X .== 1)/length(X) # or mean(x -> x == 1, X) mc = MarkovChain(P, ["unemployed", "employed"]) simulate(mc, 4, init = 1) # start at state 1 simulate(mc, 4, init = 2) # start at state 2 simulate(mc, 4) # start with randomly chosen initial condition simulate_indices(mc, 4) P = [0.9 0.1 0.0; 0.4 0.4 0.2; 0.1 0.1 0.8]; mc = MarkovChain(P) is_irreducible(mc) P = [1.0 0.0 0.0; 0.1 0.8 0.1; 0.0 0.2 0.8]; mc = MarkovChain(P); is_irreducible(mc) communication_classes(mc) P = [0 1 0; 0 0 1; 1 0 0]; mc = MarkovChain(P); period(mc) P = zeros(4, 4); P[1, 2] = 1; P[2, 1] = P[2, 3] = 0.5; P[3, 2] = P[3, 4] = 0.5; P[4, 3] = 1; mc = MarkovChain(P); period(mc) is_aperiodic(mc) P = [.4 .6; .2 .8]; ψ = [0.25, 0.75]; ψ' * P P = [.4 .6; .2 .8]; mc = MarkovChain(P); stationary_distributions(mc) P = [0.971 0.029 0.000 0.145 0.778 0.077 0.000 0.508 0.492] # stochastic matrix ψ = [0.0 0.2 0.8] # initial distribution t = 20 # path length x_vals = zeros(t) y_vals = similar(x_vals) z_vals = similar(x_vals) colors = [repeat([:red], 20); :black] # for plotting for i in 1:t x_vals[i] = ψ[1] y_vals[i] = ψ[2] z_vals[i] = ψ[3] ψ = ψ * P # update distribution end mc = MarkovChain(P) ψ_star = stationary_distributions(mc)[1] x_star, y_star, z_star = ψ_star # unpack the stationary dist plt = scatter([x_vals; x_star], [y_vals; y_star], [z_vals; z_star], color = colors, gridalpha = 0.5, legend = :none) plot!(plt, camera = (45,45)) α = 0.1 # probability of getting hired β = 0.1 # probability of getting fired N = 10_000 p̄ = β / (α + β) # steady-state probabilities P = [1 - α α β 1 - β] # stochastic matrix mc = MarkovChain(P) labels = ["start unemployed", "start employed"] y_vals = Array{Vector}(undef, 2) # sample paths holder for x0 in 1:2 X = simulate_indices(mc, N; init = x0) # generate the sample path X̄ = cumsum(X .== 1) ./ (1:N) # compute state fraction. ./ required for precedence y_vals[x0] = X̄ .- p̄ # plot divergence from steady state end plot(y_vals, color = [:blue :green], fillrange = 0, fillalpha = 0.1, ylims = (-0.25, 0.25), label = reshape(labels, 1, length(labels))) web_graph_data = sort(Dict('a' => ['d', 'f'], 'b' => ['j', 'k', 'm'], 'c' => ['c', 'g', 'j', 'm'], 'd' => ['f', 'h', 'k'], 'e' => ['d', 'h', 'l'], 'f' => ['a', 'b', 'j', 'l'], 'g' => ['b', 'j'], 'h' => ['d', 'g', 'l', 'm'], 'i' => ['g', 'h', 'n'], 'j' => ['e', 'i', 'k'], 'k' => ['n'], 'l' => ['m'], 'm' => ['g'], 'n' => ['c', 'j', 'm'])) nodes = keys(web_graph_data) n = length(nodes) # create adjacency matrix of links (Q[i, j] = true for link, false otherwise) Q = fill(false, n, n) for (node, edges) in enumerate(values(web_graph_data)) Q[node, nodes .∈ Ref(edges)] .= true end # create the corresponding stochastic matrix P = Q ./ sum(Q, dims = 2) mc = MarkovChain(P) r = stationary_distributions(mc)[1] # stationary distribution ranked_pages = Dict(zip(keys(web_graph_data), r)) # results holder # print solution println("Rankings\n ***") sort(collect(ranked_pages), by = x -> x[2], rev = true) # print sorted