# Visualization: Calculating with scales

```julia
] activate .
```

    Activating environment at `C:\Users\carsten\.julia\dev\StableDQMC.jl\notebooks\scales_visualizations\Project.toml`

## Using `String` and `Char` (type piracy)

```julia
using Latexify
```

```julia
# const small, medium, large = 'ₓ', 'x', 'X'
const tiny, small, medium, large = 't','s', 'M', 'L'
# const small, medium, large = '🞄', '●', '⬤'
# const small, medium, large = '▪', '■', '⬛'
```

    ('t', 's', 'M', 'L')

```julia
const scale2value = Dict(tiny => 1, small => 2, medium => 3, large => 4)
```

    WARNING: redefining constant scale2value

    Dict{Char,Int64} with 4 entries:
      'M' => 3
      'L' => 4
      's' => 2
      't' => 1

```julia
Base.zero(::Type{String}) = " "
Base.zero(::String) = zero(String)

Base.zero(::Type{Char}) = ' '
Base.zero(::Char) = zero(Char)

function Base.:+(x::String, y::String)
    if occursin(zero(String), x)
        if occursin(zero(String), y)
            return zero(String)
        else
            return y
        end
    elseif occursin(zero(String), y)
        return x
    else
       return sum(scale2value[c] for c in x) < sum(Int.(collect(y))) ? y : x #mean(x) < mean(y) ? y : x
    end
end

function Base.:+(x::Char, y::Char)
    if x == zero(Char)
        if y == zero(Char)
            return zero(Char)
        else
            return y
        end
    elseif y == zero(Char)
        return x
    else
       return scale2value[x] > scale2value[y] ? x : y
    end
end
```

```julia
using LinearAlgebra
D = diagm(0 => [large, medium, small])
```

    3×3 Array{Char,2}:
     'L'  ' '  ' '
     ' '  'M'  ' '
     ' '  ' '  's'

```julia
set_default(convert_unicode = false)
```

```julia
D |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
L &   &   \\
  & M &   \\
  &   & s \\
\end{array}
\right]
\end{equation}

```julia
D * [large, medium, small] |> latexify
```

\begin{equation}
\left[
\begin{array}{c}
LL \\
MM \\
ss \\
\end{array}
\right]
\end{equation}

```julia
D * [small, small, small] |> latexify
```

\begin{equation}
\left[
\begin{array}{c}
Ls \\
Ms \\
ss \\
\end{array}
\right]
\end{equation}

```julia
O = zeros(Char, 3,3)
O |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
  &   &   \\
  &   &   \\
  &   &   \\
\end{array}
\right]
\end{equation}

```julia
U = fill(small, 3,3)
U |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
s & s & s \\
s & s & s \\
s & s & s \\
\end{array}
\right]
\end{equation}

```julia
U * D |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
sL & sM & ss \\
sL & sM & ss \\
sL & sM & ss \\
\end{array}
\right]
\end{equation}

```julia
D * U * D |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
LsL & LsM & Lss \\
MsL & MsM & Mss \\
ssL & ssM & sss \\
\end{array}
\right]
\end{equation}

```julia
print(ans)
```

    \begin{equation}
    \left[
    \begin{array}{ccc}
    LsL & LsM & Lss \\
    MsL & MsM & Mss \\
    ssL & ssM & sss \\
    \end{array}
    \right]
    \end{equation}

```julia
U*D |> latexify
```

\begin{equation}
\left[
\begin{array}{ccc}
sL & sM & ss \\
sL & sM & ss \\
sL & sM & ss \\
\end{array}
\right]
\end{equation}

#### 4x4

```julia
using LinearAlgebra
D = diagm(0 => [large, medium, small, tiny])
```

    4×4 Array{Char,2}:
     'L'  ' '  ' '  ' '
     ' '  'M'  ' '  ' '
     ' '  ' '  's'  ' '
     ' '  ' '  ' '  't'

```julia
U = fill(small, 4,4)
U |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
s & s & s & s \\
s & s & s & s \\
s & s & s & s \\
s & s & s & s \\
\end{array}
\right]
\end{equation}

```julia
D*U*D |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
LsL & LsM & Lss & Lst \\
MsL & MsM & Mss & Mst \\
ssL & ssM & sss & sst \\
tsL & tsM & tss & tst \\
\end{array}
\right]
\end{equation}

```julia
D
```

    4×4 Array{Char,2}:
     'L'  ' '  ' '  ' '
     ' '  'M'  ' '  ' '
     ' '  ' '  's'  ' '
     ' '  ' '  ' '  't'

```julia
U*D*U |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
sts & sts & sts & sts \\
sts & sts & sts & sts \\
sts & sts & sts & sts \\
sts & sts & sts & sts \\
\end{array}
\right]
\end{equation}

## Using Sympy

```julia
using SymPy
using LinearAlgebra
```

```julia
X, x, ₓ = @vars X x ₓ
```

    (X, x, ₓ)

```julia

```

```julia
D = diagm([X,x,ₓ])
```

\[\left[ \begin{array}{rrr}X&0&0\\0&x&0\\0&0&ₓ\end{array}\right]\]

```julia
U = fill(x, 3,3)
```

\[\left[ \begin{array}{rrr}x&x&x\\x&x&x\\x&x&x\end{array}\right]\]

```julia
U*D
```

\[\left[ \begin{array}{rrr}X x&x^{2}&x ₓ\\X x&x^{2}&x ₓ\\X x&x^{2}&x ₓ\end{array}\right]\]

```julia
⚫, ⬤, ●, 🞄 = @vars ⚫ ⬤ ● 🞄
```

    (⚫, ⬤, ●, 🞄)

```julia
D = diagm([⚫, ⬤, ●, 🞄])
```

\[\left[ \begin{array}{rrrr}⚫&0&0&0\\0&⬤&0&0\\0&0&●&0\\0&0&0&🞄\end{array}\right]\]

```julia
Diagonal([1000, 100, 10, 1]) |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
1000 & 0 & 0 & 0 \\
0 & 100 & 0 & 0 \\
0 & 0 & 10 & 0 \\
0 & 0 & 0 & 1 \\
\end{array}
\right]
\end{equation}

```julia
⬛, ■, ◾, ▪ = @vars ⬛ ■ ◾ ▪
L, M, s, t = @vars L M s t
```

    (L, M, s, t)

```julia
d = [⬛, ■, ◾, ▪]
d = [L, M, s, t]
```

\[ \left[ \begin{array}{r}L\\M\\s\\t\end{array} \right] \]

```julia
D = diagm(d)
```

\[\left[ \begin{array}{rrrr}L&0&0&0\\0&M&0&0\\0&0&s&0\\0&0&0&t\end{array}\right]\]

```julia
U = fill(◾, 4,4)
U = fill(s, 4,4)
```

\[\left[ \begin{array}{rrrr}s&s&s&s\\s&s&s&s\\s&s&s&s\\s&s&s&s\end{array}\right]\]

```julia
R = D*U*D
```

\[\left[ \begin{array}{rrrr}L^{2} s&L M s&L s^{2}&L s t\\L M s&M^{2} s&M s^{2}&M s t\\L s^{2}&M s^{2}&s^{3}&s^{2} t\\L s t&M s t&s^{2} t&s t^{2}\end{array}\right]\]

```julia
A = U*U
A*D
```

\[\left[ \begin{array}{rrrr}4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\end{array}\right]\]

```julia
A = U*D
U*A
```

\[\left[ \begin{array}{rrrr}4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\\4 L s^{2}&4 M s^{2}&4 s^{3}&4 s^{2} t\end{array}\right]\]

```julia
U |> latexify |> print
```

    \begin{equation}
    \left[
    \begin{array}{cccc}
    s & s & s & s \\
    s & s & s & s \\
    s & s & s & s \\
    s & s & s & s \\
    \end{array}
    \right]
    \end{equation}

```julia
D |> latexify |> print
```

    \begin{equation}
    \left[
    \begin{array}{cccc}
    L & 0 & 0 & 0 \\
    0 & M & 0 & 0 \\
    0 & 0 & s & 0 \\
    0 & 0 & 0 & t \\
    \end{array}
    \right]
    \end{equation}

```julia
D*(U*D) |> latexify |> print
```

    \begin{equation}
    \left[
    \begin{array}{cccc}
    L^2*s & L*M*s & L*s^2 & L*s*t \\
    L*M*s & M^2*s & M*s^2 & M*s*t \\
    L*s^2 & M*s^2 & s^3 & s^2*t \\
    L*s*t & M*s*t & s^2*t & s*t^2 \\
    \end{array}
    \right]
    \end{equation}

```julia
U + D |> latexify |> print
```

    \begin{equation}
    \left[
    \begin{array}{cccc}
    L + s & s & s & s \\
    s & M + s & s & s \\
    s & s & 2*s & s \\
    s & s & s & s + t \\
    \end{array}
    \right]
    \end{equation}

```julia
X = diagm([1e128, 1e64, 1e0, 1e-64])
# N = rand(4,4)
# N[diagind(N)] .= 0
# X = X+N
```

    4×4 Array{Float64,2}:
     1.0e128  0.0     0.0  0.0
     0.0      1.0e64  0.0  0.0
     0.0      0.0     1.0  0.0
     0.0      0.0     0.0  1.0e-64

```julia
F = svd(X)
```

    SVD{Float64,Float64,Array{Float64,2}}
    U factor:
    4×4 Array{Float64,2}:
     1.0  0.0  0.0  0.0
     0.0  1.0  0.0  0.0
     0.0  0.0  1.0  0.0
     0.0  0.0  0.0  1.0
    singular values:
    4-element Array{Float64,1}:
     1.0e128
     1.0e64
     1.0
     1.0e-64
    Vt factor:
    4×4 Array{Float64,2}:
     1.0  0.0  0.0  0.0
     0.0  1.0  0.0  0.0
     0.0  0.0  1.0  0.0
     0.0  0.0  0.0  1.0

```julia
s = F.S
```

    4-element Array{Float64,1}:
     1.0e128
     1.0e64
     1.0
     1.0e-64

```julia
using GenericSVD
```

```julia
Xb = big.(X);
```

```julia
Fb = svd(Xb)
```

    ┌ Warning: keyword `alg` ignored in generic svd!
    └ @ GenericSVD C:\Users\carsten\.julia\packages\GenericSVD\w8oZE\src\GenericSVD.jl:12

    SVD{BigFloat,BigFloat,Array{BigFloat,2}}
    U factor:
    4×4 Array{BigFloat,2}:
     -1.0   0.0   0.0   0.0
      0.0  -1.0   0.0   0.0
      0.0   0.0  -1.0   0.0
      0.0   0.0   0.0  -1.0
    singular values:
    4-element Array{BigFloat,1}:
     1.000000000000000075174486916518208627471429064352408213482909102357765925242415e+128
     1.0000000000000000213204190094543968723012578712679649467743338496e+64
     1.0
     9.999999999999999653057388335469287129029766072807834803722132478776394919962261e-65
    Vt factor:
    4×4 Array{BigFloat,2}:
     -1.0  -0.0  -0.0  -0.0
     -0.0  -1.0  -0.0  -0.0
     -0.0  -0.0  -1.0  -0.0
     -0.0  -0.0  -0.0  -1.0

```julia
sb = Fb.S
```

    4-element Array{BigFloat,1}:
     1.000000000000000075174486916518208627471429064352408213482909102357765925242415e+128
     1.0000000000000000213204190094543968723012578712679649467743338496e+64
     1.0
     9.999999999999999653057388335469287129029766072807834803722132478776394919962261e-65

```julia
s - sb
```

    4-element Array{BigFloat,1}:
     0.0
     0.0
     0.0
     0.0

```julia
using StableDQMC
```

```julia
svd_inv_one_plus(F).S - svd_inv_one_plus(Fb).S
```

    4-element Array{BigFloat,1}:
      1.055257420480776903302833588116958909651870865180872244893734331233485866027102e-146
     -1.33738421569986748693560322601556473903283452878299156314954071924493402990837e-81
      0.0
      1.000000000000032856963321712779388680454016569740087535451726237621195734616864e-64

```julia
svd_inv_one_plus(F).S
```

    4-element Array{Float64,1}:
     9.999999999999999e-129
     1.0e-64
     0.5
     1.0

```julia
Fb.U'/Fb.V
```

    4×4 Array{BigFloat,2}:
      1.0  -0.0  -0.0  -0.0
     -0.0   1.0  -0.0  -0.0
     -0.0  -0.0   1.0  -0.0
     -0.0  -0.0  -0.0   1.0

```julia
1 / 1.0000001
```

    0.9999999000000099

```julia
Diagonal(Fb.S)
```

    4×4 Diagonal{BigFloat,Array{BigFloat,1}}:
     1.0e+128   ⋅        ⋅    ⋅
      ⋅        1.0e+64   ⋅    ⋅
      ⋅         ⋅       1.0   ⋅
      ⋅         ⋅        ⋅   1.0e-64

```julia
Fb.U'/Fb.V + Diagonal(Fb.S)
```

    search:

    Couldn't find setprecision
    Fb.U'/Fb.V + Diagonal(Fb.S)
    Perhaps you meant setprecision

No documentation found.

Binding `setprecision Fb.U'/Fb.V + Diagonal(Fb.S)` does not exist.

```julia
Ftmp = svd(F.U'/F.V + Diagonal(F.S));
```

```julia
1 ./ Ftmp.S
```

    4-element Array{Float64,1}:
     9.999999999999999e-129
     1.0e-64
     0.5
     1.0

```julia
x = big"1.0000000000000000000000000000000000000000000000000000000000000000000000001"
```

    1.000000000000000000000000000000000000000000000000000000000000000000000000100007

```julia
y = big"1.0000000000000000000000000000000000000000000000000000000000000000000000000"
```

    1.0

```julia
reldiff(x,y) = abs(x - y)/abs(x)
```

    reldiff (generic function with 1 method)

```julia
reldiff(x,y)
```

    1.00006831867993668761973954571228627033523284220172138438574486184552293070619e-73

```julia
reldiff(1/x,1/y)
```

    1.000068318679936687619739545712286270335232842201721384385744861845522930906228e-73

```julia
Dp = diagm([L, M, s, s])
```

\[\left[ \begin{array}{rrrr}L&0&0&0\\0&M&0&0\\0&0&s&0\\0&0&0&s\end{array}\right]\]

```julia
Dm = diagm([s, s, s, t])
```

\[\left[ \begin{array}{rrrr}s&0&0&0\\0&s&0&0\\0&0&s&0\\0&0&0&t\end{array}\right]\]

```julia
A = U * inv(Dp)
```

\[\left[ \begin{array}{rrrr}\frac{s}{L}&\frac{s}{M}&1&1\\\frac{s}{L}&\frac{s}{M}&1&1\\\frac{s}{L}&\frac{s}{M}&1&1\\\frac{s}{L}&\frac{s}{M}&1&1\end{array}\right]\]

```julia
B = U * Dm
```

\[\left[ \begin{array}{rrrr}s^{2}&s^{2}&s^{2}&s t\\s^{2}&s^{2}&s^{2}&s t\\s^{2}&s^{2}&s^{2}&s t\\s^{2}&s^{2}&s^{2}&s t\end{array}\right]\]

```julia
A + B
```

\[\left[ \begin{array}{rrrr}s^{2} + \frac{s}{L}&s^{2} + \frac{s}{M}&s^{2} + 1&s t + 1\\s^{2} + \frac{s}{L}&s^{2} + \frac{s}{M}&s^{2} + 1&s t + 1\\s^{2} + \frac{s}{L}&s^{2} + \frac{s}{M}&s^{2} + 1&s t + 1\\s^{2} + \frac{s}{L}&s^{2} + \frac{s}{M}&s^{2} + 1&s t + 1\end{array}\right]\]

```julia
inv(Dp) * U |> latexify |> print
```

    \begin{equation}
    \left[
    \begin{array}{cccc}
    s/L & s/L & s/L & s/L \\
    s/M & s/M & s/M & s/M \\
    1 & 1 & 1 & 1 \\
    1 & 1 & 1 & 1 \\
    \end{array}
    \right]
    \end{equation}

## Using custom types

```julia
] activate .
```

    Activating environment at `C:\Users\carsten\.julia\dev\StableDQMC.jl\notebooks\scales_visualizations\Project.toml`

```julia
@enum Scale null=1 tiny=2 small=3 medium=4 large=5
const unit=small
# const scale_symbols = [' ', '▪', '◾', '■', '⬛'];
const scale_symbols = [' ', 't', 's', 'M', 'L'];
# const scale_symbols = [' ', 'ₓ', 'u', 'x', 'X'];

symbol(s::Scale) = scale_symbols[Int(s)]
Base.isascii(::Scale) = false
Base.isoverlong(::Scale) = false
Base.ismalformed(::Scale) = false
Base.isprint(::Scale) = true

# printing
Base.show(io::IO, s::Scale) = print(io, symbol(s))
Base.show(io::IO, ::MIME"text/plain", s::Scale) = show(io,s)
Base.print(io::IO, s::Scale) = show(io, s)

# math
Base.zero(::Type{Scale}) = null
Base.iszero(s::Scale) = s === null
```

    WARNING: redefining constant scale_symbols

```julia
scales = null, tiny, small, medium, large
```

    ( , t, s, M, L)

```julia
using Statistics

struct ScaleString <: AbstractString
    scales::Vector{Scale}
end

# constructors
ScaleString(s::Scale) = ScaleString([s])

import Lazy: @forward
@forward ScaleString.scales (Base.getindex, Base.length)

# conversion
Base.convert(::Type{ScaleString}, s::Scale) = ScaleString(s)
Base.promote_rule(::Type{Scale}, ::Type{ScaleString}) = ScaleString

Base.iterate(s::ScaleString) = iterate(s.scales)
Base.iterate(s::ScaleString, state::Integer) = iterate(s.scales, state)

# Base.:+(x::ScaleString, y::ScaleString) = ScaleString(vcat(x.scales, null, null, y.scales))
Base.:*(x::ScaleString, y::ScaleString) = ScaleString(vcat(x.scales, y.scales))
Base.zero(::Type{ScaleString}) = ScaleString(zero(Scale))
Base.zero(::ScaleString) = zero(ScaleString)
function Base.:+(x::ScaleString, y::ScaleString)
    if null in x.scales
        if null in y.scales
            # both contain a null
            return ScaleString([null])
        else
            # only x contains a null
            return y
        end
    elseif null in y.scales
        # only y contains a null
        return x
    else
       return sum(Int.(x.scales)) < sum(Int.(y.scales)) ? y : x #mean(x) < mean(y) ? y : x
    end
end
Base.:*(x::ScaleString, y::Scale) = iszero(y) ? ScaleString([null]) : ScaleString(vcat(x.scales, y))
Base.:*(x::Scale, y::ScaleString) = iszero(x) ? ScaleString([null]) : ScaleString(vcat(x, y.scales))

# Scale math extension
Base.:+(x::Scale, y::Scale) = x > y ? x : y
Base.:/(s::Scale, i::Int64) = /(Int(s), i)
function Base.:*(x::Scale, y::Scale)
#     if iszero(x)
#         return ScaleString([y])
#     elseif iszero(y)
#         return ScaleString([x])
#     else
        return ScaleString([x,y])
#     end
end
```

```julia
tiny * null
```

    "t "

```julia
A = ScaleString([tiny, small, small])
B = ScaleString([null, large, small])
```

    " Ls"

```julia
using Latexify

Latexify.latexraw(s::Scale) = symbol(s)
Latexify.latexraw(s::ScaleString) = join(s.scales)
```

```julia
O = zeros(Scale, 4,4)
```

    4×4 Array{Scale,2}:

```julia
U = fill(unit, 4,4)
```

    4×4 Array{Scale,2}:
     s  s  s  s
     s  s  s  s
     s  s  s  s
     s  s  s  s

```julia
U |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
s & s & s & s \\
s & s & s & s \\
s & s & s & s \\
s & s & s & s \\
\end{array}
\right]
\end{equation}

```julia
U * U |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
ss & ss & ss & ss \\
ss & ss & ss & ss \\
ss & ss & ss & ss \\
ss & ss & ss & ss \\
\end{array}
\right]
\end{equation}

```julia
U * O
```

    4×4 Array{ScaleString,2}:
     " "  " "  " "  " "
     " "  " "  " "  " "
     " "  " "  " "  " "
     " "  " "  " "  " "

```julia
using LinearAlgebra
D = diagm([large, medium, small, tiny])
```

    4×4 Array{Scale,2}:
     L
        M
           s
              t

```julia
D |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
L &   &   &   \\
  & M &   &   \\
  &   & s &   \\
  &   &   & t \\
\end{array}
\right]
\end{equation}

```julia
U * D |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
sL & sM & ss & st \\
sL & sM & ss & st \\
sL & sM & ss & st \\
sL & sM & ss & st \\
\end{array}
\right]
\end{equation}

```julia
D * U * D |> latexify
```

\begin{equation}
\left[
\begin{array}{cccc}
LsL & LsM & Lss & Lst \\
MsL & MsM & Mss & Mst \\
ssL & ssM & sss & sst \\
tsL & tsM & tss & tst \\
\end{array}
\right]
\end{equation}

```julia
D * [small, small, small, small] |> latexify
```

\begin{equation}
\left[
\begin{array}{c}
Ls \\
Ms \\
ss \\
ts \\
\end{array}
\right]
\end{equation}

```julia
D * [large, medium, small, tiny] |> latexify
```

\begin{equation}
\left[
\begin{array}{c}
LL \\
MM \\
ss \\
tt \\
\end{array}
\right]
\end{equation}

```julia
R = D * U * D
R[1] == ScaleString([large,unit,large])
```

    true


# Use `ScenarioSeries` to check goodness of fit for a series of simulations

The `prms_python` module provides the `ScenarioSeries` class to set up and run a number of simulations at once in parallel with a common purpose. One example would be to do some sensitivity analyses of a set of parameters. We'll show this application below. This notebook is compatible with Python 3.

## scale *jh_coef* and *rad_trncf* by multiplicative factors

The example we'll show modifies *jh_coef* and *rad_trncf* by scaling them.

```python
import warnings
import sys
sys.path.append('..')
warnings.filterwarnings('ignore', module='numpy')
from prms_python import ScenarioSeries
```

```python
base_dir = '../test/data/models/lbcd/'
simulation_dir = 'jupyternb-scenario-series-example/'
title = 'Jensen-Hays and radiative transfer function sensitivity analysis'
description = '''
Use title of \'"jh_coef":{jh factor value}|"rad_trncf":{rad factor value}\' so later
we can easily generate a dictionary of these factor value combinations.
'''

sc_series = ScenarioSeries(base_dir, simulation_dir, title, description)
```

At this point we have only initialized the series, but we have not created any new scenarios since we have not yet specified what functions will be applied for each of the scenarios. We'll do that next. We need to define a list of dictionaries, each containing the specification for a scenario. First we'll define a function with the signature `_scale_fun(val)` that will itself return a function with the signature `scale(x)` which scales `x` by `val`. This function will then be used to scale all the parameter values by the same amount, `val`.

In total we will generate sixteen scenarios, with a cartesian product of scaling factors ranging from 0.7 to 1.0. This takes a bit of time since we must copy rather large files, currently in series.

```python
import numpy as np

def _scale_fun(val):
    def scale(x):
        return x*val

    return scale

scenario_list = [
    {
        'title': '"jh_coef":{0:.1f}|"rad_trncf":{1:.1f}'.format(jh_val, rad_val),
        'jh_coef': _scale_fun(jh_val),
        'rad_trncf': _scale_fun(rad_val)
    }
    for jh_val in np.arange(0.7, 1.0, 0.1)
    for rad_val in np.arange(0.7, 1.0, 0.1)
]

sc_series.build(scenario_list)
```

Now with the ScenarioSeries built, that is, the directory structure initialized and scenario data prepared, we can run the scenario series. The runner automatically uses half the available CPUs if the optional kwarg `nproc` is not provided.

```python
sc_series.run()  # alternatively sc_series.run(nproc=8)
```

## Analyze the data generated by ScenarioSeries

`ScenarioSeries` provides a mapping from UUID string-named directories to titles we used in `series_metadata.json`. Below is a printout of this `series_metadata.json`.

```python
import json
metadata = json.loads(open('jupyternb-scenario-series-example/series_metadata.json').read())

print(json.dumps(metadata, indent=2))
```

    {
      "title": "Jensen-Hays and radiative transfer function sensitivity analysis",
      "description": "\nUse title of '\"jh_coef\":{jh factor value}|\"rad_trncf\":{rad factor value}' so later\nwe can easily generate a dictionary of these factor value combinations.\n",
      "uuid_title_map": {
        "0a151f07-add4-4e5f-bbfb-50f4f20bc2b8": "\"jh_coef\":0.7|\"rad_trncf\":0.7",
        "88e3c4b0-6984-47c0-9307-ebd2ae5eff00": "\"jh_coef\":0.7|\"rad_trncf\":0.8",
        "a5726cd3-7d52-430a-9f93-45217bc862ab": "\"jh_coef\":0.7|\"rad_trncf\":0.9",
        "99af81ac-b242-44f3-8bf6-9443d0689b11": "\"jh_coef\":0.7|\"rad_trncf\":1.0",
        "b3b2ef40-a125-4eb2-9f1f-fd159c96a5d5": "\"jh_coef\":0.8|\"rad_trncf\":0.7",
        "5e8bb47d-503a-40b6-8e2c-a738fdafcc51": "\"jh_coef\":0.8|\"rad_trncf\":0.8",
        "6610caa1-5c55-4d61-98c8-3ce1bc68ee69": "\"jh_coef\":0.8|\"rad_trncf\":0.9",
        "3c67d688-ac9b-47c9-83bc-370d9b66796a": "\"jh_coef\":0.8|\"rad_trncf\":1.0",
        "adca93a4-c6ea-463f-a9d3-e8d0763693e3": "\"jh_coef\":0.9|\"rad_trncf\":0.7",
        "d0abbd5c-d7a7-471b-bda7-63afea3a4142": "\"jh_coef\":0.9|\"rad_trncf\":0.8",
        "8793a5ab-f07d-4ef1-877d-f7519fdbdbfd": "\"jh_coef\":0.9|\"rad_trncf\":0.9",
        "a3394a0f-2525-4c15-a862-f485dcb01a3f": "\"jh_coef\":0.9|\"rad_trncf\":1.0",
        "1e190ed0-fcb7-466e-a7ab-b357e6f66c4f": "\"jh_coef\":1.0|\"rad_trncf\":0.7",
        "438b4ebd-2867-4410-81a3-420a906421fd": "\"jh_coef\":1.0|\"rad_trncf\":0.8",
        "54a18b71-b538-41d3-8cf3-db562182b7d9": "\"jh_coef\":1.0|\"rad_trncf\":0.9",
        "60941270-3f89-4a48-8a25-2ba0aeb8f844": "\"jh_coef\":1.0|\"rad_trncf\":1.0"
      }
    }

Let's load a single one of these, taking the first element from the `uuid_title_map` and load the `statvar.dat` file into a Pandas DataFrame. We will be comparing the basin_cfs hydrograph in the statvar file to runoff hydrograph in the data input file.

Below we'll load both an example statvar and an input data file.

```python
import os
from prms_python import load_statvar

ex_uuid = list(metadata['uuid_title_map'].keys()).pop()
ex_statvar = os.path.join('jupyternb-scenario-series-example', ex_uuid, 'outputs', 'statvar.dat')
statvar_df = load_statvar(ex_statvar)

statvar_df.head()
```

      statistical_variables
      basin_gwflow_cfs_1
      basin_sroff_cfs_1
      basin_ssflow_cfs_1
      basin_cfs_1
      sub_cfs_1
      sub_interflow_1
      sub_sroff_1
      sub_gwflow_1
      sub_cfs_2
      sub_interflow_2
      ...
      subinc_snowmelt_1
      subinc_snowmelt_2
      subinc_snowmelt_3
      basin_potet_1
      swrad_2490
      basin_ppt_1
      basin_hortonian_1
      basin_dunnian_1
      subinc_snowmelt_1
      subinc_snowmelt_2

      date

      1992-10-01
      12.685159
      0.0
      1.688785
      14.373945
      6.722778
      0.635161
      0.0
      6.087617
      7.137637
      0.915658
      ...
      0.0
      0.0
      0.0
      0.112602
      449.189301
      0.0
      0.0
      0.0
      0.0
      0.0

      1992-10-02
      12.404567
      0.0
      1.279037
      13.683604
      6.425554
      0.478970
      0.0
      5.946583
      6.793885
      0.699584
      ...
      0.0
      0.0
      0.0
      0.109168
      441.326080
      0.0
      0.0
      0.0
      0.0
      0.0

      1992-10-03
      12.133535
      0.0
      0.969636
      13.103171
      6.172768
      0.361898
      0.0
      5.810869
      6.504972
      0.534584
      ...
      0.0
      0.0
      0.0
      0.069002
      396.180847
      0.0
      0.0
      0.0
      0.0
      0.0

      1992-10-04
      11.871843
      0.0
      0.735709
      12.607553
      5.954316
      0.273988
      0.0
      5.680328
      6.258663
      0.408489
      ...
      0.0
      0.0
      0.0
      0.055411
      392.465240
      0.0
      0.0
      0.0
      0.0
      0.0

      1992-10-05
      11.619248
      0.0
      0.558642
      12.177891
      5.762654
      0.207857
      0.0
      5.554798
      6.045657
      0.312074
      ...
      0.0
      0.0
      0.0
      0.056177
      388.749939
      0.0
      0.0
      0.0
      0.0
      0.0

5 rows × 41 columns

This also allows us to easily plot the output hydrographs like so. We add some niceness to the plots.

```python
%matplotlib inline
warnings.filterwarnings('ignore', module='matplotlib')
warnings.filterwarnings('ignore', module='mpltools')

import matplotlib as mpl
mpl.style.use('ggplot')
import matplotlib.pyplot as plt
mpl.rcParams['figure.figsize'] = (10.0, 6.0)
mpl.rcParams['figure.dpi'] = 300.0
mpl.rcParams['xtick.labelsize'] = 12.0
mpl.rcParams['ytick.labelsize'] = 12.0
mpl.rcParams['axes.labelsize'] = 16.0
mpl.rcParams['axes.titlesize'] = 18.0
mpl.rcParams['legend.fontsize'] = 16.0

statvar_df.basin_cfs_1.plot()
plt.ylabel('Streamflow (cfs)')
```

Now let's load and plot the data file on top of the simulated streamflow from the statvar file.

```python
from prms_python import load_data

data_path = os.path.join(base_dir, 'data')
data_df = load_data(data_path)

data_df.runoff_1.plot(label='observed')
statvar_df.basin_cfs_1.plot(label=metadata['uuid_title_map'][ex_uuid].replace('"', '').replace('|',', '))

plt.ylabel('Streamflow (cfs)')
plt.legend()
```

## Calculate the Nash-Sutcliffe Model Efficiency for one Simulation

In parameterizing hydrological models, it's necesary to test multiple parameters and calculate the goodness-of-fit for each model run. Goodness-of-fit is a measure of how well the model output matches historical output so that future predictions may be made. A well-known GOF measure in Hydrology is the Nash-Sutcliffe model efficiency, from Nash & Sutcliffe's 1970 paper [River Flow Forecasting Through Conceptual Models Part I - A Discussion of Principles](./nash-sutcliffe-1970.pdf). They elegantly describe the model-fitting problem like so

> To remove subjectivity in fitting the model to the data or in determining the
parametric values, O'Donnell3) suggested automatic optimisation. This
involves successive changes of parameter values according to some pre-conceived
rule or pattern of increments which takes into account the results of
previous steps and in particular whether or not a change improved the fitting.

The equation itself is

\begin{equation}
E = 1 - \frac{\sum_{t=1}^{T}\left(Q_o^t - Q_m^t\right)^2}{\sum_{t=1}^{T}\left(Q_o^t - \overline{Q_o}\right)^2}
\end{equation}

We have implemented this in the `prms_python/util.py` module. Below we import it and calculate it for the simulated hydrograph shown in the figure above.

Note that the closer to 1 the efficiency is, the more exactly the model accounts for observed variance. A value of 0 for efficiency means that the model does as well as the mean of the hydrograph for predictive purposes. A value below 0 means that the model does worse than the mean for modeling the hydrograph.

```python
from prms_python import nash_sutcliffe

nash_sutcliffe(data_df.runoff_1, statvar_df.basin_cfs_1)
```

    0.5985845573889427

## Calculate the Nash-Sutcliffe Efficiency for all Simulations

Now we'll iterate over all the statvar outputs and calculate the Nash-Sutcliffe model efficiency for each. To better understand the efficiency landscape across these two parameters, we'll use a matrix plot to see how the efficiency changes across scalings of each of the two parameters, `jh_coef` and `rad_trncf`.

```python
idx_lookup = {'{:.1f}'.format(val): idx for idx, val in enumerate(np.arange(0.7, 1.0, 0.1))}
print(idx_lookup)
```

    {'0.7': 0, '0.8': 1, '0.9': 2, '1.0': 3}

```python
nash_sutcliffe_mat = np.zeros((4,4))

modeled_flows = {
    title: load_statvar(os.path.join('jupyternb-scenario-series-example', uu, 'outputs', 'statvar.dat')).basin_cfs_1
    for uu, title in metadata['uuid_title_map'].items()
}
print(list(modeled_flows.keys())[:5])
```

    ['"jh_coef":0.7|"rad_trncf":0.7', '"jh_coef":0.7|"rad_trncf":0.8', '"jh_coef":0.7|"rad_trncf":0.9', '"jh_coef":0.7|"rad_trncf":1.0', '"jh_coef":0.8|"rad_trncf":0.7']

```python
observed = data_df.runoff_1

for title, hydrograph in modeled_flows.items():
    param_scalings = eval('{' + title.replace('|', ',') + '}')
    coord = (idx_lookup[str(param_scalings['jh_coef'])], idx_lookup[str(param_scalings['rad_trncf'])])

    nash_sutcliffe_mat[coord] = nash_sutcliffe(observed, hydrograph)
```

```python
import itertools
fig, ax = plt.subplots()

cax = ax.matshow(nash_sutcliffe_mat, cmap='viridis')
tix = [0.7, 0.8, 0.9, 1.0]
plt.xticks(range(4), tix)
plt.yticks(range(4), tix)

ax.xaxis.set_ticks_position('bottom')
plt.ylabel('jh_coef factor')
plt.xlabel('rad_trncf factor')

for i, j in itertools.product(range(4), range(4)):
    plt.text(j, i, "%.2f" % nash_sutcliffe_mat[i, j],
             horizontalalignment="center",
             color="w" if nash_sutcliffe_mat[i, j] < .61 else "k")

plt.title('Nash-Sutcliffe Matrix')
plt.grid(b=False)
cbar = fig.colorbar(cax)
```


```python
!pip install tensorflow==2.4.1
!pip install tensorflow-quantum==0.5.1
# Cirq linking seems to be broken, so reinstall the core package
!pip install --no-deps --force-reinstall cirq-core==0.11.0
```

# **Task III: Part a) implement a quantum variational autoencoder in TF Quantum and show its performance**

### Dataset:
The electron-photon dataset (which can be found here) contains 100 samples for training and another 100 for testing, laid out as follows:

● data["x_train"]: Training dataset of 100 32x32 images containing the particles' energy (100, 32, 32)

● data["y_train"]:" Training labels, 0 = "photon", 1 = "electron" (100,)

● data["x_test"]: Test dataset of 100 32x32 images containing the particles' energy (100, 32, 32)

● data["y_test"]:" Test labels, 0 = "photon", 1 = "electron" (100,)

## **Quantum Variational Autoencoder**

 A limiting factor for nearly
all of quantum applications, is the amount of quantum
resources that can be realized in an experiment. Therefore, for
experiments now and in the near future, any tool which can reduce the experimental overhead in terms of these resources is
especially valuable.This can be done using a technique called autoencoding.

Quantum Autoencoder is a way of encoding data into a compressed form using suitable training over variational circuits.

The approach used to solve this task is inspired from this paper[1] where we use a PQC(Parameterised Quantum Circuit) to perform operations on input data.
After this, we trace out a few data qubits and measure its fidelity with a reference state. The PQC circuit is trained to minimize the fidelity loss between the traced out space and the reference state. After training we can say that we have successfully atleast approximately encoded data into a compressed space called latent space.

```python
import numpy as np
import sympy
import tensorflow as tf
import tensorflow_quantum as tfq
import cirq
%matplotlib inline
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit
```

# **Dataset Preprocessing**

```python
from google.colab import files
uploaded = files.upload()
```

<input type="file" id="files-a378a05e-b4b6-48f9-abb1-df2c9f1489ef" name="files[]" multiple disabled
   style="border:none" />
<output id="result-a378a05e-b4b6-48f9-abb1-df2c9f1489ef">
 Upload widget is only available when the cell has been executed in the
 current browser session. Please rerun this cell to enable.
 </output>

    Saving electron-photon.npz to electron-photon.npz

```python
data = np.load('./electron-photon.npz', allow_pickle = True)
```

```python
for key in data.keys():
  print(key)
  print(data[key])

```

    x_train
    [[[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     ...

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]]
    y_train
    [1. 1. 1. 0. 1. 0. 1. 1. 1. 0. 1. 1. 1. 1. 0. 1. 1. 0. 0. 1. 0. 0. 1. 0.
     1. 0. 1. 1. 0. 0. 1. 0. 1. 1. 0. 0. 1. 1. 0. 1. 1. 0. 0. 0. 1. 1. 0. 1.
     1. 0. 1. 1. 0. 0. 1. 1. 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.
     0. 0. 0. 1. 1. 1. 0. 1. 0. 1. 1. 1. 0. 1. 0. 1. 0. 0. 1. 1. 1. 0. 1. 0.
     1. 1. 0. 1.]
    x_test
    [[[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     ...

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]

     [[0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      ...
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]
      [0. 0. 0. ... 0. 0. 0.]]]
    y_test
    [0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 0. 0. 1. 1. 1. 1. 0. 1.
     0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 1. 1. 0. 1. 0. 1. 1. 1. 0. 1. 1. 1. 0. 0.
     1. 0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 1. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0.
     0. 0. 1. 1. 1. 0. 1. 0. 1. 0. 1. 1. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 1. 1.
     1. 1. 1. 1.]

```python
X_train = data['x_train']
y_train = data['y_train']
X_test = data['x_test']
y_test = data['y_test']

# check
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
```

    (100, 32, 32)
    (100,)
    (100, 32, 32)
    (100,)

# Feature Reduction

Each image is of size 32x32 and the information in the image is highly sparse(most of pixels are zero). Also after careful preprocessing it is also evident that a very small ammount of information is actually present in the corner pixels and that is what actually distinguishes two or more images to a larger extent. So cropping the images won't be an option. Here, we will apply a classical subroutine called PCA(Principal Component Analysis) to the input data to reduce the feature dimensions from 1024(32x32 in 2D) to some small number of features that best fits our model.

```python
from sklearn.decomposition import PCA

n_pca = 10
X_train_flatten = X_train.reshape(-1,32*32)
X_test_flatten = X_test.reshape(-1,32*32)

pca = PCA(n_components = n_pca)
pca.fit(X_train_flatten)

X_train_transform = pca.transform(X_train_flatten)
X_test_transform = pca.transform(X_test_flatten)

#check
print(X_train_transform.shape)
print(X_test_transform.shape)

# Let's check if the pca transform preserves the inherent variance present in this data
print(np.cumsum(pca.explained_variance_ratio_))
```

    (100, 10)
    (100, 10)
    [0.48118138 0.65938324 0.76321054 0.84084606 0.8902277  0.9208717
     0.94699347 0.9600863  0.96964854 0.9764575 ]

We can see that after transforming the data using PCA, the features reduce from 1024 features to 10 features but retains upto ~97% of its variance. However, we can use more features to get better results  from the model

# **Circuit Architecture**
In this task, we are going to use 10 qubits for the data from the dataset.Along with this we use 6 reference qubits and 1 extra qubit for the Swap Test.Total qubits used will be 17 out of which the last 4 qubits form the latent space in which the compressed encoding of data occurs.

```python
# Initializing Qubits
qubits = cirq.GridQubit.rect(1,17)
# num_qubits = 9
```

```python
# Defining standard unitaries
# encoder unitary
def one_qubit_unitary_enc(bit, symbols):
    """Make a Cirq circuit enacting a rotation of the bloch sphere about the X,
    Y and Z axis, that depends on the values in `symbols`.
    """
    return cirq.Circuit(
        cirq.X(bit)**symbols[0],
        cirq.Y(bit)**symbols[1],
        cirq.Z(bit)**symbols[2])

# decoder unitary
def one_qubit_unitary_dec(bit,symbols):
   """Make a Cirq circuit enacting a rotation of the bloch sphere about the X,
    Y and Z axis, that depends on the values in `symbols`.
    """
   return cirq.Circuit(
        cirq.Z(bit)**symbols[0],
        cirq.Y(bit)**symbols[1],
        cirq.X(bit)**symbols[2]
    )

def two_qubit_unitary(bits, symbols):
    """Make a Cirq circuit that creates an arbitrary two qubit unitary."""
    circuit = cirq.Circuit()
    # circuit += one_qubit_unitary_(bits[0], symbols[0:3])
    # circuit += one_qubit_unitary(bits[1], symbols[3:6])
    circuit += [cirq.ZZ(*bits)**symbols[0]]
    circuit += [cirq.YY(*bits)**symbols[1]]
    circuit += [cirq.XX(*bits)**symbols[2]]
    # circuit += one_qubit_unitary(bits[0], symbols[9:12])
    # circuit += one_qubit_unitary(bits[1], symbols[12:])
    return circuit
```

```python
def create_encoder_circuit(qubits,symbols,layers=1):
  circuit = cirq.Circuit()

  for layer in range(layers):
    for i in range(len(qubits)):
      circuit += one_qubit_unitary_enc(qubits[i],symbols[3*i + 3*layer*len(qubits) : 3*(i+1) + 3*layer*len(qubits)])

    # for i in range(len(qubits)):
    #   if(i<len(qubits)-1):
    #     circuit += cirq.CNOT(qubits[i],qubits[i+1])
    # circuit += cirq.CNOT(qubits[len(qubits)-1],qubits[0])
    for i in range(len(qubits)):
       if(i<len(qubits)-1):
         circuit += two_qubit_unitary(qubits[i:i+2],symbols[3*len(qubits)+3*i + 3*layer*len(qubits) : 3*len(qubits)+3*(i+1) + 3*layer*len(qubits)])

  return circuit
```

```python
layers = 1
num_symbols = str(3*len(qubits)*layers*2)
SVGCircuit(create_encoder_circuit(qubits[7:17],sympy.symbols('encoder:'+num_symbols),layers))
```

```python
# def create_decoder_circuit(qubits,symbols,layers=1):
#   circuit = cirq.Circuit()

#   for layer in range(layers):
#     circuit += cirq.CNOT(qubits[0],qubits[len(qubits)-1])

#     for i in range(len(qubits)):
#       if(i<len(qubits)-1):
#         circuit += cirq.CNOT(qubits[len(qubits)-i-1],qubits[len(qubits)-i-2])

#     for i in range(len(qubits)):
#       circuit += one_qubit_unitary_dec(qubits[i],symbols[3*i + 3*layer*len(qubits) : 3*(i+1) + 3*layer*len(qubits)])

#   return circuit

```

```python
# SVGCircuit(create_decoder_circuit(qubits[0:6]+qubits[11:14],sympy.symbols('decoder:'+num_symbols),layers))
```

```python

```

```python
#swap circuit
def swap_circuit(value_qubit,qubits_ref,qubits_data):
  circuit = cirq.Circuit()
  circuit += cirq.H(value_qubit)
  num_swap_qubits = len(qubits_ref)+len(qubits_data)

  for a, b in zip(qubits_ref, qubits_data):
            circuit.append(cirq.decompose(cirq.CSwapGate().on(value_qubit, a, b)))
  circuit += cirq.H(value_qubit)
  return circuit

print(len(qubits[1:7]),len(qubits[7:13]))
SVGCircuit(swap_circuit(qubits[0],qubits[1:7],qubits[7:13]))
# SVGCircuit(tfq.from_tensor(swap_circuit(qubits[0:17])))
```

    6 6

# Data Encoding

```python
def generate_quantum_data(X,qubits):
    quantum_data =[]
    for i in X:
        circuit = cirq.Circuit()

        for j in range(len(i)):
            circuit.append(cirq.ry(i[j])(qubits[j]))

        quantum_data.append(circuit)
    return quantum_data
```

```python
train_quantum_data = tfq.convert_to_tensor(generate_quantum_data(X_train_transform,qubits[7:17]))
test_quantum_data = tfq.convert_to_tensor(generate_quantum_data(X_test_transform,qubits[7:17]))
SVGCircuit(tfq.from_tensor(train_quantum_data)[0])
```

```python
def create_full_circuit(qubits,symbols,layers=1):
  circuit = cirq.Circuit()

  circuit += create_encoder_circuit(qubits[7:17],symbols,layers)
  circuit += swap_circuit(qubits[0],qubits[1:7],qubits[7:13])

  return circuit
```

```python
create_full_circuit(qubits,sympy.symbols('encoder:'+num_symbols),layers)
```

                                                                                ┌──┐                                                                                ┌──┐                                                                                ┌──┐                                                                                ┌──┐                                                                                ┌──┐                                                                                ┌──┐
(0, 0): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────H───Y^-0.5───@───Y^0.5────@───Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───Y^-0.5───@───────Y^0.5────@──────Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───Y^-0.5───@───────Y^0.5────@──────Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───Y^-0.5───@───────Y^0.5────@──────Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───Y^-0.5───@───────Y^0.5────@──────Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───Y^-0.5───@───────Y^0.5────@──────Y^-0.5────@─────Y^0.5────────────────────@───T^-1────Y^-0.5───@────────Y^0.5───@───T───────Y^-0.5───@────────Y^0.5────@───X^0.5───@───────────────@───Y^-0.5───@────────Y^0.5────@───H──────────────────────────
                                                                                │            │             │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 1): ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@───Y^-0.5───@───Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼────────────@───────Y^-0.5───@──────Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 3): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼────────────@───────Y^-0.5───@──────Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 4): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼────────────@───────Y^-0.5───@──────Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 5): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼────────────@───────Y^-0.5───@──────Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼────────────┼────────────────┼────────────────┼──────────────────────────────┼────────────────────┼────────────────┼────────────────────┼─────────────────┼───────────┼───────────────┼────────────┼─────────────────┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │            │                │                │                              │                    │                │                    │                 │           │               │            │                 │
(0, 6): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼────────────@───────Y^-0.5───@──────Y^0.5─────┼T─────────────────────────────┼────────────────────@────────────────┼────────────────────@────────Y^-0.5───┼───────────@──────Y^0.5────┼────────────@────────X^-0.5───┼──────────────────────────────
                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │
(0, 7): ────X^encoder0───Y^encoder1───Z^encoder2──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ─────────────YY─────────────XX─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5────Y^0.5───X────────S^-1─────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────
                                                                                │              │              │                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │
(0, 8): ───────────────────────────────────────────X^encoder3───Y^encoder4───Z^encoder5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder30───YY^encoder31───XX^encoder32───ZZ─────────────YY─────────────XX──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5────Y^0.5───X────────S^-1─────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────
                                                                                │              │              │                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │
(0, 9): ──────────────────────────────────────────────────────────────────────────────────X^encoder6───Y^encoder7───Z^encoder8─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder33───YY^encoder34───XX^encoder35───ZZ─────────────YY─────────────XX───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5────Y^0.5───X────────S^-1─────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────
                                                                                │              │              │                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │
(0, 10): ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder9───Y^encoder10───Z^encoder11─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder36───YY^encoder37───XX^encoder38───ZZ─────────────YY─────────────XX────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5────Y^0.5───X────────S^-1─────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────────────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────
                                                                                │              │              │                                                                                │                              │                                     │                                      │                           │                              │                                              │                              │                                     │                                      │                           │                              │
(0, 11): ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder12───Y^encoder13───Z^encoder14────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder39───YY^encoder40───XX^encoder41───ZZ─────────────YY─────────────XX─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5────Y^0.5───X────────S^-1─────────────┼──────────────────────────────┼─────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────┼──────────────────────────────┼──────────────────────────────
                                                                                │              │              │                                                                                │                              │                                     │                                      │                           │                              │
(0, 12): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder15───Y^encoder16───Z^encoder17───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder42───YY^encoder43───XX^encoder44───ZZ─────────────YY─────────────XX──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────@─────Y^0.5───X───T───Y^-0.5───@───Y^0.5───T────────Y^-0.5───────────@───Y^0.5───T^-1─────Y^-0.5────────────@───Y^0.5───T^-1───Y^-0.5───@───Y^0.5────Y^-0.5────────────@───Y^0.5───Y^0.5───X───S^-1───
                                                                                │              │              │
(0, 13): ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder18───Y^encoder19───Z^encoder20──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder45───YY^encoder46───XX^encoder47───ZZ─────────────YY─────────────XX───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                │              │              │
(0, 14): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder21───Y^encoder22───Z^encoder23─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder48───YY^encoder49───XX^encoder50───ZZ─────────────YY─────────────XX──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                │              │              │
(0, 15): ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder24───Y^encoder25───Z^encoder26────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder51───YY^encoder52───XX^encoder53───ZZ─────────────YY─────────────XX─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                │              │              │
(0, 16): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X^encoder27───Y^encoder28───Z^encoder29───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────ZZ^encoder54───YY^encoder55───XX^encoder56───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                └──┘                                                                                └──┘                                                                                └──┘                                                                                └──┘                                                                                └──┘                                                                                └──┘

```python
@tf.function
def fidelity_loss(y_true,y_pred):
  # return -1*(tf.math.log(1-y_pred))
  return (1-y_pred)
```

```python
def create_model(qubits,symbols,layers=1):
  observables = [cirq.Z(qubits[0])]

  circuit = cirq.Circuit()
  circuit += create_full_circuit(qubits,symbols,layers)
  data_input = tf.keras.Input(shape = (),dtype = tf.dtypes.string)
  pqc_circuit = tfq.layers.PQC(circuit,
                               observables,
                               name='quantum_variational_qutoencoder')(data_input)
  model = tf.keras.Model(inputs = [data_input],outputs = [pqc_circuit])

  model.compile(optimizer = tf.keras.optimizers.Adam(lr=0.01),
                loss=[fidelity_loss],
                metrics=['accuracy'])
  return model

```

```python
model = create_model(qubits,sympy.symbols('encoder:'+num_symbols),layers)
tf.keras.utils.plot_model(model,
                          show_shapes=True,
                          show_layer_names=True,
                          dpi=70)
```

```python
# Hypeyparameters
batch = 20
epochs = 10
```

# **Training the Model**

```python
H = model.fit(x=train_quantum_data,
          y=y_train,
          batch_size=batch,
          # verbose=verbose,
          epochs = epochs,
          validation_data = (test_quantum_data,y_test))
```

    Epoch 1/10
    5/5 [==============================] - 32s 7s/step - loss: 0.9807 - accuracy: 0.4571 - val_loss: 0.9217 - val_accuracy: 0.5400
    Epoch 2/10
    5/5 [==============================] - 30s 6s/step - loss: 0.8879 - accuracy: 0.3987 - val_loss: 0.7717 - val_accuracy: 0.5400
    Epoch 3/10
    5/5 [==============================] - 30s 6s/step - loss: 0.7132 - accuracy: 0.4458 - val_loss: 0.5508 - val_accuracy: 0.4900
    Epoch 4/10
    5/5 [==============================] - 30s 6s/step - loss: 0.4949 - accuracy: 0.5157 - val_loss: 0.3550 - val_accuracy: 0.4800
    Epoch 5/10
    5/5 [==============================] - 30s 6s/step - loss: 0.3042 - accuracy: 0.5572 - val_loss: 0.1949 - val_accuracy: 0.4600
    Epoch 6/10
    5/5 [==============================] - 31s 6s/step - loss: 0.1643 - accuracy: 0.5158 - val_loss: 0.1057 - val_accuracy: 0.4600
    Epoch 7/10
    5/5 [==============================] - 30s 6s/step - loss: 0.0825 - accuracy: 0.5478 - val_loss: 0.0576 - val_accuracy: 0.4600
    Epoch 8/10
    5/5 [==============================] - 32s 7s/step - loss: 0.0479 - accuracy: 0.5033 - val_loss: 0.0360 - val_accuracy: 0.4600
    Epoch 9/10
    5/5 [==============================] - 30s 6s/step - loss: 0.0328 - accuracy: 0.5658 - val_loss: 0.0372 - val_accuracy: 0.4600
    Epoch 10/10
    5/5 [==============================] - 30s 6s/step - loss: 0.0352 - accuracy: 0.5394 - val_loss: 0.0333 - val_accuracy: 0.4600

```python
plt.plot(H.history['loss'])
plt.xlabel('Epoch')
plt.ylabel('Loss')
```

# **Conclusion**
1. The image size is 32x32(i.e 1024 features) per sample which we reduced using PCA to 10 features. It is evident reducing features substantially still captures most of the variance(~ 97%) of the dataset.
2. The circuit depth can become really large if more and more qubits are considered which may introduce errors hence the right tradeoff between number of qubits and encoding performance needs to be found out.
3. From the training loss it is evident that the circuit learns and encodes the 10 feature data into 4 features(latent space).

# **References**
[1]-[Quantum autoencoders for efficient compression of quantum data
Jonathan Romero,1
Jonathan P. Olson,1
and Alan Aspuru-Guzik1,](https://arxiv.org/pdf/1612.02806.pdf)

```python

```