In [3]:
using HDF5, JLD

In [4]:
# add additional processes to serve as workers 
n_procs = 6
addprocs(n_procs);

In [5]:
# add present working directory to path from which to load modules
push!(LOAD_PATH, ".") 

# load module DynamicProgramming on each of the processes 
using DynamicProgramming
using Interpolations

In [6]:
# nominal parameter value 
@everywhere T1 = 0.680 # seconds in white matter 
@everywhere T2 = 0.090 # seconds in white matter 
@everywhere dT = 0.2   # seconds between acquisitions 
@everywhere sigma = 0.1  # noise strength 
@everywhere theta0 = [exp(-dT/T1); exp(-dT/T2)]

# time horizon 
@everywhere N = 30

# state dimension 
@everywhere n = 6

# initial state
@everywhere x0 = [0.; 0.; 1.; 0; 0; 0]

# define rotation matrices 
@everywhere function Rx(alpha::Float64)
    return [1     0           0     ;
            0 cos(alpha) -sin(alpha);
            0 sin(alpha)  cos(alpha)]
end
@everywhere function Ry(alpha::Float64)
    return [cos(alpha) 0 -sin(alpha);
                0      1      0     ;
            sin(alpha) 0  cos(alpha)]
end
@everywhere function Rz(alpha::Float64)
    return [cos(alpha) -sin(alpha) 0;
            sin(alpha)  cos(alpha) 0;
                0           0      1]
end

# dynamics 
@everywhere function f(t::Int64, x::Array{Float64, 1}, u::Array{Float64, 1}, theta::Array{Float64, 1})
    x_state = x[1:3]
    x_sensitivity = x[4:6]
    U = Rz(u[1])*Ry(u[2])*Rx(u[3])
    D = [theta[2], theta[2], theta[1]]
    x_state_plus = U*(D.*x_state) + [0; 0; 1-theta[1]]
    x_sensitivity_plus = U*(D.*x_sensitivity) + U*([0; 0; 1].*x_state) + [0; 0; -1]
    return [x_state_plus; x_sensitivity_plus]
end

# test dynamics 
f(1, x0, [0.; 0.; 0.], theta0)

# reward function 
@everywhere function g(k::Int64, x::Array{Float64, 1}, u::Array{Float64, 1}, theta::Array{Float64, 1})
    return x[4]^2 + x[5]^2 
end

# terminal reward 
@everywhere function g_terminal(x::Array{Float64, 1})
    return x[4]^2 + x[5]^2 
end

# test reward function 
g(0, x0, [0.; 0.; 0.], theta0)

# define state grid 
@everywhere nx1 = 6 # number of grid points in each dimension  
@everywhere nx2 = 6
@everywhere nx3 = 6
@everywhere nx4 = 7
@everywhere nx5 = 7
@everywhere nx6 = 7
@everywhere xgrid = (
                     linspace(-1., 1., nx1), 
                     linspace(-1., 1., nx2), 
                     linspace(-1., 1., nx3), 
                     linspace(-50., 50., nx4), 
                     linspace(-50., 50., nx5), 
                     linspace(-100., 100., nx6)
                    ) 

# define input grid
# make nu's even so that there is a grid knot at zero
@everywhere nu1 = 1
@everywhere nu2 = 16
@everywhere nu3 = 8
@everywhere ugrid = (
                     linspace(0, 0, nu1), 
                     linspace(-pi, pi-2*pi/nu2, nu2), 
                     linspace(0, pi-pi/nu3, nu3)
                    )

In [7]:
# define invariants 

@everywhere function rho(x::Array{Float64, 1})
    r = sqrt(x[1]*x[1] + x[2]*x[2])
    return [r;
            x[3];
            1/r*(x[2]*x[4] - x[1]*x[5]);
            1/r*(x[1]*x[4] + x[2]*x[5]);
            x[6]]
end

@everywhere function rho_bar_inverse(x_bar::Array{Float64, 1})
    return [0; x_bar]
end

In [10]:
# @everywhere nx1_reduced = 6
# @everywhere nx2_reduced = 15
# @everywhere nx3_reduced = 20
# @everywhere nx4_reduced = 20
# @everywhere nx5_reduced = 20

@everywhere nx1_reduced = 6
@everywhere nx2_reduced = 10
@everywhere nx3_reduced = 15
@everywhere nx4_reduced = 15
@everywhere nx5_reduced = 15


@everywhere xgrid_reduced = (
                     linspace(0.01, 0.6, nx1_reduced), 
                     linspace(1-2*theta0[1], 1., nx2_reduced), 
                     linspace(-5., 5., nx3_reduced), 
                     linspace(-5., 5., nx4_reduced), 
                     linspace(-5., 5., nx5_reduced)
                    )

In [6]:
@time J = dp_reduced(f, g, g_terminal, rho, rho_bar_inverse, ugrid, xgrid_reduced, theta0, N);


====== Constructing array J ======
J is size (6,10,15,15,15) by 30
====== Array J constructed  ======
Step k = 30
Step k = 29
Step k = 28
Step k = 27
Step k = 26
Step k = 25
Step k = 24
Step k = 23
Step k = 22
Step k = 21
Step k = 20
Step k = 19
Step k = 18
Step k = 17
Step k = 16
Step k = 15
Step k = 14
Step k = 13
Step k = 12
Step k = 11
Step k = 10
Step k = 9
Step k = 8
Step k = 7
Step k = 6
Step k = 5
Step k = 4
Step k = 3
Step k = 2
Step k = 1
12694.522147 seconds (73.41 M allocations: 2.173 GB, 0.00% gc time)

In [8]:
# save value function computed at grid points 
# save("J_MR_fingerprinting.jld", "data", J)

In [8]:
# reload value function 
J = load("J_MR_fingerprinting.jld")["data"];

In [11]:
# define a finer input grid for policy rollout 
@everywhere nu1 = 32
@everywhere nu2 = 32
@everywhere nu3 = 16
@everywhere ugrid = (
                     linspace(0, 0, 1), 
                     linspace(-pi, pi-2*pi/nu2, nu2), 
                     linspace(0, pi-pi/nu3, nu3)
                    ) 


# compute optimal trajectory from initial condition x0 
x0 = [0.; 0.; 1.; 0.; 0.; 0.]
x_opt, u_opt = dp_rollout_reduced(J, x0, f, g, rho, ugrid, xgrid_reduced, theta0, N);

In [12]:
using Colors 
using Gadfly

berkeley_blue = RGB((1/256*[ 45.,  99., 127.])...)
berkeley_gold = RGB((1/256*[224., 158.,  25.])...); 
gray          = RGB((1/256*[200., 200., 200.])...);

In [14]:
# plot optimal input 

p = plot(layer(x=0:N-1, y=180/pi*u_opt[1, :], Geom.point, Geom.line, Theme(default_color=berkeley_blue)), 
        layer(x=0:N-1, y=180/pi*u_opt[2, :], Geom.point, Geom.line, Theme(default_color=berkeley_gold)), 
        layer(x=0:N-1, y=180/pi*u_opt[3, :], Geom.point, Geom.line, Theme(default_color=gray)), 
        Guide.XLabel("time"), 
        Guide.YLabel("input angle (degrees)"),
Guide.manual_color_key("Angle", ["α", "β", "δ"], [berkeley_blue, berkeley_gold, gray])
)
draw(PNG("MRI_optimal_input.png", 15cm, 10cm), p)
p


Out[14]:
time -40 -30 -20 -10 0 10 20 30 40 50 60 70 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 -30 0 30 60 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 α β δ Angle -700 -600 -500 -400 -300 -200 -100 0 100 200 300 400 500 600 700 -600 -580 -560 -540 -520 -500 -480 -460 -440 -420 -400 -380 -360 -340 -320 -300 -280 -260 -240 -220 -200 -180 -160 -140 -120 -100 -80 -60 -40 -20 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360 380 400 420 440 460 480 500 520 540 560 580 600 -600 -300 0 300 600 -600 -550 -500 -450 -400 -350 -300 -250 -200 -150 -100 -50 0 50 100 150 200 250 300 350 400 450 500 550 600 input angle (degrees)

In [13]:
# plot optimal trajectory in transverse plane 

p = plot(x=x_opt[1, :], y=x_opt[2, :], 
        Guide.XLabel("x_1 magnetization"), 
        Guide.YLabel("x_2 magnetization"), 
        Geom.path, Geom.point, Coord.cartesian(fixed=true),
        Theme(default_color=berkeley_gold)
)
draw(SVG("MRI_full_trajectory_transverse_plane.svg", 10cm, 20cm), p)
p


Out[13]:
x_1 magnetization -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 -0.62 -0.60 -0.58 -0.56 -0.54 -0.52 -0.50 -0.48 -0.46 -0.44 -0.42 -0.40 -0.38 -0.36 -0.34 -0.32 -0.30 -0.28 -0.26 -0.24 -0.22 -0.20 -0.18 -0.16 -0.14 -0.12 -0.10 -0.08 -0.06 -0.04 -0.02 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50 0.52 0.54 0.56 0.58 0.60 0.62 -0.6 -0.3 0.0 0.3 0.6 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 -0.80 -0.78 -0.76 -0.74 -0.72 -0.70 -0.68 -0.66 -0.64 -0.62 -0.60 -0.58 -0.56 -0.54 -0.52 -0.50 -0.48 -0.46 -0.44 -0.42 -0.40 -0.38 -0.36 -0.34 -0.32 -0.30 -0.28 -0.26 -0.24 -0.22 -0.20 -0.18 -0.16 -0.14 -0.12 -0.10 -0.08 -0.06 -0.04 -0.02 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50 0.52 0.54 0.56 0.58 0.60 0.62 0.64 0.66 0.68 0.70 -1.0 -0.5 0.0 0.5 1.0 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 x_2 magnetization

In [14]:
# plot optimal trajectory in transverse vs. longitudinal

p = plot(x=sqrt(x_opt[1, :].^2 + x_opt[2, :].^2), y=x_opt[3, :], 
        Guide.XLabel("transverse magnetization"), 
        Guide.YLabel("longitudinal magnetization"), 
        Geom.path, Geom.point, Coord.cartesian(fixed=true),
        Theme(default_color=berkeley_gold)
)
draw(SVG("MRI_full_trajectory_transverse_vs_longitudinal.svg", 10cm, 20cm), p)
p


Out[14]:
transverse magnetization -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 -0.25 -0.24 -0.23 -0.22 -0.21 -0.20 -0.19 -0.18 -0.17 -0.16 -0.15 -0.14 -0.13 -0.12 -0.11 -0.10 -0.09 -0.08 -0.07 -0.06 -0.05 -0.04 -0.03 -0.02 -0.01 0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.20 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.40 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.50 -0.25 0.00 0.25 0.50 -0.26 -0.24 -0.22 -0.20 -0.18 -0.16 -0.14 -0.12 -0.10 -0.08 -0.06 -0.04 -0.02 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 -2.00 -1.95 -1.90 -1.85 -1.80 -1.75 -1.70 -1.65 -1.60 -1.55 -1.50 -1.45 -1.40 -1.35 -1.30 -1.25 -1.20 -1.15 -1.10 -1.05 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 -2 0 2 4 -2.0 -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 longitudinal magnetization

In [15]:
p = plot(layer(x=0:N, y=x_opt[1, :], Geom.point, Geom.line, Theme(default_color=berkeley_blue)), 
        layer(x=0:N, y=x_opt[2, :], Geom.point, Geom.line, Theme(default_color=berkeley_gold)), 
        layer(x=0:N, y=x_opt[3, :], Geom.point, Geom.line, Theme(default_color=gray)), 
        Guide.XLabel("time"), 
Guide.YLabel("state"),
# Guide.manual_color_key("Angle", ["α", "β", "δ"], [berkeley_blue, berkeley_gold, gray])
)


Out[15]:
time -40 -30 -20 -10 0 10 20 30 40 50 60 70 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 -30 0 30 60 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 -2.00 -1.95 -1.90 -1.85 -1.80 -1.75 -1.70 -1.65 -1.60 -1.55 -1.50 -1.45 -1.40 -1.35 -1.30 -1.25 -1.20 -1.15 -1.10 -1.05 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 -2 0 2 4 -2.0 -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 state

In [15]:
p = plot(layer(x=0:N, y=sqrt(x_opt[1, :].^2 + x_opt[2, :].^2), Geom.point, Geom.line, Theme(default_color=berkeley_blue)), 
        layer(x=0:N, y=x_opt[3, :], Geom.point, Geom.line, Theme(default_color=berkeley_gold)), 
        # layer(x=0:N, y=x_opt[6, :], Geom.point, Geom.line, Theme(default_color=gray)), 
        Guide.XLabel("time"), 
        Guide.YLabel("magnetization"),
        Guide.manual_color_key("", ["transverse |(x_1, x_2)|", "longitudinal (x_3)"], [berkeley_blue, berkeley_gold])
)
draw(PNG("MRI_optimal_magnetization.png", 15cm, 10cm), p)
p


Out[15]:
time -40 -30 -20 -10 0 10 20 30 40 50 60 70 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 -30 0 30 60 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 transverse |(x_1, x_2)| longitudinal (x_3) -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 -2.00 -1.95 -1.90 -1.85 -1.80 -1.75 -1.70 -1.65 -1.60 -1.55 -1.50 -1.45 -1.40 -1.35 -1.30 -1.25 -1.20 -1.15 -1.10 -1.05 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 -2 0 2 4 -2.0 -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 magnetization

In [17]:
p = plot(layer(x=0:N, y=x_opt[4, :], Geom.point, Geom.line, Theme(default_color=berkeley_blue)), 
        layer(x=0:N, y=x_opt[5, :], Geom.point, Geom.line, Theme(default_color=berkeley_gold)), 
        layer(x=0:N, y=x_opt[6, :], Geom.point, Geom.line, Theme(default_color=gray)), 
        Guide.XLabel("time"), 
Guide.YLabel("sensitivity"),
# Guide.manual_color_key("Angle", ["α", "β", "δ"], [berkeley_blue, berkeley_gold, gray])
)


Out[17]:
time -40 -30 -20 -10 0 10 20 30 40 50 60 70 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 -30 0 30 60 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 -8.0 -7.8 -7.6 -7.4 -7.2 -7.0 -6.8 -6.6 -6.4 -6.2 -6.0 -5.8 -5.6 -5.4 -5.2 -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4 -3.2 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -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.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -10 -5 0 5 10 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 sensitivity

In [16]:
p = plot(layer(x=0:N, y=sqrt(x_opt[4, :].^2 + x_opt[5, :].^2), Geom.point, Geom.line, Theme(default_color=berkeley_blue)), 
        layer(x=0:N, y=x_opt[6, :], Geom.point, Geom.line, Theme(default_color=berkeley_gold)), 
        # layer(x=0:N, y=x_opt[6, :], Geom.point, Geom.line, Theme(default_color=gray)), 
        Guide.XLabel("time"), 
Guide.YLabel("sensitivity"),
Guide.manual_color_key("", ["transverse |(x_4, x_5)|", "longitudinal (x_6)"], [berkeley_blue, berkeley_gold])
)
draw(PNG("MRI_optimal_sensitivity.png", 15cm, 10cm), p)
p


Out[16]:
time -40 -30 -20 -10 0 10 20 30 40 50 60 70 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 -30 0 30 60 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 transverse |(x_4, x_5)| longitudinal (x_6) -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 -8.0 -7.8 -7.6 -7.4 -7.2 -7.0 -6.8 -6.6 -6.4 -6.2 -6.0 -5.8 -5.6 -5.4 -5.2 -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4 -3.2 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -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.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -10 -5 0 5 10 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 sensitivity

In [19]:
Pkg.status()


12 required packages:
 - Cairo                         0.2.35
 - Compose                       0.4.4
 - Fontconfig                    0.1.1
 - GR                            0.19.0
 - Gadfly                        0.5.2
 - HDF5                          0.7.2
 - IJulia                        1.4.1
 - Interpolations                0.3.6
 - JLD                           0.6.9
 - Plots                         0.10.3
 - PyPlot                        2.2.4
 - StatPlots                     0.2.1
55 additional packages:
 - AxisAlgorithms                0.1.5
 - BinDeps                       0.4.5
 - Blosc                         0.1.7
 - Calculus                      0.2.0
 - ColorTypes                    0.2.12
 - Colors                        0.6.9
 - Compat                        0.13.0
 - Conda                         0.4.0
 - Contour                       0.2.0
 - DataArrays                    0.3.11
 - DataFrames                    0.8.5
 - DataStructures                0.5.2
 - DiffBase                      0.0.3
 - Distances                     0.3.2
 - Distributions                 0.11.1
 - FileIO                        0.2.2
 - FixedPointNumbers             0.2.1
 - FixedSizeArrays               0.2.5
 - ForwardDiff                   0.3.3
 - GZip                          0.2.20
 - Graphics                      0.1.3
 - Hexagons                      0.0.4
 - Hiccup                        0.1.1
 - Homebrew                      0.4.2
 - Iterators                     0.2.0
 - JSON                          0.8.2
 - Juno                          0.2.5
 - KernelDensity                 0.3.0
 - LaTeXStrings                  0.2.0
 - LegacyStrings                 0.2.0
 - LineSearches                  0.1.5
 - Loess                         0.1.0
 - MacroTools                    0.3.4
 - Measures                      0.0.3
 - Media                         0.2.4
 - NaNMath                       0.2.2
 - Nettle                        0.2.4
 - Optim                         0.7.4
 - PDMats                        0.5.4
 - PlotThemes                    0.1.0
 - PlotUtils                     0.3.0
 - PositiveFactorizations        0.0.3
 - PyCall                        1.8.0
 - Ratios                        0.0.4
 - RecipesBase                   0.1.0
 - Reexport                      0.0.3
 - Rmath                         0.1.6
 - SHA                           0.3.0
 - Showoff                       0.0.7
 - SortingAlgorithms             0.1.0
 - StatsBase                     0.13.0
 - StatsFuns                     0.4.0
 - URIParser                     0.1.7
 - WoodburyMatrices              0.2.1
 - ZMQ                           0.4.1

In [ ]: