# Linear Regression (Botswana)

In this code, we use linear regression on the analytical forms of the Green Solow model to find its parameters. We show that the parameters found using linear regression are not consistent, and each analytical equation gives different/ conflicting parameters.

```julia
# #generating the environment, this has to be done the first time this code is run
# using Pkg
# Pkg.generate("regression_Y")

# Pkg.add("ModelingToolkit")
# Pkg.add("OrdinaryDiffEq")
# Pkg.add("LinearAlgebra")
# Pkg.add("Plots")
# Pkg.add("StatsModels")
# Pkg.add("Plots")
# Pkg.add("DataFrames")
# Pkg.add("CSV")
# Pkg.add("GLM")
# Pkg.add("Statistics")
# Pkg.add("Flux")
# Pkg.add("StatsBase")
```

```julia
println(@__DIR__)
using Pkg
Pkg.activate(string(@__DIR__, "/regression_Y/"))
Pkg.status()
```

    /home/ziyu/solow/NODE/Neural Ordinary Differential Equations for the Regression and Prediction of Macroeconomics Data under the Green Solow Model/Model -1 Analytical Solution Regression

     Activating environment at `~/solow/NODE/Neural Ordinary Differential Equations for the Regression and Prediction of Macroeconomics Data under the Green Solow Model/Model -1 Analytical Solution Regression/regression_Y/Project.toml`

    Project regression_Y v0.1.0
    Status `~/solow/NODE/Neural Ordinary Differential Equations for the Regression and Prediction of Macroeconomics Data under the Green Solow Model/Model -1 Analytical Solution Regression/regression_Y/Project.toml`
      [336ed68f] CSV v0.8.4
      [a93c6f00] DataFrames v0.22.5
      [587475ba] Flux v0.11.1
      [38e38edf] GLM v1.4.0
      [961ee093] ModelingToolkit v5.10.1
      [1dea7af3] OrdinaryDiffEq v5.51.1
      [91a5bcdd] Plots v1.6.12
      [2913bbd2] StatsBase v0.33.3
      [3eaba693] StatsModels v0.6.21
      [37e2e46d] LinearAlgebra
      [10745b16] Statistics

```julia
using ModelingToolkit
using OrdinaryDiffEq
using LinearAlgebra
using Statistics
using Flux
using StatsBase
using DataFrames
# using Plots
```

# Importing data

```julia
using CSV
raw_data = CSV.read(string(@__DIR__,"/compileddf.csv"),normalizenames = true, DataFrame)
```

	Year	Albania_et	Albania_yt	Albania_Popt	Albania_nt	Albania_Ktotal	Albania_kt

	Int64	Float64?	Float64?	Float64	Float64?	Float64?	Float64?

50 rows × 834 columns (omitted printing of 827 columns)

1	1959	missing	missing	1.57133e6	missing	missing	missing

2	1960	1.25819	0.001451	1.62311e6	0.0329562	missing	missing

3	1961	1.37419	0.001463	1.67664e6	0.0329743	missing	missing

4	1962	1.43996	0.001511	1.72814e6	0.0307175	missing	missing

5	1963	1.18168	0.001563	1.77972e6	0.029846	missing	missing

6	1964	1.11174	0.001616	1.83228e6	0.0295379	missing	missing

7	1965	1.1661	0.001675	1.88365e6	0.028035	missing	missing

8	1966	1.33306	0.001738	1.93296e6	0.0261784	missing	missing

9	1967	1.36375	0.001804	1.98406e6	0.0264345	missing	missing

10	1968	1.51955	0.001869	2.0387e6	0.0275385	missing	missing

11	1969	1.55897	0.001932	2.10026e6	0.0301982	missing	missing

12	1970	1.75324	0.002004	2.15661e6	0.0268295	8341.5	0.00386787

13	1971	1.9895	0.002084	2.20872e6	0.0241615	9139.71	0.00413801

14	1972	2.51591	0.002165	2.26355e6	0.0248266	9979.96	0.00440898

15	1973	2.3039	0.002273	2.29569e6	0.0141976	10938.6	0.00476486

16	1974	1.84901	0.002282	2.34792e6	0.0227526	12095.4	0.00515151

17	1975	1.91063	0.002289	2.40111e6	0.0226515	13168.9	0.0054845

18	1976	2.01358	0.002299	2.45482e6	0.0223713	14067.9	0.0057307

19	1977	2.27588	0.002309	2.50905e6	0.0220888	15281.5	0.00609056

20	1978	2.53063	0.002319	2.56338e6	0.0216528	16651.3	0.00649584

21	1979	2.89821	0.002331	2.61768e6	0.0211842	18108.5	0.00691776

22	1980	1.93506	0.002347	2.67141e6	0.020527	19475.2	0.00729022

23	1981	2.69302	0.00236	2.72427e6	0.0197873	20820.0	0.00764241

24	1982	2.62486	0.002373	2.7801e6	0.0204917	22260.3	0.00800703

25	1983	2.68324	0.002387	2.83732e6	0.0205813	22660.8	0.00798669

26	1984	2.69429	0.0024	2.896e6	0.0206826	23848.4	0.00823495

27	1985	2.65802	0.002413	2.9567e6	0.0209596	24653.7	0.00833826

28	1986	2.66536	0.002428	3.01544e6	0.0198671	26068.0	0.00864484

29	1987	2.41406	0.002443	3.07532e6	0.0198588	27256.4	0.00886296

30	1988	2.3316	0.002459	3.13684e6	0.0200051	28346.3	0.00903656

⋮	⋮	⋮	⋮	⋮	⋮	⋮	⋮

```julia
Botswana_raw = raw_data[:, ["Botswana_kt", "Botswana_et", "Botswana_yt", "Botswana_nt"]]
delete!(Botswana_raw, 1:15)
Botswana_raw[!,:t] = 1:35
Botswana_y_reg = Botswana_raw[:,[1,3,2,5]]
DataFrames.rename!(Botswana_y_reg, [:k, :y, :e, :t])
Botswana_y_reg = Botswana_y_reg[2:end,:]

Botswana_y_reg[!, :yty0] = Botswana_y_reg[!, :y]/Botswana_y_reg[!, :y][1]
Botswana_y_reg[!, :lgyty0] = log.(Botswana_y_reg[!, :yty0])
Botswana_y_reg[!, :ktk0] = Botswana_y_reg[!, :k]/Botswana_y_reg[!, :k][1]
Botswana_y_reg[!, :lgktk0] = log.(Botswana_y_reg[!, :ktk0])
Botswana_raw
```

	Botswana_kt	Botswana_et	Botswana_yt	Botswana_nt	t

	Float64?	Float64?	Float64?	Float64?	Int64

35 rows × 5 columns

1	0.00394345	0.123138	0.0013	0.0446184	1

2	0.00408493	0.252264	0.001223	0.0488591	2

3	0.00404858	0.77152	0.001381	0.0520614	3

4	0.00402169	0.975694	0.001358	0.0542297	4

5	0.00407305	0.99993	0.001537	0.0521772	5

6	0.00424262	1.08941	0.001613	0.0490789	6

7	0.00457454	1.09863	0.001765	0.0439067	7

8	0.00477105	1.08385	0.001858	0.0377156	8

9	0.00494978	1.14252	0.001921	0.0387538	9

10	0.00482787	1.03443	0.002144	0.0374656	10

11	0.00486212	1.01324	0.0023	0.0361255	11

12	0.00494681	1.08339	0.002387	0.0347864	12

13	0.00521229	0.960533	0.002485	0.0334021	13

14	0.00543057	1.0732	0.002619	0.0324946	14

15	0.00581681	1.08476	0.002937	0.0320561	15

16	0.0067093	1.14918	0.003216	0.0316046	16

17	0.00791826	2.1003	0.003304	0.0310595	17

18	0.00870503	1.98788	0.00336	0.0304378	18

19	0.00936606	2.03849	0.003354	0.0319407	19

20	0.01013	2.28547	0.003311	0.0331845	20

21	0.0109341	2.1147	0.003321	0.0319128	21

22	0.0119173	2.07414	0.003367	0.0306224	22

23	0.0128182	1.83261	0.003458	0.0293187	23

24	0.013753	1.81871	0.003589	0.0277978	24

25	0.0149094	2.12226	0.003704	0.0261113	25

26	0.0163178	1.963	0.003845	0.0242742	26

27	0.0177838	2.30061	0.004084	0.0223605	27

28	0.0193387	2.29916	0.004211	0.0204378	28

29	0.0209827	2.33404	0.004339	0.0187677	29

30	0.0228039	2.20731	0.004429	0.0177044	30

⋮	⋮	⋮	⋮	⋮	⋮

```julia
#useful for calculations later
println(mean(Botswana_raw[!,"Botswana_nt"]))
```

    0.03228734200605755

## Parameters for the equation for y(t)

Start by regressing the equation for $y(t)$. To regress the following equation, the analytical solution of the Green Solow Model equation:

$\frac{y(t)}{y(0)} = \frac{k(t)^\alpha}{k(0)^\alpha} \times e^{g_B \times t} = \left(\frac{k(t)}{k(0)}\right)^\alpha \times e^{g_B \times t}$

Can take the log of both sides to get:

$\log\left(\frac{y(t)}{y(0)}\right) = \alpha \log\left(\frac{k(t)}{k(0)}\right) + g_B\times t$

```julia
using GLM

#regression of Botswana y data
ols_y_Botswana = lm(@formula(lgyty0 ~ lgktk0 + t), Botswana_y_reg)
```

    StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,CholeskyPivoted{Float64,Array{Float64,2}}}},Array{Float64,2}}

    lgyty0 ~ 1 + lgktk0 + t

    Coefficients:
    ─────────────────────────────────────────────────────────────────────────────
                      Coef.  Std. Error       t  Pr(>|t|)   Lower 95%   Upper 95%
    ─────────────────────────────────────────────────────────────────────────────
    (Intercept)  -0.185088   0.0362612    -5.10    <1e-4   -0.259043   -0.111133
    lgktk0       -0.651249   0.0647908   -10.05    <1e-10  -0.78339    -0.519107
    t             0.0866218  0.00476762   18.17    <1e-17   0.0768982   0.0963454
    ─────────────────────────────────────────────────────────────────────────────

Note that the value of $\alpha$ can be found through this regression, via the coefficient for $log\frac{k(t)}{k(0)}$

```julia
#returns the coefficients, which are the values of $\alpha$ and $g_B$

Botswana_intercept = coef(ols_y_Botswana)[1]
Botswana_alpha = coef(ols_y_Botswana)[2]
Botswana_gB = coef(ols_y_Botswana)[3]

println("alpha is ", Botswana_alpha)
println("gB is ", Botswana_gB)
```

    alpha is -0.6512485258602105
    gB is 0.08662180641283503

## Parameters for the equation for e(t)

Regressing the equation for $e(t)$. To regress the following equation, the analytical solution of the Green Solow Model equation:

\begin{gather}
    \frac{e(t)}{e(0)}
    = \left( \frac{k(t)}{k(0)}\right)^\alpha \times e^{(g_B -g_A) \times t}
\end{gather}

Can take the log of both sides to get:

$\log\left(\frac{e(t)}{e(0)}\right) = \alpha \log\left(\frac{k(t)}{k(0)}\right) + (g_B-g_A)\times t$

```julia
Botswana_e_reg = Botswana_raw[:,[1,3,2,5]]
DataFrames.rename!(Botswana_e_reg, [:k, :y, :e, :t])
Botswana_e_reg = Botswana_e_reg[2:end,:]

Botswana_e_reg[!, :ete0] = Botswana_e_reg[!, :e]/Botswana_y_reg[!, :e][1]
Botswana_e_reg[!, :lgete0] = log.(Botswana_e_reg[!, :ete0])
Botswana_e_reg[!, :ktk0] = Botswana_e_reg[!, :k]/Botswana_e_reg[!, :k][1]
Botswana_e_reg[!, :lgktk0] = log.(Botswana_e_reg[!, :ktk0])
# print(Botswana_y_reg)

ols_e_Botswana = lm(@formula(lgete0 ~ lgktk0 + t), Botswana_e_reg)
```

    StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,CholeskyPivoted{Float64,Array{Float64,2}}}},Array{Float64,2}}

    lgete0 ~ 1 + lgktk0 + t

    Coefficients:
    ───────────────────────────────────────────────────────────────────────────
                      Coef.  Std. Error      t  Pr(>|t|)   Lower 95%  Upper 95%
    ───────────────────────────────────────────────────────────────────────────
    (Intercept)   0.751093    0.180663    4.16    0.0002   0.38263    1.11956
    lgktk0       -0.55891     0.322804   -1.73    0.0933  -1.21727    0.0994533
    t             0.0814058   0.0237535   3.43    0.0017   0.0329602  0.129851
    ───────────────────────────────────────────────────────────────────────────

Upon observation, we can see that the values for $\alpha$ already differ among these two regessions.

## Parameters for the equation for k(t)

\begin{equation}
    k(t) = (\frac{\frac{(1-\alpha)\times s\times y(0)}{k(0)^\alpha} \times \frac{e^{(1-\alpha)\times (\delta+n+g_B)\times t + g_B \times t}}{(1-\alpha)\times (\delta+n+g_B) + g_B } +C}{e^{(1-\alpha)\times (\delta +n+g_B)\times t }})^\frac{1}{1-\alpha}
\end{equation}
Where:
\begin{equation}
    C = k(0)^{1-\alpha} - \frac{(1-\alpha)\times s\times y(0)}{{k(0)^\alpha}\times((1-\alpha)\times (\delta+n+g_B) + g_B )}
\end{equation}

We can simplify the equation to:
\begin{equation}
    k(t) ^ {(1-\alpha)}= \frac{(1-\alpha)\times s\times y(0)}{k(0)^\alpha \times ((1-\alpha)\times (\delta+n+g_B) + g_B )}  \times e^{g_B \times t} +C\times {e^{(\alpha-1)\times (\delta +n+g_B)\times t }}
\end{equation}

Which is equivalent to:
\begin{equation}
    k(t) ^ {(1-\alpha)}= \frac{(1-\alpha)\times s\times y(0)}{k(0)^\alpha \times ((1-\alpha)\times (\delta+n+g_B) + g_B )}  \times e^{g_B \times t} +(k(0)^{1-\alpha} - \frac{(1-\alpha)\times s\times y(0)}{{k(0)^\alpha}\times((1-\alpha)\times (\delta+n+g_B) + g_B )})\times {e^{(\alpha-1)\times (\delta +n+g_B)\times t }}
\end{equation}

Finding of coefficients based on:
https://math.stackexchange.com/questions/2249200/exponential-regression-with-two-terms-and-constraints
https://scikit-guess.readthedocs.io/en/latest/_downloads/4cd313a50f7e08ab81758ce0bd661bc3/Regressions-et-equations-integrales.pdf

```julia
function regression_system(dataframe)
regression_system_matrix = zeros(5,5)

regression_system_matrix[1,1] = sum(dataframe[:, :SSk].^2)
regression_system_matrix[1,2] = sum(dataframe[:, :SSk].*dataframe[:, :Sk])
regression_system_matrix[1,3] = sum(dataframe[:, :SSk].*dataframe[:, :t].^2)
regression_system_matrix[1,4] = sum(dataframe[:, :SSk].*dataframe[:, :t])
regression_system_matrix[1,5] = sum(dataframe[:, :SSk])

regression_system_matrix[2,1] = regression_system_matrix[1,2]
regression_system_matrix[2,2] = sum(dataframe[:, :Sk].^2)
regression_system_matrix[2,3] = sum(dataframe[:, :Sk].*dataframe[:, :t].^2)
regression_system_matrix[2,4] = sum(dataframe[:, :Sk].*dataframe[:, :t])
regression_system_matrix[2,5] = sum(dataframe[:, :Sk])

regression_system_matrix[3,1] = sum(dataframe[:, :SSk].*dataframe[:, :t].^2)
regression_system_matrix[3,2] = sum(dataframe[:, :Sk].*dataframe[:, :t].^2)
regression_system_matrix[3,3] = sum(dataframe[:, :t].^4)
regression_system_matrix[3,4] = sum(dataframe[:, :t].^3)
regression_system_matrix[3,5] = sum(dataframe[:, :t].^2)

regression_system_matrix[4,1] = sum(dataframe[:, :SSk].*dataframe[:, :t])
regression_system_matrix[4,2] = sum(dataframe[:, :Sk].*dataframe[:, :t])
regression_system_matrix[4,3] = sum(dataframe[:, :t].^3)
regression_system_matrix[4,4] = sum(dataframe[:, :t].^2)
regression_system_matrix[4,5] = sum(dataframe[:, :t].^1)

regression_system_matrix[5,1] = sum(dataframe[:, :SSk])
regression_system_matrix[5,2] = sum(dataframe[:, :Sk])
regression_system_matrix[5,3] = sum(dataframe[:, :t].^2)
regression_system_matrix[5,4] = sum(dataframe[:, :t].^1)
regression_system_matrix[5,5] = length(dataframe[:, :t])
# print(regression_system_matrix)

regression_system_vector = zeros(5,1)
regression_system_vector[1] = sum(dataframe[:, :SSk].*dataframe[:, :kalpha])
regression_system_vector[2] = sum(dataframe[:, :Sk].*dataframe[:, :kalpha])
regression_system_vector[3] = sum(dataframe[:, :kalpha].*dataframe[:, :t].^2)
regression_system_vector[4] = sum(dataframe[:, :kalpha].*dataframe[:, :t].^1)
regression_system_vector[5] = sum(dataframe[:, :kalpha])
# print(regression_system_vector)

ABCDE = inv(regression_system_matrix) * regression_system_vector
# print(ABCDE)
A = ABCDE[1]
B = ABCDE[2]

return A, B
end
```

    regression_system (generic function with 1 method)

```julia
function unrelated_coefficients(dataframe,p ,q)
unrelated_coefficient_matrix = zeros(3,3)

unrelated_coefficient_matrix[1,1] = length(dataframe[:, :t])
unrelated_coefficient_matrix[1,2] = sum(exp.(p.*dataframe[:, :t]))
unrelated_coefficient_matrix[1,3] = sum(exp.(q.*dataframe[:, :t]))

unrelated_coefficient_matrix[2,1] = sum(exp.(p.*dataframe[:, :t]))
unrelated_coefficient_matrix[2,2] = sum(exp.(2*p.*dataframe[:, :t]))
unrelated_coefficient_matrix[2,3] = sum(exp.((p+q).*dataframe[:, :t]))

unrelated_coefficient_matrix[3,1] = sum(exp.(q*dataframe[:, :t]))
unrelated_coefficient_matrix[3,2] = sum(exp.((p+q).*dataframe[:, :t]))
unrelated_coefficient_matrix[3,3] = sum(exp.(2*q.*dataframe[:, :t]))
# print(unrelated_coefficient_matrix)

unrelated_coefficient_vector = zeros(3,1)
unrelated_coefficient_vector[1] = sum(dataframe[:, :kalpha])
unrelated_coefficient_vector[2] = sum(dataframe[:, :kalpha].*exp.(p.*dataframe[:, :t]))
unrelated_coefficient_vector[3] = sum(dataframe[:, :kalpha].*exp.(q.*dataframe[:, :t]))
# print(unrelated_coefficient_vector)

abc = inv(unrelated_coefficient_matrix) * unrelated_coefficient_vector
a,b,c = abc
return a,b,c
end
```

    unrelated_coefficients (generic function with 1 method)

Proceed with regression for k

We solve for a,b,c,p,q to get the regression equation:

\begin{equation}
    y = k(t) ^{1-\alpha} = a +b\times e ^{p \times t} +c \times e ^{q \times t}
\end{equation}

Therefore we solve for k(t):
$k(t) = y^\frac{1}{1-\alpha}$

## Parameters for the equation for k(t)

```julia
Botswana_k_reg = Botswana_raw[:,[1,5]]
DataFrames.rename!(Botswana_k_reg, [:k, :t])
Botswana_k_reg = Botswana_k_reg[2:end,:]

Botswana_k_reg[!, :kalpha] = Botswana_k_reg[!,:k].^(1-Botswana_alpha) #already sorted in increasing order of k and t

Botswana_k_reg[!, :Sk] = convert(UnitRange{Float64},0:(size(Botswana_k_reg[!,:k])[1]-1))
Botswana_k_reg[!, :SSk] = convert(UnitRange{Float64},0:(size(Botswana_k_reg[!,:k])[1]-1))

for i in 1:(size(Botswana_k_reg[!,:k])[1]-1)
    Botswana_k_reg[i+1, :Sk] = Botswana_k_reg[i, :Sk] + 0.5*(Botswana_k_reg[i+1, :kalpha]+Botswana_k_reg[i, :kalpha])*(Botswana_k_reg[i+1, :t]-Botswana_k_reg[i, :t])
    Botswana_k_reg[i+1, :SSk] = Botswana_k_reg[i, :SSk] + 0.5*(Botswana_k_reg[i+1, :Sk]+Botswana_k_reg[i, :Sk])*(Botswana_k_reg[i+1, :t]-Botswana_k_reg[i, :t])
end
# last(Botswana_k_reg,5)

Botswana_A,Botswana_B = regression_system(Botswana_k_reg)

Botswana_p = 0.5(Botswana_B+sqrt(Botswana_B^2+4*Botswana_A))
Botswana_q = 0.5(Botswana_B-sqrt(Botswana_B^2+4*Botswana_A))
print(" p = ", Botswana_p,"\n q = ",Botswana_q)

Botswana_a,Botswana_b,Botswana_c = unrelated_coefficients(Botswana_k_reg, Botswana_p, Botswana_q)
print("\n a = ", Botswana_a,"\n b = ",Botswana_b, "\n c = ",Botswana_c)

#solving for predicted values of k
Botswana_k_reg[!,:k_pred] = (Botswana_a .+ Botswana_b .* exp.(Botswana_p.*Botswana_k_reg[!,:t]) .+ Botswana_c .* exp.(Botswana_q.*Botswana_k_reg[!,:t])).^(1/(1-Botswana_alpha))
Botswana_k_reg
```

     p = 0.1803856004081679
     q = 0.06811716963609693
     a = 2.219184453549694e-5
     b = 7.323800151796328e-6
     c = 4.7500769184909135e-5

	k	t	kalpha	Sk	SSk	k_pred

	Float64?	Int64	Float64	Float64	Float64	Float64

34 rows × 6 columns

1	0.00408493	2	0.000113624	0.0	0.0	0.00347823

2	0.00404858	3	0.00011196	0.000112792	5.6396e-5	0.00361935

3	0.00402169	4	0.000110735	0.000224139	0.000224862	0.0037726

4	0.00407305	5	0.000113079	0.000336046	0.000504954	0.00393934

5	0.00424262	6	0.000120958	0.000453065	0.000899509	0.00412109

6	0.00457454	7	0.000136978	0.000582033	0.00141706	0.00431958

7	0.00477105	8	0.00014683	0.000723937	0.00207004	0.00453673

8	0.00494978	9	0.000156023	0.000875363	0.00286969	0.00477474

9	0.00482787	10	0.000149729	0.00102824	0.00382149	0.00503608

10	0.00486212	11	0.000151487	0.00117885	0.00492504	0.00532351

11	0.00494681	12	0.000155868	0.00133252	0.00618072	0.00564016

12	0.00521229	13	0.000169921	0.00149542	0.00759469	0.00598952

13	0.00543057	14	0.00018183	0.00167129	0.00917805	0.00637554

14	0.00581681	15	0.000203676	0.00186405	0.0109457	0.00680262

15	0.0067093	16	0.000257812	0.00209479	0.0129251	0.00727571

16	0.00791826	17	0.000338934	0.00239316	0.0151691	0.00780031

17	0.00870503	18	0.000396323	0.00276079	0.0177461	0.00838262

18	0.00936606	19	0.000447236	0.00318257	0.0207178	0.00902954

19	0.01013	20	0.000509057	0.00366072	0.0241394	0.00974877

20	0.0109341	21	0.000577488	0.00420399	0.0280718	0.0105489

21	0.0119173	22	0.000665717	0.00482559	0.0325866	0.0114396

22	0.0128182	23	0.000750846	0.00553388	0.0377663	0.0124315

23	0.013753	24	0.000843399	0.006331	0.0436987	0.0135365

24	0.0149094	25	0.000963675	0.00723453	0.0504815	0.014768

25	0.0163178	26	0.00111857	0.00827566	0.0582366	0.0161408

26	0.0177838	27	0.00128931	0.00947959	0.0671142	0.0176713

27	0.0193387	28	0.0014807	0.0108646	0.0772863	0.0193782

28	0.0209827	29	0.00169424	0.0124521	0.0889447	0.0212817

29	0.0228039	30	0.00194386	0.0142711	0.102306	0.023405

30	0.0253333	31	0.0023126	0.0163993	0.117641	0.0257734

⋮	⋮	⋮	⋮	⋮	⋮	⋮

The simplest value to compare is to $g_B$ from the regression of $y(t)$, which should correspond to $p$ in the regression of $k(t)$. These values do not match.

# Fitting of values using linear regression

Using each linear regression to regenerate the values of k(t), y(t) and e(t) from initial conditions, we find that the regressions actually fit the data well despite the regression coefficients/ Green Solow model parameters being inconsistent between equations. This suggests that it may be difficult to fit all three equations with constant and consistent parameters.

```julia
Botswana_pred = Botswana_k_reg[:,[1,2]]
DataFrames.rename!(Botswana_pred, [:k,:t])
Botswana_pred[:,:k_pred] = Botswana_k_reg[!,:k_pred]

Botswana_pred[!,:y_pred] = Botswana_y_reg[1,:y].*exp.(coef(ols_y_Botswana)[2]*log.(Botswana_k_reg[!,:k_pred]./Botswana_k_reg[1,:k_pred])
            .+ coef(ols_y_Botswana)[1]
            .+ coef(ols_y_Botswana)[3].*Botswana_k_reg[!,:t])

Botswana_pred[!,:e_pred] = Botswana_e_reg[1,:e].*exp.(coef(ols_e_Botswana)[2]*log.(Botswana_k_reg[!,:k_pred]./Botswana_k_reg[1,:k_pred])
            .+ coef(ols_e_Botswana)[1]
            .+ coef(ols_e_Botswana)[3].*Botswana_k_reg[!,:t])
Botswana_pred[!,:y_actual] = Botswana_y_reg[!,:y]
Botswana_pred[!,:e_actual] = Botswana_e_reg[!,:e]
Botswana_pred

```

	k	t	k_pred	y_pred	e_pred	y_actual	e_actual

	Float64?	Int64	Float64	Float64	Float64	Float64?	Float64?

34 rows × 7 columns

1	0.00408493	2	0.00347823	0.0012086	0.629157	0.001223	0.252264

2	0.00404858	3	0.00361935	0.00128426	0.667513	0.001381	0.77152

3	0.00402169	4	0.0037726	0.00136315	0.707534	0.001358	0.975694

4	0.00407305	5	0.00393934	0.00144521	0.74921	0.001537	0.99993

5	0.00424262	6	0.00412109	0.00153036	0.792518	0.001613	1.08941

6	0.00457454	7	0.00431958	0.00161848	0.837424	0.001765	1.09863

7	0.00477105	8	0.00453673	0.00170944	0.883881	0.001858	1.08385

8	0.00494978	9	0.00477474	0.00180307	0.931829	0.001921	1.14252

9	0.00482787	10	0.00503608	0.00189915	0.981196	0.002144	1.03443

10	0.00486212	11	0.00532351	0.00199747	1.0319	0.0023	1.01324

11	0.00494681	12	0.00564016	0.00209777	1.08384	0.002387	1.08339

12	0.00521229	13	0.00598952	0.00219978	1.13693	0.002485	0.960533

13	0.00543057	14	0.00637554	0.00230321	1.19104	0.002619	1.0732

14	0.00581681	15	0.00680262	0.00240776	1.24607	0.002937	1.08476

15	0.0067093	16	0.00727571	0.00251315	1.30189	0.003216	1.14918

16	0.00791826	17	0.00780031	0.00261906	1.35841	0.003304	2.1003

17	0.00870503	18	0.00838262	0.00272522	1.4155	0.00336	1.98788

18	0.00936606	19	0.00902954	0.00283136	1.47305	0.003354	2.03849

19	0.01013	20	0.00974877	0.00293723	1.53098	0.003311	2.28547

20	0.0109341	21	0.0105489	0.00304261	1.58919	0.003321	2.1147

21	0.0119173	22	0.0114396	0.00314732	1.64761	0.003367	2.07414

22	0.0128182	23	0.0124315	0.00325119	1.70618	0.003458	1.83261

23	0.013753	24	0.0135365	0.0033541	1.76485	0.003589	1.81871

24	0.0149094	25	0.014768	0.00345596	1.82359	0.003704	2.12226

25	0.0163178	26	0.0161408	0.0035567	1.88238	0.003845	1.963

26	0.0177838	27	0.0176713	0.00365631	1.9412	0.004084	2.30061

27	0.0193387	28	0.0193782	0.00375478	2.00006	0.004211	2.29916

28	0.0209827	29	0.0212817	0.00385214	2.05898	0.004339	2.33404

29	0.0228039	30	0.023405	0.00394842	2.11799	0.004429	2.20731

30	0.0253333	31	0.0257734	0.00404371	2.17711	0.004489	2.20785

⋮	⋮	⋮	⋮	⋮	⋮	⋮	⋮

```julia
pred = Array(Botswana_pred[!, [:k_pred, :y_pred, :e_pred]])
kdata = Botswana_pred[!, :k]
ydata = Botswana_pred[!, :y_actual]
edata = Botswana_pred[!, :e_actual]
Botswana_k_pred = identity.(Botswana_pred[!, :k_pred])
Botswana_y_pred = identity.(Botswana_pred[!, :y_pred])
Botswana_e_pred = identity.(Botswana_pred[!, :e_pred])
```

    34-element Array{Float64,1}:
     0.6291565333192833
     0.667512851125945
     0.7075342173803375
     0.7492100461252883
     0.7925181444917635
     0.8374240803851268
     0.8838808157099484
     0.9318286654130445
     0.9811956344216893
     1.0318981703574344
     1.0838423498252345
     1.1369254910273006
     1.1910381572112592
     ⋮
     1.764854150791789
     1.823592452602984
     1.8823765794593053
     1.9411986851174328
     2.0000628994854885
     2.058984220764798
     2.117987277222114
     2.1771050270471943
     2.236377455034811
     2.295850313452482
     2.3555739426973594
     2.415602196187065

```julia
#checking the implementation of MSE
# println("(Botswana Mean Squared Errors) kt: ", Flux.mse(Botswana_k_reg[!, :k_pred], Botswana_k_reg[!, :k]),
#     " yt: ", Flux.mse(Botswana_y_pred, Botswana_y_reg[!, :y]),
#     " et: ", Flux.mse(Botswana_e_pred, Botswana_e_reg[!, :e]))
println("(Botswana Mean Squared Errors) kt: ", (sqL2dist(Botswana_k_reg[!, :k_pred], identity.(Botswana_k_reg[!, :k]))/length(Botswana_k_reg[!, :k])),
    " yt: ", (sqL2dist(Botswana_y_pred, identity.(Botswana_y_reg[!, :y]))/length(Botswana_y_reg[!, :y])),
    " et: ", (sqL2dist(Botswana_e_pred, identity.(Botswana_e_reg[!, :e]))/length(Botswana_e_reg[!, :e])))
println("(Botswana Root Mean Squared Errors) kt: ", (L2dist(Botswana_k_reg[!, :k_pred], identity.(Botswana_k_reg[!, :k]))/length(Botswana_k_reg[!, :k])),
    " yt: ", (L2dist(Botswana_y_pred, identity.(Botswana_y_reg[!, :y]))/length(Botswana_y_reg[!, :y])),
    " et: ", (L2dist(Botswana_e_pred, identity.(Botswana_e_reg[!, :e]))/length(Botswana_e_reg[!, :e])))
#checking the implementation of MAE
# println("(Botswana Mean Absolute Errors) kt: ", Flux.mae(Botswana_k_reg[!, :k_pred], Botswana_k_reg[!, :k]),
#     " yt: ", Flux.mae(Botswana_y_pred, Botswana_y_reg[!, :y]),
#     " et: ", Flux.mae(Botswana_e_pred, Botswana_e_reg[!, :e]))
println("(Botswana Mean Absolute Errors) kt: ",
    L1dist(convert(Array{Float64},Botswana_k_reg[!, :k_pred]),identity.(Botswana_k_reg[!, :k]))/length(Botswana_k_reg[!, :k]),
    " yt: ", L1dist(convert(Array{Float64},Botswana_y_pred),identity.(Botswana_y_reg[!, :y]))/length(Botswana_y_reg[!, :y]),
    " et: ", L1dist(convert(Array{Float64},Botswana_e_pred),identity.(Botswana_e_reg[!, :e]))/length(Botswana_e_reg[!, :e]))

function r2_impl(data,pred)
tss = sum((data .-mean(data)).^2)
rss = sum((data .-pred).^2)
r2 = 1- rss/tss
return r2
end
#checking the implementation of R2
# println("(Botswana R2 Correlation Coefficient) yt: ", r2(ols_y_Botswana),
#     " et: ", r2(ols_e_Botswana))
# println("(Botswana R2 Correlation Coefficient) yt: ", r2_impl(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana)),
#     " et: ", r2_impl(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana)))
println("(Botswana R2 Correlation Coefficient) kt: ", r2_impl(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred]),
    " yt: ", r2_impl(Botswana_y_reg[!, :y], Botswana_y_pred),
    " et: ", r2_impl(Botswana_e_reg[!, :e], Botswana_e_pred))

function Ar2_impl(data,pred, p)
tss = sum((data .-mean(data)).^2)
rss = sum((data .-pred).^2)
r2 = 1- rss/tss
n = size(data)[1]
ar2 = 1 - abs((1 - r2)*(n-1)/(n-p-1))
return ar2
end

#checking the implementation of adjusted R2
# println("(Botswana Adjusted R2) yt: ", adjr2(ols_y_Botswana),
#     " et: ", adjr2(ols_e_Botswana))
# println("(Botswana Adjusted R2) yt: ", Ar2_impl(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana),2),
#     " et: ", Ar2_impl(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana),2))
# 2 parameters are coeff of lge, coeff of t, y intercept is excluded
# for k, there are 4 parameters excluding intercept
println("(Botswana Adjusted R2) kt: ", Ar2_impl(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred], 4),
    " yt: ", Ar2_impl(Botswana_y_reg[!, :y], Botswana_y_pred, 2),
    " et: ", Ar2_impl(Botswana_e_reg[!, :e], Botswana_e_pred, 2))

println("(Botswana Mean Percentage Error) kt: ", mean((Botswana_k_reg[!, :k].- Botswana_k_reg[!, :k_pred])./Botswana_k_reg[!, :k])*100,
    " yt: ", mean((Botswana_y_reg[!, :y].- Botswana_y_pred)./Botswana_y_reg[!, :y])*100,
    " et: ", mean((Botswana_e_reg[!, :e].- Botswana_e_pred)./Botswana_e_reg[!, :e])*100)

println("(Botswana Mean Absolute Percentage Error) kt: ", mean(abs.((Botswana_k_reg[!, :k].- Botswana_k_reg[!, :k_pred])./Botswana_k_reg[!, :k]))*100,
    " yt: ", mean(abs.((Botswana_y_reg[!, :y].- Botswana_y_pred)./Botswana_y_reg[!, :y]))*100,
    " et: ", mean(abs.((Botswana_e_reg[!, :e].- Botswana_e_pred)./Botswana_e_reg[!, :e]))*100)

println("(Botswana Mean Arctangent Absolute Percentage Error) kt: ", mean(atan.(abs.((Botswana_k_reg[!, :k].- Botswana_k_reg[!, :k_pred])./Botswana_k_reg[!, :k])))*100,
    " yt: ", mean(atan.(abs.((Botswana_y_reg[!, :y].- Botswana_y_pred)./Botswana_y_reg[!, :y])))*100,
    " et: ", mean(atan.(abs.((Botswana_e_reg[!, :e].- Botswana_e_pred)./Botswana_e_reg[!, :e])))*100)

println("(Botswana Mean Bias Error) kt: ", mean(Botswana_k_reg[!, :k].- Botswana_k_reg[!, :k_pred]),
    " yt: ", mean(Botswana_y_reg[!, :y].- Botswana_y_pred),
    " et: ", mean(Botswana_e_reg[!, :e].- Botswana_e_pred))

function loglikelihood_calc(data,pred)
rss = sum((data .-pred).^2)
n = length(pred)
return -n/2*(log(2pi*rss/n)+1)
end
# implementation from julia: https://github.com/JuliaStats/GLM.jl/blob/950579166c52ff1cbbeab75cbc23235b30640802/src/lm.jl

#checking implementation for loglikelihood
# println("(Botswana Loglikelihood) yt: ", loglikelihood(ols_y_Botswana),
#     " et: ", loglikelihood(ols_e_Botswana))
# println("(Botswana Loglikelihood) yt: ", loglikelihood_calc(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana)),
#     " et: ", loglikelihood_calc(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana)))
println("(Botswana Loglikelihood) kt: ", loglikelihood_calc(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred]),
    " yt: ", loglikelihood_calc(Botswana_y_reg[!, :y], Botswana_y_pred),
    " et: ", loglikelihood_calc(Botswana_e_reg[!, :e], Botswana_e_pred))

function aic_calc(data, pred, params)
    L = loglikelihood_calc(data,pred)
    return 2*params-2*L
end

#checking implementation for aic
# println("(Botswana Aikaike Information Criterion) yt: ", aic(ols_y_Botswana),
#     " et: ", aic(ols_e_Botswana))
# println("(Botswana Aikaike Information Criterion) yt: ", aic_calc(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana),4),
#     " et: ", aic_calc(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana),4))
# 4 degrees of freedom in the model: intercept, two coefficients and variance

println("(Botswana Aikaike Information Criterion) kt: ", aic_calc(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred], 6),
    " yt: ", aic_calc(Botswana_y_reg[!, :y], Botswana_y_pred, 4),
    " et: ", aic_calc(Botswana_e_reg[!, :e], Botswana_e_pred, 4))

function aicc_calc(data, pred, params)
    n = length(pred)
    L = loglikelihood_calc(data,pred)
    return -2*L + 2*params + 2*params*(params+1)/(n-params-1)
end

# checking implementation for aicc
# println("(Botswana Corrected AIC) yt: ", aicc(ols_y_Botswana),
#     " et: ", aicc(ols_e_Botswana))
# println("(Botswana Corrected AIC) yt: ", aicc_calc(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana),4),
#     " et: ", aicc_calc(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana),4))
# 4 degrees of freedom in the model: intercept, two coefficients and variance

println("(Botswana Corrected AIC) kt: ", aicc_calc(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred], 6),
    " yt: ", aicc_calc(Botswana_y_reg[!, :y], Botswana_y_pred, 4),
    " et: ", aicc_calc(Botswana_e_reg[!, :e], Botswana_e_pred, 4))

function bic_calc(data, pred, params)
    n = length(pred)
    L = loglikelihood_calc(data,pred)
    return -2*L + params*log(n)
end

# checking implementation for bic_calc
# println("(Botswana Corrected BIC) yt: ", bic(ols_y_Botswana),
#     " et: ", bic(ols_e_Botswana))
# println("(Botswana Corrected BIC) yt: ", bic_calc(Botswana_y_reg[!, :lgyty0], predict(ols_y_Botswana),4),
#     " et: ", bic_calc(Botswana_e_reg[!, :lgete0], predict(ols_e_Botswana),4))
# 4 degrees of freedom in the model: intercept, two coefficients and variance

println("(Botswana BIC) kt: ", bic_calc(Botswana_k_reg[!, :k], Botswana_k_reg[!, :k_pred], 6),
    " yt: ", bic_calc(Botswana_y_reg[!, :y], Botswana_y_pred, 4),
    " et: ", bic_calc(Botswana_e_reg[!, :e], Botswana_e_pred, 4))
```

    (Botswana Mean Squared Errors) kt: 1.8353243246405207e-7 yt: 1.334718112850297e-7 et: 0.09664974444185301
    (Botswana Root Mean Squared Errors) kt: 7.347116930831402e-5 yt: 6.265494001579784e-5 et: 0.05331640969164598
    (Botswana Mean Absolute Errors) kt: 0.0003581956547092669 yt: 0.000319080997829496 et: 0.23805821661076648
    (Botswana R2 Correlation Coefficient) kt: 0.998029611575365 yt: 0.8874003363994728 et: 0.7366721156280416
    (Botswana Adjusted R2) kt: 0.9977578338616222 yt: 0.8801358419736324 et: 0.7196832198621088
    (Botswana Mean Percentage Error) kt: -0.31342874337945087 yt: 9.847689574383578 et: 5.508468521008606
    (Botswana Mean Absolute Percentage Error) kt: 5.098749601865523 yt: 9.870001593624838 et: 18.31824286508371
    (Botswana Mean Arctangent Absolute Percentage Error) kt: 5.076341761766376 yt: 9.813879491797739 et: 16.566547053527106
    (Botswana Mean Bias Error) kt: -6.61183866914205e-6 yt: 0.00031877800060819977 et: 0.16692422034373902
    (Botswana Loglikelihood) kt: 215.44095537476974 yt: 220.8554739290611 et: -8.520660931592296
    (Botswana Aikaike Information Criterion) kt: -418.8819107495395 yt: -433.7109478581222 et: 25.041321863184592
    (Botswana Corrected AIC) kt: -415.7707996384284 yt: -432.33163751329465 et: 26.42063220801218
    (Botswana BIC) kt: -409.72374760184255 yt: -427.60550575965755 et: 31.14676396164924

```julia
using LaTeXStrings
using Plots

```

```julia
pred[:,1:2]
```

    34×2 Array{Float64,2}:
     0.00347823  0.0012086
     0.00361935  0.00128426
     0.0037726   0.00136315
     0.00393934  0.00144521
     0.00412109  0.00153036
     0.00431958  0.00161848
     0.00453673  0.00170944
     0.00477474  0.00180307
     0.00503608  0.00189915
     0.00532351  0.00199747
     0.00564016  0.00209777
     0.00598952  0.00219978
     0.00637554  0.00230321
     ⋮
     0.0135365   0.0033541
     0.014768    0.00345596
     0.0161408   0.0035567
     0.0176713   0.00365631
     0.0193782   0.00375478
     0.0212817   0.00385214
     0.023405    0.00394842
     0.0257734   0.00404371
     0.0284155   0.00413806
     0.0313629   0.00423158
     0.0346511   0.00432437
     0.0383194   0.00441654

```julia
function plot_graphmodel1(nnpred,country,nntstepsfull,kdata,ydata,edata)
        upscale = 0.9 #8x upscaling in resolution
    fntsm = Plots.font("sans-serif", pointsize=round(12.0*upscale))
    fntlg = Plots.font("sans-serif", pointsize=round(16.0*upscale))
    default(titlefont=fntlg, guidefont=fntlg, tickfont=fntsm, legendfont=fntsm)
    default(size=(550*upscale,400*upscale)) #Plot canvas size
    default(dpi=150)

#     fctime = collect(Int(floor(size(nntstepsfull,1)*0.8))+1:1:size(nntstepsfull,1))
#             println(fctime)
#             println(nntstepsfull)
    plotkyenn12ic= scatter(xaxis=nntstepsfull,nnpred[:,1:2],
        label=[L"k_{sol}" L"y_{sol}"],color=[:red :blue],legend=(0.102,0.955),
        markershape=[:circle :diamond],markersize=4,
        ylabel=L"k^c_t,y^t_c",right_margin = 15Plots.mm)

    plot!(plotkyenn12ic,[kdata,ydata],label=[L"k_{data}" L"y_{data}"],linestyle=[:solid :dash],
        color=[:red :blue],ylim=(0,1.5.*round(maximum(kdata);sigdigits=1)),foreground_color_legend = nothing)

#     scatter!(plotkyenn12ic,fctime,nnpred[1:2,fctime]',
#         color=[:red :blue],markershape=[:circle :diamond], markersize=4,label=nothing) #markersize = 8 for predict

    pr = twinx()

    scatter!(pr,nntstepsfull,nnpred[:,3],label=L"e_{sol}",
        color=:green,legend=(0.89,0.954), markershape = [:utriangle], markersize=4, right_margin = 15Plots.mm,
        foreground_color_legend = nothing,background_color_legend = nothing)

# #     scatter!(pr,fctime,nnpred[3,fctime],
# #         label=L"e_{sol}",color=:green,legend=(0.89,0.954), markershape = [:utriangle], markersize=4,
# #         ylabel=L"e^t_c",right_margin = 15Plots.mm,
# #         foreground_color_legend = nothing,background_color_legend = nothing)

    plot!(pr,edata,label=L"e_{data}",color=:green,ylim=(0,1.7.*round(maximum(edata);sigdigits=1)),
                linestyle=:dot)

    xpts = collect(0:5:5*ceil(length(nntstepsfull)/5))
#     if xpts[end] != length(nntsteps)
#         push!(xpts,length(nntsteps))
        xpts[1]=1
#     end

   plot(plotkyenn12ic,xlabel = "years",xticks=xpts,box=:on,linewidth=2*upscale)
#     display(StatsPlots.plot(pl,xlabel = "Days post 21 March 2020",xticks=0:10:110,tickfont=12,
#         guidefont = 16,legendfontsize=12,legend=(0.1,0.92),
#         dpi=300,box=:on,linewidth=2*upscale))
# file_dir1 = @__DIR__
#     savefig(string(file_dir1,"/",country,"model1_maxdata"))
end

plot_graphmodel1(pred,"Botswana",range(1, 34, length = 34),kdata,ydata,edata)
```

```julia

```

```julia

```


# ヤコビ行列の計算

```python
import sympy as sy
from sympy import sqrt, sin, cos

l1, l2, l3 = sy.symbols("l1, l2, l3")
lam, phi, theta = sy.symbols("lam, phi, theta")
xi = sy.Symbol("xi")

L0, r = sy.symbols("L0, r")

q_vec = sy.Matrix([[l1, l2, l3]]).T
c_vec = sy.Matrix([[lam, phi, theta]]).T
```

```python
def mapping_from_actuator_to_configuration(q, xi):
    """アクチュエータ空間から配置空間への写像"""

    l1 = q[0,0]
    l2 = q[1,0]
    l3 = q[2,0]

    A1 = l1**2 + l2**2 + l3**2 - \
        l1*l2 - l1*l3 - l2*l3
    A2 = 2*l1 - l2 - l3
    A3 = l2 - l3
    A4 = 3*L0 + l1 + l2 + l3

    lam = A4 / 2*sqrt(A1)
    phi = 2*sqrt(A1) / 3*r
    theta = sy.atan(sqrt(3) * (-A3) / (-A2))

    return sy.Matrix([[lam, phi, theta]]).T

def mapping_from_configration_to_task_p(c, xi):
    """配置空間からタスク空間pへの写像"""

    lam = c[0, 0]
    phi = c[1, 0]
    theta = c[2, 0]

    return sy.Matrix([
        [lam * cos(theta) * (1 - cos(xi * phi))],
        [lam * sin(theta) * (1 - cos(xi * phi))],
        [lam * sin(xi * phi)],
    ])
```

配置空間のアクチュエータ空間による偏微分

```python
c = mapping_from_actuator_to_configuration(q_vec, xi)
Jc = c.jacobian(q_vec)
Jc
```

$\displaystyle \left[\begin{matrix}\frac{\left(l_{1} - \frac{l_{2}}{2} - \frac{l_{3}}{2}\right) \left(\frac{3 L_{0}}{2} + \frac{l_{1}}{2} + \frac{l_{2}}{2} + \frac{l_{3}}{2}\right)}{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} + \frac{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{2} & \frac{\left(- \frac{l_{1}}{2} + l_{2} - \frac{l_{3}}{2}\right) \left(\frac{3 L_{0}}{2} + \frac{l_{1}}{2} + \frac{l_{2}}{2} + \frac{l_{3}}{2}\right)}{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} + \frac{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{2} & \frac{\left(- \frac{l_{1}}{2} - \frac{l_{2}}{2} + l_{3}\right) \left(\frac{3 L_{0}}{2} + \frac{l_{1}}{2} + \frac{l_{2}}{2} + \frac{l_{3}}{2}\right)}{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} + \frac{\sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{2}\\\frac{2 r \left(l_{1} - \frac{l_{2}}{2} - \frac{l_{3}}{2}\right)}{3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{2 r \left(- \frac{l_{1}}{2} + l_{2} - \frac{l_{3}}{2}\right)}{3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{2 r \left(- \frac{l_{1}}{2} - \frac{l_{2}}{2} + l_{3}\right)}{3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}\\\frac{2 \sqrt{3} \left(- l_{2} + l_{3}\right)}{\left(\frac{3 \left(- l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} + 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} & \frac{- \frac{\sqrt{3} \left(- l_{2} + l_{3}\right)}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} - \frac{\sqrt{3}}{- 2 l_{1} + l_{2} + l_{3}}}{\frac{3 \left(- l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} + 1} & \frac{- \frac{\sqrt{3} \left(- l_{2} + l_{3}\right)}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} + \frac{\sqrt{3}}{- 2 l_{1} + l_{2} + l_{3}}}{\frac{3 \left(- l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}} + 1}\end{matrix}\right]$

```python
print(Jc)
```

    Matrix([[(l1 - l2/2 - l3/2)*(3*L0/2 + l1/2 + l2/2 + l3/2)/sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/2, (-l1/2 + l2 - l3/2)*(3*L0/2 + l1/2 + l2/2 + l3/2)/sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/2, (-l1/2 - l2/2 + l3)*(3*L0/2 + l1/2 + l2/2 + l3/2)/sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/2], [2*r*(l1 - l2/2 - l3/2)/(3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), 2*r*(-l1/2 + l2 - l3/2)/(3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), 2*r*(-l1/2 - l2/2 + l3)/(3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))], [2*sqrt(3)*(-l2 + l3)/((3*(-l2 + l3)**2/(-2*l1 + l2 + l3)**2 + 1)*(-2*l1 + l2 + l3)**2), (-sqrt(3)*(-l2 + l3)/(-2*l1 + l2 + l3)**2 - sqrt(3)/(-2*l1 + l2 + l3))/(3*(-l2 + l3)**2/(-2*l1 + l2 + l3)**2 + 1), (-sqrt(3)*(-l2 + l3)/(-2*l1 + l2 + l3)**2 + sqrt(3)/(-2*l1 + l2 + l3))/(3*(-l2 + l3)**2/(-2*l1 + l2 + l3)**2 + 1)]])

タスク空間の配置空間による偏微分

```python
p = mapping_from_configration_to_task_p(c_vec, xi)
Jp = p.jacobian(c_vec)
Jp
```

$\displaystyle \left[\begin{matrix}\left(1 - \cos{\left(\phi \xi \right)}\right) \cos{\left(\theta \right)} & lam \xi \sin{\left(\phi \xi \right)} \cos{\left(\theta \right)} & - lam \left(1 - \cos{\left(\phi \xi \right)}\right) \sin{\left(\theta \right)}\\\left(1 - \cos{\left(\phi \xi \right)}\right) \sin{\left(\theta \right)} & lam \xi \sin{\left(\theta \right)} \sin{\left(\phi \xi \right)} & lam \left(1 - \cos{\left(\phi \xi \right)}\right) \cos{\left(\theta \right)}\\\sin{\left(\phi \xi \right)} & lam \xi \cos{\left(\phi \xi \right)} & 0\end{matrix}\right]$

```python
print(Jp)
```

    Matrix([[(1 - cos(phi*xi))*cos(theta), lam*xi*sin(phi*xi)*cos(theta), -lam*(1 - cos(phi*xi))*sin(theta)], [(1 - cos(phi*xi))*sin(theta), lam*xi*sin(theta)*sin(phi*xi), lam*(1 - cos(phi*xi))*cos(theta)], [sin(phi*xi), lam*xi*cos(phi*xi), 0]])

いっぺんに計算

```python
p_zenbu = mapping_from_configration_to_task_p(c, xi)

J_all = p_zenbu.jacobian(q_vec)
J_all.simplify()
```

```python
J_all
```

$\displaystyle \left[\begin{matrix}\frac{\left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(36 \left(l_{2} - l_{3}\right)^{2} \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) + 2 \left(- r \xi \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 6 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin^{2}{\left(\frac{r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} + 3 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2} \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right)\right)}{12 \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{5}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{5} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{\left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 18 \left(\left(- l_{2} + l_{3}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) + \left(l_{2} - l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) + 2 \left(- r \xi \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 6 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin^{2}{\left(\frac{r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} + 3 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right)\right)}{12 \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{5}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{5} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{\left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 36 \left(- l_{1} + l_{2}\right) \left(l_{2} - l_{3}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) + 2 \left(- r \xi \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 6 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin^{2}{\left(\frac{r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} + 3 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right)\right)}{12 \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{5}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{5} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}\\\frac{\sqrt{3} \left(l_{2} - l_{3}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right)^{2} \left(2 r \xi \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2} \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 36 \left(l_{2} - l_{3}\right)^{2} \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) - 3 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2} \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) + 6 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) + 12 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right)\right)}{12 \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{7}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{8} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{\sqrt{3} \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{3}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2} \left(18 \left(l_{2} - l_{3}\right) \left(\left(- l_{2} + l_{3}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) + \left(l_{2} - l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) - 3 \left(l_{2} - l_{3}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) - 6 \left(l_{2} - l_{3}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) + 2 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(r \xi \left(l_{2} - l_{3}\right) \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 3 \left(l_{2} - l_{3}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} + 3 \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}\right)}{12 \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right)^{3} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{\sqrt{3} \left(\frac{3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}{\left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}}\right)^{\frac{3}{2}} \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2} \left(3 \left(- l_{1} + l_{2}\right) \left(l_{2} - l_{3}\right)^{2} \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right) - \frac{\left(l_{2} - l_{3}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right)}{4} - \frac{\left(l_{2} - l_{3}\right) \left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \left(l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}\right)}{2} + \frac{\left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right) \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(r \xi \left(l_{2} - l_{3}\right) \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 3 \left(l_{2} - l_{3}\right) \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} - 3 \left(\cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} - 1\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{6}\right)}{\left(3 \left(l_{2} - l_{3}\right)^{2} + \left(- 2 l_{1} + l_{2} + l_{3}\right)^{2}\right)^{3} \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}\\\frac{2 \left(- r \xi \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} - 3 \left(- 2 l_{1} + l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}}{12 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{2 \left(- r \xi \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} - 3 \left(l_{1} - 2 l_{2} + l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}}{12 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}} & \frac{2 \left(- r \xi \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \cos{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)} + 3 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}\right) \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}} - 3 \left(l_{1} + l_{2} - 2 l_{3}\right) \left(3 L_{0} + l_{1} + l_{2} + l_{3}\right) \sin{\left(\frac{2 r \xi \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}{3} \right)}}{12 \sqrt{l_{1}^{2} - l_{1} l_{2} - l_{1} l_{3} + l_{2}^{2} - l_{2} l_{3} + l_{3}^{2}}}\end{matrix}\right]$

```python
print(J_all)
```

    Matrix([[(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(36*(l2 - l3)**2*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 2*(-r*xi*(-2*l1 + l2 + l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 6*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3)**2)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 3*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)**2*(3*L0 + l1 + l2 + l3))/(12*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(5/2)*(-2*l1 + l2 + l3)**5*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), (3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-18*((-l2 + l3)*(-2*l1 + l2 + l3) + (l2 - l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 2*(-r*xi*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 6*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3)**2)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 3*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3))/(12*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(5/2)*(-2*l1 + l2 + l3)**5*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), (3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-36*(-l1 + l2)*(l2 - l3)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 2*(-r*xi*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 6*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3)**2)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 3*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3))/(12*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(5/2)*(-2*l1 + l2 + l3)**5*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))], [sqrt(3)*(l2 - l3)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)**2*(2*r*xi*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)**2*(3*L0 + l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 36*(l2 - l3)**2*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)**2*(3*L0 + l1 + l2 + l3) + 6*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 12*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))/(12*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(7/2)*(-2*l1 + l2 + l3)**8*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), sqrt(3)*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(3/2)*(-2*l1 + l2 + l3)**2*(18*(l2 - l3)*((-l2 + l3)*(-2*l1 + l2 + l3) + (l2 - l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(l2 - l3)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3) - 6*(l2 - l3)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 2*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)*(r*xi*(l2 - l3)*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 3*(l2 - l3)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) + 3*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))/(12*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)**3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), sqrt(3)*((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)/(-2*l1 + l2 + l3)**2)**(3/2)*(-2*l1 + l2 + l3)**2*(3*(-l1 + l2)*(l2 - l3)**2*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - (l2 - l3)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(-2*l1 + l2 + l3)*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3)/4 - (l2 - l3)*(3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/2 + (3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)*(-2*l1 + l2 + l3)*(r*xi*(l2 - l3)*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 3*(l2 - l3)*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) - 1)*(3*L0 + l1 + l2 + l3)*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/6)/((3*(l2 - l3)**2 + (-2*l1 + l2 + l3)**2)**3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))], [(2*(-r*xi*(-2*l1 + l2 + l3)*(3*L0 + l1 + l2 + l3)*cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(-2*l1 + l2 + l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))/(12*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), (2*(-r*xi*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3)*cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(l1 - 2*l2 + l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))/(12*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)), (2*(-r*xi*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3)*cos(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3) + 3*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2) - 3*(l1 + l2 - 2*l3)*(3*L0 + l1 + l2 + l3)*sin(2*r*xi*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2)/3))/(12*sqrt(l1**2 - l1*l2 - l1*l3 + l2**2 - l2*l3 + l3**2))]])


```python
import numpy as np
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import matplotlib.pyplot as plt
```

```python
nx = 81 # tente mudar este número de 41 para 81 e rodar tudo novamente ... o que acontece?
dx = 2/(nx-1)
nt = 25
dt = .02
c = 1 # suponha velocidade da onda c = 1
x = np.linspace(0,2,nx)
u = np.ones(nx)      # numpy function ones()
u[int(.5 / dx):int(1 / dx + 1)] = 2  # setting u = 2 between 0.5 and 1 as per our I.C.s
print(x)
print(u)
plt.plot(x,u,'o-')
plt.grid()
```

    [0.    0.025 0.05  0.075 0.1   0.125 0.15  0.175 0.2   0.225 0.25  0.275
     0.3   0.325 0.35  0.375 0.4   0.425 0.45  0.475 0.5   0.525 0.55  0.575
     0.6   0.625 0.65  0.675 0.7   0.725 0.75  0.775 0.8   0.825 0.85  0.875
     0.9   0.925 0.95  0.975 1.    1.025 1.05  1.075 1.1   1.125 1.15  1.175
     1.2   1.225 1.25  1.275 1.3   1.325 1.35  1.375 1.4   1.425 1.45  1.475
     1.5   1.525 1.55  1.575 1.6   1.625 1.65  1.675 1.7   1.725 1.75  1.775
     1.8   1.825 1.85  1.875 1.9   1.925 1.95  1.975 2.   ]
    [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2.
     2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 1. 1. 1. 1. 1. 1. 1.
     1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
     1. 1. 1. 1. 1. 1. 1. 1. 1.]

```python
un = np.ones(nx) #initialize a temporary array

for n in range(nt):  #loop for values of n from 0 to nt, so it will run nt times
    un = u.copy() ##copy the existing values of u into un
    for i in range(1, nx): ## you can try commenting this line and...
    #for i in range(nx): ## ... uncommenting this line and see what happens!
        u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])
```

```python
plt.plot(x, u, 'o-')
plt.grid()
```

## Implementação com Devito

```python
#NBVAL_IGNORE_OUTPUT
from examples.cfd import plot_field, init_hat
from devito import Grid, TimeFunction

grid = Grid(shape=(nx,), extent=(2.,))
u = TimeFunction(name='u', grid=grid)

u.data[0][:] = 1.
u.data[0][int(.5 / dx):int(1 / dx + 1)] = 2.
# Note que u.data[0] == u.data[0,:]
print(u.data[0],u.data.shape,u.data.size)
plt.plot(x,u.data[0],'o-')
plt.grid()
```

    [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2.
     2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 1. 1. 1. 1. 1. 1. 1.
     1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
     1. 1. 1. 1. 1. 1. 1. 1. 1.] (2, 81) 162

```python
from devito import Eq

# Specify the `interior` flag so that the stencil is only
# applied to the interior of the domain.
eq = Eq(u.dt + c*u.dxl, subdomain=grid.interior)

print(eq)
eq
```

    Eq(Derivative(u(t, x), x) + Derivative(u(t, x), t), 0)

$\displaystyle \frac{\partial}{\partial x} u{\left(t,x \right)} + \frac{\partial}{\partial t} u{\left(t,x \right)} = 0$

```python
u.forward
```

$\displaystyle u{\left(t + dt,x \right)}$

```python
from devito import solve
from sympy import nsimplify, pprint

stencil = solve(eq, u.forward)

pprint(stencil)
```

       ⎛  ∂             u(t, x)⎞
    dt⋅⎜- ──(u(t, x)) + ───────⎟
       ⎝  ∂x               dt  ⎠

```python
#NBVAL_IGNORE_OUTPUT
from devito import Operator

# Reset our initial condition in both buffers.
# This is required to avoid 0s propagating into
# our solution, which has a background value of 1.
for i in range(u.data.shape[0]):
    u.data[i][:] = 1.
    u.data[i][int(.5 / dx):int(1 / dx + 1)] = 2.

# Create an operator that updates the forward stencil point
op = Operator(Eq(u.forward, stencil, subdomain=grid.interior))

# Apply the operator for a number of timesteps
op.apply(time=nt, dt=dt)
```

    Operator `Kernel` ran in 0.01 s

    PerformanceSummary([(PerfKey(name='section0', rank=None),
                         PerfEntry(time=5.999999999999999e-06, gflopss=0.0, gpointss=0.0, oi=0.0, ops=0, itershapes=[]))])

```python
plt.plot(np.linspace(0, 2, nx), u.data[0], 'o-')
plt.grid()
```

```python
print(op.ccode)
```

    #define _POSIX_C_SOURCE 200809L
    #define START_TIMER(S) struct timeval start_ ## S , end_ ## S ; gettimeofday(&start_ ## S , NULL);
    #define STOP_TIMER(S,T) gettimeofday(&end_ ## S, NULL); T->S += (double)(end_ ## S .tv_sec-start_ ## S.tv_sec)+(double)(end_ ## S .tv_usec-start_ ## S .tv_usec)/1000000;

    #include "stdlib.h"
    #include "math.h"
    #include "sys/time.h"
    #include "xmmintrin.h"
    #include "pmmintrin.h"

    struct dataobj
    {
      void *restrict data;
      int * size;
      int * npsize;
      int * dsize;
      int * hsize;
      int * hofs;
      int * oofs;
    } ;

    struct profiler
    {
      double section0;
    } ;

    int Kernel(const float dt, const float h_x, struct dataobj *restrict u_vec, const int i0x_ltkn, const int i0x_rtkn, const int time_M, const int time_m, const int x_M, const int x_m, struct profiler * timers)
    {
      float (*restrict u)[u_vec->size[1]] __attribute__ ((aligned (64))) = (float (*)[u_vec->size[1]]) u_vec->data;

      /* Flush denormal numbers to zero in hardware */
      _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
      _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);

      for (int time = time_m, t0 = (time)%(2), t1 = (time + 1)%(2); time <= time_M; time += 1, t0 = (time)%(2), t1 = (time + 1)%(2))
      {
        /* Begin section0 */
        START_TIMER(section0)
        for (int i0x = i0x_ltkn + x_m; i0x <= -i0x_rtkn + x_M; i0x += 1)
        {
          u[t1][i0x + 1] = dt*((u[t0][i0x] - u[t0][i0x + 1])/h_x + u[t0][i0x + 1]/dt);
        }
        STOP_TIMER(section0,timers)
        /* End section0 */
      }

      return 0;
    }

### Outra condição inicial

```python
nx = 41
L = 1.0
dx = L/(nx-1)
print(dx)
x = np.linspace(0,L,nx)
u = np.sin(2.0*np.pi*x)
plt.plot(x,u,'-o')
plt.grid()
```

    0.025

```python
c = 1.0 # m/s - wave speed
dt = dx/c  # run just at the CFL condition
cfl = c*dt/dx
print(dt, int(1./dt))

un = u.copy() ##copy the existing values of u into un
u[1:-1] = un[1:-1] - cfl * (un[1:-1] - un[:-2])
u[-1] = un[-1] - cfl*(un[-1] - un[-2]) # compute last point on the right using periodicity
u[0] = u[-1] # set periodic boundary on the left
print(u.size,u.shape)
plt.plot(x,un,'-o',x,u,'--o')
plt.grid()
```

    0.025 40
    41 (41,)

```python
grid = Grid(shape=(nx,), extent=(1.,))
u = TimeFunction(name='u', grid=grid)

u.data[0][:] = np.sin(2.0*np.pi*x)
# Note que u.data[0] == u.data[0,:]
print(u.data[0],u.data.shape,u.data.size)
plt.plot(x,u.data[0],'o-')
plt.grid()
```

    [ 0.0000000e+00  1.5643446e-01  3.0901700e-01  4.5399049e-01
      5.8778524e-01  7.0710677e-01  8.0901700e-01  8.9100653e-01
      9.5105654e-01  9.8768836e-01  1.0000000e+00  9.8768836e-01
      9.5105654e-01  8.9100653e-01  8.0901700e-01  7.0710677e-01
      5.8778524e-01  4.5399049e-01  3.0901700e-01  1.5643446e-01
      1.2246469e-16 -1.5643446e-01 -3.0901700e-01 -4.5399049e-01
     -5.8778524e-01 -7.0710677e-01 -8.0901700e-01 -8.9100653e-01
     -9.5105654e-01 -9.8768836e-01 -1.0000000e+00 -9.8768836e-01
     -9.5105654e-01 -8.9100653e-01 -8.0901700e-01 -7.0710677e-01
     -5.8778524e-01 -4.5399049e-01 -3.0901700e-01 -1.5643446e-01
     -2.4492937e-16] (2, 41) 82

```python
eq = Eq(u.dt + c*u.dxl, subdomain=grid.interior)

stencil = solve(eq, u.forward)
update = Eq(u.forward, stencil)#, subdomain=grid.interior)
update
```

$\displaystyle u{\left(t + dt,x \right)} = dt \left(- 1.0 \frac{\partial}{\partial x} u{\left(t,x \right)} + \frac{u{\left(t,x \right)}}{dt}\right)$

```python
x = grid.dimensions
t = grid.stepping_dim
bc_left = Eq(u[t + 1, 0], u[t + 1, nx-1])
```

```python
for i in range(u.data.shape[0]):
    u.data[i][:] = np.sin(2.0*np.pi*np.linspace(0,L,nx))

#op2 = Operator([update], opt='noop')
op2 = Operator([update]+[bc_left], opt='noop')
op2(time=0, dt=dt)
```

    Operator `Kernel` ran in 0.01 s

    PerformanceSummary([(PerfKey(name='section0', rank=None),
                         PerfEntry(time=1e-06, gflopss=0.0, gpointss=0.0, oi=0.0, ops=0, itershapes=[]))])

```python
plt.plot(np.linspace(0,L,nx),u.data[0],'o-',np.linspace(0,L,nx),u.data[1],'--o')
plt.grid()
```

```python
print(op2.ccode)
```

    #define _POSIX_C_SOURCE 200809L
    #define START_TIMER(S) struct timeval start_ ## S , end_ ## S ; gettimeofday(&start_ ## S , NULL);
    #define STOP_TIMER(S,T) gettimeofday(&end_ ## S, NULL); T->S += (double)(end_ ## S .tv_sec-start_ ## S.tv_sec)+(double)(end_ ## S .tv_usec-start_ ## S .tv_usec)/1000000;

    #include "stdlib.h"
    #include "math.h"
    #include "sys/time.h"

    struct dataobj
    {
      void *restrict data;
      int * size;
      int * npsize;
      int * dsize;
      int * hsize;
      int * hofs;
      int * oofs;
    } ;

    struct profiler
    {
      double section0;
    } ;

    int Kernel(const float dt, const float h_x, struct dataobj *restrict u_vec, const int time_M, const int time_m, const int x_M, const int x_m, struct profiler * timers)
    {
      float (*restrict u)[u_vec->size[1]] __attribute__ ((aligned (64))) = (float (*)[u_vec->size[1]]) u_vec->data;

      for (int time = time_m, t0 = (time)%(2), t1 = (time + 1)%(2); time <= time_M; time += 1, t0 = (time)%(2), t1 = (time + 1)%(2))
      {
        /* Begin section0 */
        START_TIMER(section0)
        for (int x = x_m; x <= x_M; x += 1)
        {
          u[t1][x + 1] = dt*(1.0F*u[t0][x]/h_x - 1.0F*u[t0][x + 1]/h_x + u[t0][x + 1]/dt);
        }
        STOP_TIMER(section0,timers)
        /* End section0 */
        u[t1][1] = u[t1][41];
      }

      return 0;
    }

```python
for i in range(u.data.shape[0]):
    u.data[i][:] = np.sin(2.0*np.pi*np.linspace(0,L,nx))

op2(time=nt, dt=dt)
```

    Operator `Kernel` ran in 0.01 s

    PerformanceSummary([(PerfKey(name='section0', rank=None),
                         PerfEntry(time=1.8000000000000004e-05, gflopss=0.0, gpointss=0.0, oi=0.0, ops=0, itershapes=[]))])

```python
plt.plot(np.linspace(0,L,nx),u.data[1],'o-')
plt.grid()
```

```python

```


# Winnie J Kulei - Epidemiology

### <font color="red"> Good. See some comments on your pdf file.

!pip3 install sympy

```python
import matplotlib.pyplot as plt
import numpy as np
import sympy as sp
```

```python
from sympy.interactive import printing
printing.init_printing(use_latex=True)
```

```python
S,I,R= sp.symbols('S,I,R')
mu, beta,gamma,epsilon,N= sp.symbols('mu, beta,gamma,epsilon,N')
```

```python
Sdot = (- beta*S*I)+ epsilon*(N-S-I)
Sdot
```

```python
Idot = beta*S*I -gamma*I
Idot
```

```python
SEq = sp.Eq(Sdot,0)
IEq = sp.Eq(Idot,0)
```

# Determining our fixed points

```python
equilibria = sp.solve( (SEq,IEq), S,I )
print(equilibria)
```

    [(N, 0), (-(-N*epsilon + epsilon*(N*beta - gamma)/beta)/epsilon, epsilon*(N*beta - gamma)/(beta*(epsilon + gamma)))]

#Disease free equilibrium point

```python
[N,0]
```

#Endemic equilibrium point

```python
a=sp.simplify((-(-N*epsilon + epsilon*(N*beta - gamma)/beta)/epsilon))
a
```

```python
b=sp.simplify(epsilon*(N*beta - gamma)/(beta*(epsilon + gamma)))
b
```

```python
[a,b]
```

# Creating the Jacobian Matrix

```python
Matrix = sp.Matrix([ Sdot, Idot ])
Mat = sp.Matrix([ S,I])
jacobian = Matrix.jacobian(Mat)
print( jacobian)
```

    Matrix([[-I*beta - epsilon, -S*beta - epsilon], [I*beta, S*beta - gamma]])

# Performing Iterations.

```python
#Finding the jacobian matrix.
for item in equilibria:
    Matrix = jacobian.subs([ (S, item[0]), (I, item[1]) ])
    eigenvals = list(Matrix.eigenvals().keys())
    print((item[0], item[1], eigenvals[0],eigenvals[1]))
```

    (N, 0, -epsilon, N*beta - gamma)
    (-(-N*epsilon + epsilon*(N*beta - gamma)/beta)/epsilon, epsilon*(N*beta - gamma)/(beta*(epsilon + gamma)), -epsilon*(N*beta + epsilon)/(2*(epsilon + gamma)) - sqrt(epsilon*(N**2*beta**2*epsilon - 2*N*beta*epsilon**2 - 8*N*beta*epsilon*gamma - 4*N*beta*gamma**2 + epsilon**3 + 4*epsilon**2*gamma + 8*epsilon*gamma**2 + 4*gamma**3))/(2*(epsilon + gamma)), -epsilon*(N*beta + epsilon)/(2*(epsilon + gamma)) + sqrt(epsilon*(N**2*beta**2*epsilon - 2*N*beta*epsilon**2 - 8*N*beta*epsilon*gamma - 4*N*beta*gamma**2 + epsilon**3 + 4*epsilon**2*gamma + 8*epsilon*gamma**2 + 4*gamma**3))/(2*(epsilon + gamma)))

# QUESTION 2

```python
# import required libraries
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
```

# Question 2(d).

```python
#Defining given parameters
beta= 4.0; gamma=1.6; mu=2

#The differential equations system.
def derivative_S(S,I):
    return mu - beta*S*I + gamma*I - mu*S
def derivative_I(S,I):
    return beta*S*I - gamma*I - mu*I

#Initializing the lists containing our values
S = []
I = []
t = []

#iv1, iv2 = initial values, dt = timestep, time = range
def sys(InitialV_1,InitialV_2, dt, time):
	# initial values:
	t.append(0)
	S.append(InitialV_1)
	I.append(InitialV_2)

	# compute and fill lists
	for i in range(time):
		t.append((i+1)*dt)
		S.append(S[i] + (deri_S(S[i],I[i])) * dt)
		I.append(I[i] + (deri_I(S[i],I[i])) * dt)
	return t,S,I

sys(0.2, 0.8, 0.2, 1000)
plt.plot(S,I, color="red")
S = []
I = []
t = []
sys(0.4, 0.6, 0.2, 1000)
plt.plot(S,I, color="pink")
S = []
I = []
t = []
sys(0.6, 0.4, 0.2, 1000)
plt.plot(S,I, color="green")
S = []
I = []
t = []
sys(0.8, 0.2, 0.2, 1000)
plt.plot(S,I, color="orange")

plt.xlabel("S")
plt.ylabel("I")
plt.title("i(t) versus s(t)")
plt.grid()
plt.show()

```

# Question 2(e).

```python
#Defining parameters
beta= 4.0; gamma=2.5; mu=2

#The differential equations system.
def derivative_S(S,I):
    return mu - beta*S*I + gamma*I - mu*S
def derivative_I(S,I):
    return beta*S*I - gamma*I - mu*I

#Initializing the lists containing our values
S = []
I = []
t = []

#iv1, iv2 = initial values, dt = timestep, time = range
def sys(InitialV_1,InitialV_2, dt, time):
	# initial values:
	t.append(0)
	S.append(InitialV_1)
	I.append(InitialV_2)

	# compute and fill lists
	for i in range(time):
		t.append((i+1)*dt)
		S.append(S[i] + (deri_S(S[i],I[i])) * dt)
		I.append(I[i] + (deri_I(S[i],I[i])) * dt)
	return t,S,I

sys(0.2, 0.8, 0.2, 1000)
plt.plot(S,I, color="red")
S = []
I = []
t = []
sys(0.4, 0.6, 0.2, 1000)
plt.plot(S,I, color="pink")
S = []
I = []
t = []
sys(0.6, 0.4, 0.2, 1000)
plt.plot(S,I, color="green")
S = []
I = []
t = []
sys(0.8, 0.2, 0.2, 1000)
plt.plot(S,I, color="orange")

plt.xlabel("S")
plt.ylabel("I")
plt.title("i(t) versus s(t)")
plt.grid()
plt.show()

```

```python

```

```python

```

```python

```

```python

```


# Scattershot Boson Sampling

*Author: Arthur Pesah*

Implementation of Scattershot Boson Sampling (see references [(1)](https://arxiv.org/abs/1305.4346) and [(2)](https://www.scottaaronson.com/blog/?p=1579)) in Strawberry Fields.

As we have seen in the Boson Sampling (BS) tutorial, a boson sampler is a quantum machine that takes a deterministic input made of $m$ modes, $n$ of them sending photons simultaneously through an interferometer modeled by a unitary matrix $U$. The output of the interferometer is a random distribution of photons that can be computed classically with the permanent of $U$.

Scattershot Boson Sampling (SBS) was motivated by the fact that emitting $n$ photons simultaneously in the input is experimentally very hard to realize for large $n$. What is simpler to build is a random input using Spontaneous Parametric Down-Conversion (SPDC), whose distribution is given by $P(k_i = k)=(1-\chi^2) \chi^{2 k}$ where $k_i$ is the number of photon in mode i and $\chi \in (-1,1)$ is a given parameter (equation (7) of the [original paper (1)](https://arxiv.org/abs/1305.4346)). The advantage of SPDC is not only that it's a coherent source of photons but also that it always emits an even number of photons: one that can be used in a boson sampling circuit and one to measure the input.

In quantum optics, we model SPDC by 2-mode squeezing gates $\hat{S}_2$ such that $\hat{S}_2 |0 \rangle |0 \rangle = \sqrt{(1-\chi^2)} \sum_{k=0}^{\infty} \chi^k |k \rangle |k \rangle$ (equation (3) of the paper). The first qumode will be used to measure the input while the second will be sent to the circuit.

In SF, this 2-mode squeezing gate is called the `S2gate` and takes as input a squeezing parameter $r$ related to $\chi$ by the formula $r=\tanh(\chi)$.

```python
import numpy as np
import scipy as sp
from math import factorial, tanh
import itertools

import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib.path as mpath
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
from matplotlib.collections import PatchCollection

import strawberryfields as sf
from strawberryfields.ops import *
```

```python
colormap = np.array(plt.rcParams['axes.prop_cycle'].by_key()['color'])
```

## Constructing the circuit

### Constants

Our circuit will depend on a few parameters. The first constants are the squeezing parameter $r \in [-1,1]$ (already described in introduction) and the cutoff number, which corresponds to the maximum number of photons per mode considered in the computation (used to make the simulation tractable).

```python
r_squeezing = 0.5 # squeezing parameter for the S2gate (here taken randomly between -1 and 1)
cutoff = 7 # max number of photons computed per mode
```

Then comes the unitary matrix, representing the interferometer. We have decided to implement a 4-modes boson sampler, and we therefore need a $4 \times 4$-unitary matrix. Any kind of such unitary matrix could do well, but for simplicity, we choose to implement it using two rotations: one with angle $\theta_1$ for the qumodes 1 and 2, and another with angle $\theta_2$ for the qubits 3 and 4. The final matrix has the form:

$$\begin{pmatrix} \cos(\theta_1) & - \sin(\theta_1) & 0 & 0  \\ \sin(\theta_1) & cos(\theta_1) & 0 & 0 \\ 0 & 0 & \cos(\theta_2) & - \sin(\theta_2) \\ 0 & 0 & \cos(\theta_2) & \sin(\theta_2) \end{pmatrix}~~\text{with}~~\theta_1, \theta_2 \in [0,2\pi).$$

```python
theta1 = 0.5
theta2 = 1

U = np.array([[np.cos(theta1), -np.sin(theta1), 0,               0             ],
              [np.sin(theta1),  np.cos(theta1), 0,               0             ],
              [0,               0,              np.cos(theta2), -np.sin(theta2)],
              [0,               0,              np.sin(theta2),  np.cos(theta2)]])
```

### Circuit

We instantiate our circuit with 8 qubits, 4 for the input, 4 for the output.

```python
prog = sf.Program(8)
```

We can then declare our circuit. The first four lines are 2-modes squeezing gates, which generate a random number of photons

```python
with prog.context as q:
    S2gate(r_squeezing) | (q[0], q[4])
    S2gate(r_squeezing) | (q[1], q[5])
    S2gate(r_squeezing) | (q[2], q[6])
    S2gate(r_squeezing) | (q[3], q[7])

    Interferometer(U) | (q[4], q[5], q[6], q[7])
```

### Running

Run the simulation up to 'cutoff' photons per mode

```python
eng = sf.Engine("fock", backend_options={"cutoff_dim":cutoff})
state = eng.run(prog).state
```

    /home/xanadu-laptop/nathan-dev/strawberryfields/strawberryfields/program.py:541: UserWarning: The circuit consists of 2 disconnected components.

Get the probability associated to each state

```python
probs = state.all_fock_probs()
```

Reshape 'probs' such that probs $[m_1, \dots, m_4,n_1, \dots, n_4]$ gives the probability of the having jointly the input state $(m_1, \dots, m_4)$ (with $m_i$ the number of photons in input mode $i$) and the output state $(n_1, \dots, n_4)$ (with $n_i$ the number of photons in output mode $i$)

```python
probs = probs.reshape(*[cutoff]*8)
```

The sum is not 1 because of the finite cutoff:

```python
np.sum(probs)
```

    0.9946200380981707

## Analysis

The goal of this section is to compare the simulated probability with the theoretical one.

### Computation of the theoretical probability

To do so, the first step is to compute the theoretical probability $P(\mathrm{input}=(m_1, m_2, m_3, m_4), \mathrm{output}=(n_1, n_2, n_3, n_4))$, where $m_i,n_i \in \mathbb{N}$ represent the number of photons respectively in input and output modes $i$.   Using the definition of conditional probability, we can decompose it as:

$$P(\mathrm{input}, \mathrm{output}) = P(\mathrm{output} \mid \mathrm{input}) P(\mathrm{input}) $$

The value of $P(\mathrm{output} \mid \mathrm{input})$ is given in the [Boson Sampling tutorial](https://strawberryfields.readthedocs.io/en/latest/tutorials/tutorial_boson_sampling.html#boson-tutorial):

$$P(\mathrm{input}=(m_1, m_2, m_3, m_4) \mid \mathrm{output}=(n_1, n_2, n_3, n_4)) = \frac{\left| \mathrm{Perm}(U_{st}) \right| ^2}{n_1! n_2! n_3! n_4! m_1! m_2! m_3! m_4!}$$

while $P(\mathrm{input})$ depends on the SPDC properties (see introduction) and can be computed in the following way:

$$\begin{equation}
\begin{split}
P(\textrm{input} =(m_1, m_2, m_3, m_4)) &= \prod_{i=1}^4 P(m_i) \\
 & = \prod_{i=1}^4 (1-\chi^2) \chi^{2m_i} \\
 & = (1-\chi^2)^4 \chi^{2 \sum m_i} \\
 & = (1-\chi^2)^m \chi^{2 n}
\end{split}
\end{equation}$$

with $m$ the number of modes (here 4) and $n=\sum m_i$ the total number of photons. The value of $P(m_i)$ is directly taken from the original paper (equation (7)).

Using that, we can now perform the computation.

First, the permanent of the matrix can be calculated via the [Hafnian](https://hafnian.readthedocs.io) library:

```python
from hafnian import perm
```

Then the probability of the output given an input. For that, we use the algorithm given in section V of reference [(3)](https://arxiv.org/pdf/1212.2240.pdf) to compute the matrix $U_{st}$ (called $U_{I,O}$ in the cited paper). To sum it up, it consists in extracting $m_j$ times the column $j$ of $U$ for every $j$, and $n_i$ times the row $i$ of $U$ for every $i$ (with $m_j$ and $n_i$ still representing the number of photons respectively in input $j$ and output $i$).

```python
def get_proba_output(U, input, output):
    # The two lines below are the extracted row and column indices.
    # For instance, for output=[3,2,1,0], we want list_rows=[0,0,0,1,1,2].
    # sum(.,[]) is a Python trick to flatten the list
    list_rows = sum([[i] * output[i] for i in range(len(output))],[])
    list_columns = sum([[i] * input[i] for i in range(len(input))],[])

    U_st = U[:,list_columns][list_rows,:]
    perm_squared = np.abs(perm(U_st))**2
    denominator = np.prod([factorial(inp) for inp in input]) * np.prod([factorial(out) for out in output])
    return perm_squared / denominator
```

```python
def get_proba_input(input):
    chi = np.tanh(r_squeezing)
    n = np.sum(input)
    m = len(input)
    return (1 - chi**2)**m * chi**(2*n)
```

```python
def get_proba(U, result):
    input, output = result[0:4], result[4:8]
    return get_proba_output(U, input, output) * get_proba_input(input) # P(O,I) = P(O|I) P(I)
```

### Comparison between theory and simulation

```python
print("Theory: \t", get_proba(U, [0,0,0,0,0,0,0,0]))
print("Simulation: \t", probs[0,0,0,0,0,0,0,0])
```

    Theory: 	 0.0
    Simulation: 	 0.38254229538212553

```python
print("Theory: \t", get_proba(U, [1,0,0,0,1,0,0,0]))
print("Simulation: \t", probs[1,0,0,0,1,0,0,0])
```

    Theory: 	 0.06291578440230364
    Simulation: 	 0.06291578440230361

```python
print("Theory: \t", get_proba(U, [1,0,0,0,0,1,0,0]))
print("Simulation: \t", probs[1,0,0,0,0,1,0,0])
```

    Theory: 	 0.018776990012967093
    Simulation: 	 0.018776990012967086

We see that the results are very similar.

## Visualization

To visualize the results and the effect of a scattershot boson sampler, we will draw some examples of sampling.

### Make the probabilities sum to 1
Due to computational issues, the sum of the probability does not equal 1. Since it prevents us from sampling correctly, we choose to add the missing weight to the outcome [0,0,0,0, 0,0,0,0]

```python
probs[0,0,0,0, 0,0,0,0] += 1 - np.sum(probs)
```

```python
np.sum(probs)
```

    1.0

### Sample

Get all possible choices as a list of outcomes $[m_1, m_2, m_3, m_4, n_1, n_2, n_3, n_4 ]$

```python
list_choices = list(itertools.product(*[range(cutoff)]*8))
list_choices[0]
```

    (0, 0, 0, 0, 0, 0, 0, 0)

Get the probability of each choice index

```python
list_probs = [probs[list_choices[i]] for i in range(len(list_choices))]
list_probs[0]
```

    0.38792225728395485

Sample a choice using this probability distribution

```python
choice = list_choices[np.random.choice(range(len(list_choices)), p=list_probs)]
choice
```

    (0, 0, 1, 0, 0, 0, 1, 0)

### Visualize

#### Constants

```python
## Colors
color_interf = colormap[0]
color_lines = "black"
color_laser = colormap[3]
color_photons = "#F5D76E"
color_spdc = colormap[4]
color_meas = colormap[1]

color_text_interf = "white"
color_text_spdc = "white"
color_text_measure = "white"

## Sizes
unit = 0.05
radius_photons = 0.015
margin_photons = 0.01
margin_input_meas = 1*unit # space between the end of the input measure and the interferometer

width_laser = 8*unit
width_spdc = 2*unit
width_lines_spdc = 1*unit
width_line_interf = 8*unit
width_measure = 2*unit
width_line_input = width_line_interf - margin_input_meas - width_measure
width_interf = 8*unit
width_line_output = 6*unit

height_interf = 20*unit
height_spdc = 2*unit

## Positions
x_begin_laser = -0.5
x_begin_spdc = x_begin_laser + width_laser
x_end_spdc = x_begin_spdc + width_spdc
x_begin_lines_spdc = x_end_spdc
x_end_lines_spdc = x_end_spdc + width_lines_spdc
x_end_line_input = x_end_lines_spdc + width_line_input
x_begin_input_meas = x_end_line_input
x_end_input_meas = x_begin_input_meas + width_measure
x_begin_interf = x_end_lines_spdc + width_line_interf
x_end_interf = x_begin_interf + width_interf
x_end_line_output = x_end_interf + width_line_output
x_end_output_meas = x_end_line_output + width_measure

y_begin_interf = 0
sep_lines_interf = height_interf / 5
sep_lines_spdc = 2*unit
```

#### Plot

```python
# Sampling

choice = list_choices[np.random.choice(range(len(list_choices)), p=list_probs)]

# Plot

fig, ax = plt.subplots()
fig.set_size_inches(12, 9)
fig.axis = "equal"

interf = mpatches.Rectangle((x_begin_interf,0),width_interf, height_interf,
                            edgecolor=color_interf,facecolor=color_interf)
ax.add_patch(interf)

plt.text(x_begin_interf+width_interf/2, y_begin_interf+height_interf/2, 'U',
         {'ha': 'center', 'va': 'center'}, size=40, color=color_text_interf)

for i_line in range(4):
    y_line_interf = y_begin_interf + (i_line+1) * sep_lines_interf
    y_line_input = y_line_interf + sep_lines_spdc
    y_line_laser = y_line_interf + (y_line_input - y_line_interf) / 2

    # draw laser lines
    plt.plot([x_begin_laser,x_begin_spdc], [y_line_laser,y_line_laser], color=color_laser)

    # draw lines for the output of the SPDC
    plt.plot([x_begin_lines_spdc,x_end_lines_spdc], [y_line_laser,y_line_interf], color=color_lines)
    plt.plot([x_begin_lines_spdc,x_end_lines_spdc], [y_line_laser,y_line_input], color=color_lines)

    # draw lines interferometer lines
    plt.plot([x_end_lines_spdc,x_begin_interf], [y_line_interf,y_line_interf], color=color_lines)
    plt.plot([x_end_interf, x_end_line_output], [y_line_interf,y_line_interf], color=color_lines)

    # draw lines for the input photons (before measure)
    plt.plot([x_end_lines_spdc,x_end_line_input], [y_line_input,y_line_input], color=color_lines)

    # draw the input measures
    input_meas = mpatches.Rectangle((x_begin_input_meas, y_line_input-width_measure/2),width_measure,width_measure,
                                    edgecolor=color_meas,facecolor=color_meas)
    plt.text(x_begin_input_meas+width_measure/2, y_line_input, str(choice[i_line]),
             {'ha': 'center', 'va': 'center'}, size=12, color=color_text_measure)
    ax.add_patch(input_meas)

    # draw the output measures
    input_meas = mpatches.Rectangle((x_end_line_output, y_line_interf-width_measure/2),width_measure,width_measure,
                                    edgecolor=color_meas,facecolor=color_meas)
    plt.text(x_end_line_output+width_measure/2, y_line_interf, str(choice[4+i_line]),
             {'ha': 'center', 'va': 'center'}, size=12, color=color_text_measure)
    ax.add_patch(input_meas)

    # draw the SPDC
    spdc = mpatches.Rectangle((x_begin_spdc,y_line_interf),width_spdc,height_spdc,
                              edgecolor=color_spdc,facecolor=color_spdc, zorder=3)
    plt.text(x_begin_spdc+width_spdc/2, y_line_interf+height_spdc/2, 'SPDC',
             {'ha': 'center', 'va': 'center'}, size=12, color=color_text_spdc)
    ax.add_patch(spdc)

    # draw the input photons
    for i_photon in range(choice[i_line]):
        x_photon = x_end_line_input - margin_photons - radius_photons - i_photon*(radius_photons*2 + margin_photons)
        circle = mpatches.Circle([x_photon,y_line_input], radius_photons, color=color_photons, zorder=3)
        ax.add_patch(circle)

    # draw the output photons
    for i_photon in range(choice[4 + i_line]):
        x_photon = x_end_line_output - margin_photons - radius_photons - i_photon*(radius_photons*2 + margin_photons)
        circle = mpatches.Circle([x_photon,y_line_interf], radius_photons, color=color_photons, zorder=3)
        ax.add_patch(circle)

plt.title("Choice: {}".format(choice))
plt.axis('equal')
plt.axis('off')
```

This figure represents an example of sampling (each time you execute the cell, it samples a new state).

At time 0, a laser hits the 4 SPDC, which produce in consequence $n$ pairs of photons. For each pair, one photon is sent to a measuring device (for the input) and the other to the interferometer. This interferometer then outputs those $n$ photons, but in different modes (different lines in the figure), following the probability distribution described above. A measuring device finally captures those output photons.

A state consists in both the input photons (produced by the SPDC) and the output ones.

## References

1. A. P. Lund, A. Laing, S. Rahimi-Keshari, T. Rudolph, J. L O'Brien and T. C. Ralph. Boson Sampling from Gaussian States. Physical Review Letters, [doi:10.1103/PhysRevLett.113.100502](https://link.aps.org/doi/10.1103/PhysRevLett.113.100502).

2. Scott Aaronson. Scattershot Boson Sampling: A new approach to scalable Boson Sampling experiments. [Blog article](https://www.scottaaronson.com/blog/?p=1579).

3. Max Tillmann, Borivoje Dakić, René Heilmann, Stefan Nolte, Alexander Szameit, Philip Walther. Experimental Boson Sampling. Nature Photonics [doi:10.1038/nphoton.2013.102](https://www.nature.com/articles/nphoton.2013.102).