text:
#### Batched Generalized Minimal Residual Solver

export BatchedGeneralizedMinimalResidual

"""
    BatchedGeneralizedMinimalResidual

# Description

Launches n independent GMRES solves

# Members

- `atol::FT` (float) absolute tolerance
- `rtol::FT` (float) relative tolerance
- `m::IT` (int) size of vector in each independent instance
- `n::IT` (int) number of independent GMRES
- `k_n::IT` (int) Krylov Dimension for each GMRES. It is also the number of GMRES iterations before nuking the subspace
- `residual::VT` (vector) residual values for each independent linear solve
- `b::VT` (vector) permutation of the rhs. probably can be removed if memory is an issue
- `x::VT` (vector) permutation of the initial guess. probably can be removed if memory is an issue
- `sol::VT` (vector) solution vector, it is used twice. First to represent Aqⁿ (the latest Krylov vector without being normalized), the second to represent the solution to the linear system
- `rhs::VT` (vector) rhs vector.
- `cs::VT` (vector) Sequence of Gibbs Rotation matrices in compact form. This is implicitly the Qᵀ of the QR factorization of the upper hessenberg matrix H.
- `H::VT` (vector) The latest column of the Upper Hessenberg Matrix. The previous columns are discarded since they are unnecessary
- `Q::AT` (array) Orthonormalized Krylov Subspace
- `R::AT` (array) The R of the QR factorization of the UpperHessenberg matrix H. A factor of  or so in memory can be saved here
- `reshape_tuple_f::TT1` (tuple), reshapes structure of array that plays nice with the linear operator to a format compatible with struct
- `permute_tuple_f::TT1` (tuple). forward permute tuple. permutes structure of array that plays nice with the linear operator to a format compatible with struct
- `reshape_tuple_b::TT2` (tuple). reshapes structure of array that plays nice with struct to play nice with the linear operator
- `permute_tuple_b::TT2` (tuple). backward permute tuple. permutes structure of array that plays nice with struct to play nice with the linear operator

# Intended Use
Solving n linear systems iteratively

# Comments on Improvement
- Too much memory in H and R struct: Could use a sparse representation to cut memory use in half (or more)
- Needs to perform a transpose of original data structure into current data structure: Could perhaps do a transpose free version, but the code gets a bit clunkier and the memory would no longer be coalesced for the heavy operations
"""
struct BatchedGeneralizedMinimalResidual{FT, IT, VT, AT, TT1, TT2} <:
       AbstractIterativeSystemSolver
    atol::FT
    rtol::FT
    m::IT
    n::IT
    k_n::IT
    residual::VT
    b::VT
    x::VT
    sol::VT
    rhs::VT
    cs::VT
    Q::AT
    H::VT
    R::AT
    reshape_tuple_f::TT1
    permute_tuple_f::TT1
    reshape_tuple_b::TT2
    permute_tuple_b::TT2
end

# So that the struct can be passed into kernels
Adapt.adapt_structure(to, x::BatchedGeneralizedMinimalResidual) =
    BatchedGeneralizedMinimalResidual(
        x.atol,
        x.rtol,
        x.m,
        x.n,
        x.k_n,
        adapt(to, x.residual),
        adapt(to, x.b),
        adapt(to, x.x),
        adapt(to, x.sol),
        adapt(to, x.rhs),
        adapt(to, x.cs),
        adapt(to, x.Q),
        adapt(to, x.H),
        adapt(to, x.R),
        x.reshape_tuple_f,
        x.permute_tuple_f,
        x.reshape_tuple_b,
        x.permute_tuple_b,
    )

"""
    BatchedGeneralizedMinimalResidual(
        Qrhs;
        m = length(Qrhs[:,1]),
        n = length(Qrhs[1,:]),
        subspace_size = m,
        atol = sqrt(eps(eltype(Qrhs))),
        rtol = sqrt(eps(eltype(Qrhs))),
        ArrayType = Array,
        reshape_tuple_f = size(Qrhs),
        permute_tuple_f = Tuple(1:length(size(Qrhs))),
        reshape_tuple_b = size(Qrhs),
        permute_tuple_b = Tuple(1:length(size(Qrhs)))
    )

# Description
Generic constructor for `BatchedGeneralizedMinimalResidual`

# Arguments
- `Qrhs`: (array) Array structure that `linear_operator!` acts on

# Keyword Arguments
- `m`: (int) size of vector space for each independent linear solve. This is assumed to be the same for each and every linear solve. `DEFAULT = size(Qrhs)[1]`
- `n`: (int) number of independent linear solves, `DEFAULT = size(Qrhs)[end]`
- `atol`: (float) absolute tolerance. `DEFAULT = sqrt(eps(eltype(Qrhs)))`
- `rtol`: (float) relative tolerance. `DEFAULT = sqrt(eps(eltype(Qrhs)))`
- `ArrayType`: (type). used for either using CuArrays or Arrays. `DEFAULT = Array`
- `reshape_tuple_f`: (tuple). used in the wrapper function for flexibility. `DEFAULT = size(Qrhs)`. this means don't do anything
- `permute_tuple_f`: (tuple). used in the wrapper function for flexibility. `DEFAULT = Tuple(1:length(size(Qrhs)))`. this means, don't do anything.

# Return
instance of `BatchedGeneralizedMinimalResidual` struct
"""
function BatchedGeneralizedMinimalResidual(
    Qrhs;
    m = size(Qrhs)[1],
    n = size(Qrhs)[end],
    subspace_size = m,
    atol = sqrt(eps(eltype(Qrhs))),
    rtol = sqrt(eps(eltype(Qrhs))),
    ArrayType = Array,
    reshape_tuple_f = size(Qrhs),
    permute_tuple_f = Tuple(1:length(size(Qrhs))),
)
    k_n = subspace_size
    # define the back permutations and reshapes
    permute_tuple_b = Tuple(sortperm([permute_tuple_f...]))
    tmp_reshape_tuple_b = [reshape_tuple_f...]
    permute!(tmp_reshape_tuple_b, [permute_tuple_f...])
    reshape_tuple_b = Tuple(tmp_reshape_tuple_b)
    # allocate memory
    residual = ArrayType(zeros(eltype(Qrhs), (k_n, n)))
    b = ArrayType(zeros(eltype(Qrhs), (m, n)))
    x = ArrayType(zeros(eltype(Qrhs), (m, n)))
    sol = ArrayType(zeros(eltype(Qrhs), (m, n)))
    rhs = ArrayType(zeros(eltype(Qrhs), (k_n + 1, n)))
    cs = ArrayType(zeros(eltype(Qrhs), (2 * k_n, n)))
    Q = ArrayType(zeros(eltype(Qrhs), (m, k_n + 1, n)))
    H = ArrayType(zeros(eltype(Qrhs), (k_n + 1, n)))
    R = ArrayType(zeros(eltype(Qrhs), (k_n + 1, k_n, n)))
    return BatchedGeneralizedMinimalResidual(
        atol,
        rtol,
        m,
        n,
        k_n,
        residual,
        b,
        x,
        sol,
        rhs,
        cs,
        Q,
        H,
        R,
        reshape_tuple_f,
        permute_tuple_f,
        reshape_tuple_b,
        permute_tuple_b,
    )
end

"""
    BatchedGeneralizedMinimalResidual(
        dg::DGModel,
        Q::MPIStateArray;
        atol = sqrt(eps(eltype(Q))),
        rtol = sqrt(eps(eltype(Q))),
        max_subspace_size = nothing,
        independent_states = false,
    )

# Description
Specialized constructor for `BatchedGeneralizedMinimalResidual` struct, using
a `DGModel` to infer state-information and determine appropriate reshaping
and permutations.

# Arguments
- `dg`: (DGModel) A `DGModel` containing all relevant grid and topology
        information.
- `Q` : (MPIStateArray) An `MPIStateArray` containing field information.

# Keyword Arguments
- `atol`: (float) absolute tolerance. `DEFAULT = sqrt(eps(eltype(Q)))`
- `rtol`: (float) relative tolerance. `DEFAULT = sqrt(eps(eltype(Q)))`
- `max_subspace_size` : (Int).    Maximal dimension of each (batched)
                                  Krylov subspace. DEFAULT = nothing
- `independent_states`: (boolean) An optional flag indicating whether
                                  or not degrees of freedom are coupled
                                  internally (within a column).
                                  `DEFAULT = false`
# Return
instance of `BatchedGeneralizedMinimalResidual` struct
"""
function BatchedGeneralizedMinimalResidual(
    dg::DGModel,
    Q::MPIStateArray;
    atol = sqrt(eps(eltype(Q))),
    rtol = sqrt(eps(eltype(Q))),
    max_subspace_size = nothing,
    independent_states = false,
)

    # Need to determine array type for storage vectors
    if isa(Q.data, Array)
        ArrayType = Array
    else
        ArrayType = CuArray
    end

    grid = dg.grid
    topology = grid.topology
    dim = dimensionality(grid)

    # Number of Gauss-Lobatto quadrature points in 1D
    Nq = polynomialorder(grid) + 1

    # Assumes same number of quadrature points in all spatial directions
    Np = Tuple([Nq for i in 1:dim])

    # Number of states and elements (in vertical and horizontal directions)
    num_states = size(Q)[2]
    nelem = length(topology.elems)
    nvertelem = topology.stacksize
    nhorzelem = div(nelem, nvertelem)

    # Definition of a "column" here is a vertical stack of degrees
    # of freedom. For example, consider a mesh consisting of a single
    # linear element:
    #    o----------o
    #    |\ d1   d2 |\
    #    | \        | \
    #    |  \ d3    d4 \
    #    |   o----------o
    #    o--d5---d6-o   |
    #     \  |       \  |
    #      \ |        \ |
    #       \|d7    d8 \|
    #        o----------o
    # There are 4 total 1-D columns, each containing two
    # degrees of freedom. In general, a mesh of stacked elements will
    # have `Nq^2 * nhorzelem` total 1-D columns.
    # A single 1-D column has `Nq * nvertelem * num_states`
    # degrees of freedom.
    #
    # nql = length(Np)
    # indices:      (1...nql, nql + 1 , nql + 2, nql + 3)
    reshaping_tup = (Np..., num_states, nvertelem, nhorzelem)

    if independent_states
        m = Nq * nvertelem
        n = (Nq^(dim - 1)) * nhorzelem * num_states
    else
        m = Nq * nvertelem * num_states
        n = (Nq^(dim - 1)) * nhorzelem
    end

    if max_subspace_size === nothing
        max_subspace_size = m
    end

    # Now we need to determine an appropriate permutation
    # of the MPIStateArray to perform column-wise strides.
    # Total size of the permute tuple
    permute_size = length(reshaping_tup)

    # Index associated with number of GL points
    # in the 'vertical' direction
    nql = length(Np)
    # Want: (index associated with the stack size of the column,
    #        index associated with GL pts in vertical direction,
    #        index associated with number of states)
    # FIXME: Better way to do this?
    #             (vert stack, GL pts, num states)
    column_strides = (nql + 2, nql, nql + 1)
    diff = Tuple(setdiff(Set([i for i in 1:permute_size]), Set(column_strides)))
    permute_tuple_f = (column_strides..., diff...)

    return BatchedGeneralizedMinimalResidual(
        Q;
        m = m,
        n = n,
        subspace_size = max_subspace_size,
        atol = atol,
        rtol = rtol,
        ArrayType = ArrayType,
        reshape_tuple_f = reshaping_tup,
        permute_tuple_f = permute_tuple_f,
    )
end

# initialize function (1)
function initialize!(
    linearoperator!,
    Q,
    Qrhs,
    solver::BatchedGeneralizedMinimalResidual,
    args...,
)
    # body of initialize function in abstract iterative solver
    return false, zero(eltype(Q))
end

# iteration function (2)
function doiteration!(
    linearoperator!,
    Q,
    Qrhs,
    gmres::BatchedGeneralizedMinimalResidual,
    threshold,
    args...,
)
    # Get device and groupsize information
    device = array_device(gmres.b)
    if isa(device, CPU)
        groupsize = Threads.nthreads()
    else # isa(device, CUDA)
        groupsize = 256
    end

    # initialize gmres.x
    convert_structure!(gmres.x, Q, gmres.reshape_tuple_f, gmres.permute_tuple_f)
    # apply linear operator to construct residual
    r_vector = copy(Q)
    linearoperator!(r_vector, Q, args...)
    @. r_vector = Qrhs - r_vector
    # The following ar and rr are technically not correct in general cases
    ar = norm(r_vector)
    rr = norm(r_vector) / norm(Qrhs)
    # check if the initial guess is fantastic
    if (ar < gmres.atol) || (rr < gmres.rtol)
        return true, 0, ar
    end
    # initialize gmres.b
    convert_structure!(
        gmres.b,
        r_vector,
        gmres.reshape_tuple_f,
        gmres.permute_tuple_f,
    )
    # apply linear operator to construct second krylov vector
    linearoperator!(Q, r_vector, args...)
    # initialize gmres.sol
    convert_structure!(
        gmres.sol,
        Q,
        gmres.reshape_tuple_f,
        gmres.permute_tuple_f,
    )
    # initialize the rest of gmres
    event = Event(device)
    event = initialize_gmres_kernel!(device, groupsize)(
        gmres;
        ndrange = gmres.n,
        dependencies = (event,),
    )
    wait(device, event)

    ar, rr = compute_residuals(gmres, 1)
    # check if converged
    if (ar < gmres.atol) || (rr < gmres.rtol)
        event = Event(device)
        event = construct_solution_kernel!(device, groupsize)(
            1,
            gmres;
            ndrange = size(gmres.x),
            dependencies = (event,),
        )
        wait(device, event)

        convert_structure!(
            Q,
            gmres.x,
            gmres.reshape_tuple_b,
            gmres.permute_tuple_b,
        )
        return true, 1, ar
    end
    # body of iteration
    @inbounds for i in 2:(gmres.k_n)
        convert_structure!(
            r_vector,
            view(gmres.Q, :, i, :),
            gmres.reshape_tuple_b,
            gmres.permute_tuple_b,
        )
        linearoperator!(Q, r_vector, args...)
        convert_structure!(
            gmres.sol,
            Q,
            gmres.reshape_tuple_f,
            gmres.permute_tuple_f,
        )

        event = Event(device)
        event = gmres_update_kernel!(device, groupsize)(
            i,
            gmres;
            ndrange = gmres.n,
            dependencies = (event,),
        )
        wait(device, event)

        ar, rr = compute_residuals(gmres, i)
        # check if converged
        if (ar < gmres.atol) || (rr < gmres.rtol)
            event = Event(device)
            event = construct_solution_kernel!(device, groupsize)(
                i,
                gmres;
                ndrange = size(gmres.x),
                dependencies = (event,),
            )
            wait(device, event)

            convert_structure!(
                Q,
                gmres.x,
                gmres.reshape_tuple_b,
                gmres.permute_tuple_b,
            )
            return true, i, ar
        end
    end

    event = Event(device)
    event = construct_solution_kernel!(device, groupsize)(
        gmres.k_n,
        gmres;
        ndrange = size(gmres.x),
        dependencies = (event,),
    )
    wait(device, event)

    convert_structure!(Q, gmres.x, gmres.reshape_tuple_b, gmres.permute_tuple_b)
    ar, rr = compute_residuals(gmres, gmres.k_n)
    converged = (ar < gmres.atol) || (rr < gmres.rtol)
    return converged, gmres.k_n, ar
end

# The function(s) that probably needs the most help
"""
    convert_structure!(
        x,
        y,
        reshape_tuple,
        permute_tuple;
        convert = true,
    )

# Description
Computes a tensor transpose and stores result in x
- This needs to be improved!

# Arguments
- `x`: (array) [OVERWRITTEN]. target destination for storing the y data
- `y`: (array). data that we want to copy
- `reshape_tuple`: (tuple) reshapes y to be like that of x, up to a permutation
- `permute_tuple`: (tuple) permutes the reshaped array into the correct structure

# Keyword Arguments
- `convert`: (bool). decides whether or not permute and convert. The default is true

# Return
nothing
"""
@inline function convert_structure!(
    x,
    y,
    reshape_tuple,
    permute_tuple;
    convert = true,
)
    if convert
        alias_y = reshape(y, reshape_tuple)
        permute_y = permutedims(alias_y, permute_tuple)
        x[:] .= permute_y[:]
    end
    return nothing
end

# MPIStateArray dispatch
@inline convert_structure!(x, y::MPIStateArray, reshape_tuple, permute_tuple) =
    convert_structure!(x, y.data, reshape_tuple, permute_tuple)
@inline convert_structure!(x::MPIStateArray, y, reshape_tuple, permute_tuple) =
    convert_structure!(x.data, y, reshape_tuple, permute_tuple)

# Kernels
"""
    initialize_gmres_kernel!(gmres)

# Description
Initializes the gmres struct by calling
- initialize_arnoldi
- initialize_QR!
- update_arnoldi!
- update_QR!
- solve_optimization!
It is assumed that the first two krylov vectors are already constructed

# Arguments
- `gmres`: (struct) gmres struct

# Return
(implicitly) kernel abstractions function closure
"""
@kernel function initialize_gmres_kernel!(gmres)
    I = @index(Global)
    initialize_arnoldi!(gmres, I)
    update_arnoldi!(1, gmres, I)
    initialize_QR!(gmres, I)
    update_QR!(1, gmres, I)
    solve_optimization!(1, gmres, I)
end

"""
    gmres_update_kernel!(i, gmres)

# Description
kernel that calls
- update_arnoldi!
- update_QR!
- solve_optimization!
Which is the heart of the gmres algorithm

# Arguments
- `i`: (int) interation index
- `gmres`: (struct) gmres struct
- `I`: (int) thread index

# Return
kernel object from KernelAbstractions
"""
@kernel function gmres_update_kernel!(i, gmres)
    I = @index(Global)
    update_arnoldi!(i, gmres, I)
    update_QR!(i, gmres, I)
    solve_optimization!(i, gmres, I)
end

"""
    construct_solution_kernel!(i, gmres)

# Description
given step i of the gmres iteration, constructs the "best" solution of the linear system for the given Krylov subspace

# Arguments
- `i`: (int) gmres iteration
- `gmres`: (struct) gmres struct

# Return
kernel object from KernelAbstractions
"""
@kernel function construct_solution_kernel!(i, gmres)
    M, I = @index(Global, NTuple)
    tmp = zero(eltype(gmres.b))
    @inbounds for j in 1:i
        tmp += gmres.Q[M, j, I] * gmres.sol[j, I]
    end
    gmres.x[M, I] += tmp # since previously gmres.x held the initial value
end

# Helper Functions

"""
    initialize_arnoldi!(gmres, I)

# Description
- First step of Arnoldi Iteration is to define first Krylov vector. Additionally sets things equal to zero

# Arguments
- `g`: (struct) [OVERWRITTEN] the gmres struct
- `I`: (int) thread index

# Return
nothing
"""
@inline function initialize_arnoldi!(gmres, I)
    # set (almost) everything to zero to be sure
    # the assumption is that gmres.k_n is small enough
    # to where these loops don't matter that much
    ft_zero = zero(eltype(gmres.H)) # float type zero

    @inbounds for i in 1:(gmres.k_n + 1)
        gmres.rhs[i, I] = ft_zero
        gmres.H[i, I] = ft_zero
        @inbounds for j in 1:(gmres.k_n)
            gmres.R[i, j, I] = ft_zero
        end
    end
    # gmres.x was initialized as the initial x
    # gmres.sol was initialized right before this function call
    # gmres.b was initialized right before this function call
    # compute norm
    @inbounds for i in 1:(gmres.m)
        gmres.rhs[1, I] += gmres.b[i, I] * gmres.b[i, I]
    end
    gmres.rhs[1, I] = sqrt(gmres.rhs[1, I])
    # now start computations
    @inbounds for i in 1:(gmres.m)
        gmres.sol[i, I] /= gmres.rhs[1, I]
        gmres.Q[i, 1, I] = gmres.b[i, I] / gmres.rhs[1, I] # First Krylov vector
    end
    return nothing
end

"""
    initialize_QR!(gmres::BatchedGeneralizedMinimalResidual, I)

# Description
initializes the QR decomposition of the UpperHesenberg Matrix

# Arguments
- `gmres`: (struct) [OVERWRITTEN] the gmres struct
- `I`: (int) thread index

# Return
nothing
"""
@inline function initialize_QR!(gmres, I)
    gmres.cs[1, I] = gmres.H[1, I]
    gmres.cs[2, I] = gmres.H[2, I]
    gmres.R[1, 1, I] = sqrt(gmres.cs[1, I]^2 + gmres.cs[2, I]^2)
    gmres.cs[1, I] /= gmres.R[1, 1, I]
    gmres.cs[2, I] /= -gmres.R[1, 1, I]
    return nothing
end

# The meat of gmres with updates that leverage information from the previous iteration
"""
    update_arnoldi!(n, gmres, I)

# Description
Perform an Arnoldi iteration update

# Arguments
- `n`: current iteration number
- `gmres`: gmres struct that gets overwritten
- `I`: (int) thread index
# Return
- nothing
# linear_operator! Arguments
- `linear_operator!(x,y)`
# Description
- Performs Linear operation on vector and overwrites it
# Arguments
- `y`: (array)
# Return
nothing

"""
@inline function update_arnoldi!(n, gmres, I)
    # make new Krylov Vector orthogonal to previous ones
    @inbounds for j in 1:n
        gmres.H[j, I] = 0
        # dot products
        @inbounds for i in 1:(gmres.m)
            gmres.H[j, I] += gmres.Q[i, j, I] * gmres.sol[i, I]
        end
        # orthogonalize latest Krylov Vector
        @inbounds for i in 1:(gmres.m)
            gmres.sol[i, I] -= gmres.H[j, I] * gmres.Q[i, j, I]
        end
    end
    norm_q = 0.0
    @inbounds for i in 1:(gmres.m)
        norm_q += gmres.sol[i, I] * gmres.sol[i, I]
    end
    gmres.H[n + 1, I] = sqrt(norm_q)
    @inbounds for i in 1:(gmres.m)
        gmres.Q[i, n + 1, I] = gmres.sol[i, I] / gmres.H[n + 1, I]
    end
    return nothing
end

"""
    update_QR!(n, gmres, I)

# Description
Given a QR decomposition of the first n-1 columns of an upper hessenberg matrix, this computes the QR decomposition associated with the first n columns
# Arguments
- `gmres`: (struct) [OVERWRITTEN] the struct has factors that are updated
- `n`: (integer) column that needs to be updated
- `I`: (int) thread index
# Return
- nothing

# Comment
What is actually produced by the algorithm isn't the Q in the QR decomposition but rather Q^*. This is convenient since this is what is actually needed to solve the linear system
"""
@inline function update_QR!(n, gmres, I)
    # Apply previous Q to new column
    @inbounds for i in 1:n
        gmres.R[i, n, I] = gmres.H[i, I]
    end
    # apply rotation
    @inbounds for i in 1:(n - 1)
        tmp1 =
            gmres.cs[1 + 2 * (i - 1), I] * gmres.R[i, n, I] -
            gmres.cs[2 * i, I] * gmres.R[i + 1, n, I]
        gmres.R[i + 1, n, I] =
            gmres.cs[2 * i, I] * gmres.R[i, n, I] +
            gmres.cs[1 + 2 * (i - 1), I] * gmres.R[i + 1, n, I]
        gmres.R[i, n, I] = tmp1
    end
    # Now update, cs and R
    gmres.cs[1 + 2 * (n - 1), I] = gmres.R[n, n, I]
    gmres.cs[2 * n, I] = gmres.H[n + 1, I]
    gmres.R[n, n, I] =
        sqrt(gmres.cs[1 + 2 * (n - 1), I]^2 + gmres.cs[2 * n, I]^2)
    gmres.cs[1 + 2 * (n - 1), I] /= gmres.R[n, n, I]
    gmres.cs[2 * n, I] /= -gmres.R[n, n, I]
    return nothing
end

"""
    solve_optimization!(iteration, gmres, I)

# Description
Solves the optimization problem in GMRES
# Arguments
- `iteration`: (int) current iteration number
- `gmres`: (struct) [OVERWRITTEN]
- `I`: (int) thread index
# Return
nothing
"""
@inline function solve_optimization!(n, gmres, I)
    # just need to update rhs from previous iteration
    # apply latest givens rotation
    tmp1 =
        gmres.cs[1 + 2 * (n - 1), I] * gmres.rhs[n, I] -
        gmres.cs[2 * n, I] * gmres.rhs[n + 1, I]
    gmres.rhs[n + 1, I] =
        gmres.cs[2 * n, I] * gmres.rhs[n, I] +
        gmres.cs[1 + 2 * (n - 1), I] * gmres.rhs[n + 1, I]
    gmres.rhs[n, I] = tmp1
    # gmres.rhs[iteration+1] is the residual. Technically convergence should be checked here.
    gmres.residual[n, I] = abs.(gmres.rhs[n + 1, I])
    # copy for performing the backsolve and saving gmres.rhs
    @inbounds for i in 1:n
        gmres.sol[i, I] = gmres.rhs[i, I]
    end
    # do the backsolve
    @inbounds for i in n:-1:1
        gmres.sol[i, I] /= gmres.R[i, i, I]
        @inbounds for j in 1:(i - 1)
            gmres.sol[j, I] -= gmres.R[j, i, I] * gmres.sol[i, I]
        end
    end
    return nothing
end

"""
    compute_residuals(gmres, i)

# Description
Compute atol and rtol of current iteration

# Arguments
- `gmres`: (struct)
- `i`: (current iteration)

# Return
- `atol`: (float) absolute tolerance
- `rtol`: (float) relative tolerance

# Comment
sometimes gmres.R[1, 1,:] term has some very large components which makes rtol quite small
"""
function compute_residuals(gmres, i)
    atol = maximum(gmres.residual[i, :])
    rtol = maximum(gmres.residual[i, :] ./ norm(gmres.R[1, 1, :]))
    return atol, rtol
end

max_stars_repo_name: leios/CLIMA

max_issues_repo_name: leios/CLIMA

max_forks_repo_name: leios/CLIMA


text:
using TropicalGEMM, BenchmarkTools
using Octavian
using DelimitedFiles

function run_benchmarks(cases, suite; output_file)
    tune!(suite)
    res = run(suite)

    times = zeros(length(cases))
    for (k, case) in enumerate(cases)
        times[k] = minimum(res[case].times)
    end

    println("Writing benchmark results to file: $output_file.")
    mkpath(dirname(output_file))
    writedlm(output_file, times)
end

function naivemm!(o::Matrix, a::Matrix, b::Matrix)
    @assert size(a, 2) == size(b, 1) && size(o) == (size(a, 1), size(b, 2))
    for j=1:size(b, 2)
        for k=1:size(a, 2)
            for i=1:size(a, 1)
                @inbounds o[i,j] += a[i,k] * b[k,j]
            end
        end
    end
    return o
end

function generate_suite(; multithreading)
    cases = []
    suite = BenchmarkGroup()
    for s=1:12
        for T in (Float32, Float64, Int)
            n = 1<<s
            if multithreading
                push!(cases, "octavian-$T-$n")
                suite["octavian-$T-$n"] = @benchmarkable Octavian.matmul!(o, a, b) setup=(a = Tropical.(ones($T, $n, $n)); b = Tropical.(ones($T, $n, $n)); o = zeros(Tropical{$T}, $n, $n))
            else
                push!(cases, "naive-$T-$n")
                suite["naive-$T-$n"] = @benchmarkable naivemm!(o, a, b) setup=(a = Tropical.(ones($T, $n, $n)); b = Tropical.(ones($T, $n, $n)); o = zeros(Tropical{$T}, $n, $n))
                push!(cases, "octavian-$T-$n")
                suite["octavian-$T-$n"] = @benchmarkable Octavian.matmul_serial!(o, a, b) setup=(a = Tropical.(ones($T, $n, $n)); b = Tropical.(ones($T, $n, $n)); o = zeros(Tropical{$T}, $n, $n))
            end
        end
    end
    cases, suite
end

nthreads = Base.Threads.nthreads()
if  nthreads == 1
    cases, suite = generate_suite(multithreading=false)
    run_benchmarks(cases, suite; output_file=joinpath(@__DIR__, "benchmarks.dat"))
else
    cases, suite = generate_suite(multithreading=true)
    run_benchmarks(cases, suite; output_file=joinpath(@__DIR__, "benchmarks-$nthreads.dat"))
end

ext: jl


text:
"""
    module Simulate_NewtonsCradle

Model of [Newtons' Cradle](https://en.wikipedia.org/wiki/Newton%27s_cradle).

The balls of the Newton Cradle are initially placed in such a way, that there is a small
distance between the balls, so the balls are **not** touching each other. This distance was
determined (by trial-and-error) in such a way, that collisions between the balls
occur in sequence (so if ball1 hits ball2, then ball3 is hit by ball2 only after the
contact between ball1 and ball2 has already ended; this can be easily determined by
setting `simulate!(..., log=true)`). Only in this case, the simulation matches the
real experiment. If the balls are directly touching each other, multiple contacts
occur at the same time instant and the simulation result is then no longer according
to reality.

See also:

M. Payr (2008): **[An Experimental and Theoretical Study of Perfect Multiple
                Contact Collisions in Linear Chains of Balls.](http://www.zfm.ethz.ch/e/dynamics/payr_collisions.htm)**
                Dissertation, ETH Zürich.
"""
module Simulate_NewtonsCradle

using  Modia3D
import Modia3D.ModiaMath

vmatGraphics = Material(color="LightBlue", transparency=0.1)   # material of Graphics
vmatSolids   = Material(color="Red"      , transparency=0.0)   # material of solids

diameter   = 0.02
lengthWire = 0.15
rsmall     = diameter/100
#rsmall = 0.0

Lx = diameter/2
Ly = 5*diameter
Lz = Lx

@assembly Pendulum() begin
  wire = Object3D( Cylinder(diameter/5, lengthWire; material=vmatGraphics) )

  frame1 = Object3D(wire; r=[0.0, 0.0,  lengthWire/2])
  frame2 = Object3D(wire; r=[0.0, 0.0, -lengthWire/2])

  cylinder = Object3D(frame1, Cylinder(0.6*Lx, 1.4*Lx; material=vmatSolids); R=ModiaMath.rot2(-pi/2))
  sphere   = Object3D(frame2, Solid(SolidSphere(diameter), "Steel", vmatSolids; contactMaterial="BilliardBall") )
end

@assembly NewtonsCradle() begin
  world  = Object3D(visualizeFrame=true)
  box    = Object3D(world, Box(Lx, Ly, Lz; material=vmatGraphics))

  frame1 = Object3D(box; r=[0.0, -2*(diameter+rsmall), 0.0])
  frame2 = Object3D(box; r=[0.0,   -(diameter+rsmall), 0.0])
  frame3 = Object3D(box; r=[0.0,                  0.0, 0.0])
  frame4 = Object3D(box; r=[0.0,    (diameter+rsmall), 0.0])
  frame5 = Object3D(box; r=[0.0,  2*(diameter+rsmall), 0.0])

  pendulum1 = Pendulum()
  pendulum2 = Pendulum()
  pendulum3 = Pendulum()
  pendulum4 = Pendulum()
  pendulum5 = Pendulum()

  rev1 = Revolute(frame1, pendulum1.frame1; axis = 1 , phi_start =  -pi/3)
  rev2 = Revolute(frame2, pendulum2.frame1; axis = 1 )#,phi_start =  -pi/3)
  rev3 = Revolute(frame3, pendulum3.frame1; axis = 1 ) #, phi_start =  -pi/3)
  rev4 = Revolute(frame4, pendulum4.frame1; axis = 1 )#,phi_start =  pi/3 ) #
  rev5 = Revolute(frame5, pendulum5.frame1; axis = 1 )#,phi_start =  pi/3 ) #
end

gravField     = UniformGravityField(g=9.81, n=[0,0,-1])
newtonsCradle = NewtonsCradle(sceneOptions=SceneOptions(elasticContactReductionFactor=1.0, gravityField=gravField, visualizeFrames=false,
                                                        defaultFrameLength=2*diameter, enableContactDetection=true))

# Modia3D.visualizeAssembly!( newtonsCradle )
model  = SimulationModel( newtonsCradle )
result = ModiaMath.simulate!(model; stopTime=10.0, tolerance=1e-8, log=false)

println("... success of examples/collisions/Simulate_NewtonsCradle.jl!")
end


text:
#file with the LaTeXSVG constant
const LaTeXSVG = Dict{LaTeXString,String}(
    L"\mathcal{O}(\log{n})" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"8.413ex\" height=\"2.843ex\" style=\"vertical-align: -0.838ex;\" viewBox=\"0 -863.1 3622.2 1223.9\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">script upper O left-parenthesis log n right-parenthesis</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJCAL-4F\" d=\"M308 428Q289 428 289 438Q289 457 318 508T378 593Q417 638 475 671T599 705Q688 705 732 643T777 483Q777 380 733 285T620 123T464 18T293 -22Q188 -22 123 51T58 245Q58 327 87 403T159 533T249 626T333 685T388 705Q404 705 404 693Q404 674 363 649Q333 632 304 606T239 537T181 429T158 290Q158 179 214 114T364 48Q489 48 583 165T677 438Q677 473 670 505T648 568T601 617T528 636Q518 636 513 635Q486 629 460 600T419 544T392 490Q383 470 372 459Q341 430 308 428Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-28\" d=\"M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-6C\" d=\"M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-6F\" d=\"M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-67\" d=\"M329 409Q373 453 429 453Q459 453 472 434T485 396Q485 382 476 371T449 360Q416 360 412 390Q410 404 415 411Q415 412 416 414V415Q388 412 363 393Q355 388 355 386Q355 385 359 381T368 369T379 351T388 325T392 292Q392 230 343 187T222 143Q172 143 123 171Q112 153 112 133Q112 98 138 81Q147 75 155 75T227 73Q311 72 335 67Q396 58 431 26Q470 -13 470 -72Q470 -139 392 -175Q332 -206 250 -206Q167 -206 107 -175Q29 -140 29 -75Q29 -39 50 -15T92 18L103 24Q67 55 67 108Q67 155 96 193Q52 237 52 292Q52 355 102 398T223 442Q274 442 318 416L329 409ZM299 343Q294 371 273 387T221 404Q192 404 171 388T145 343Q142 326 142 292Q142 248 149 227T179 192Q196 182 222 182Q244 182 260 189T283 207T294 227T299 242Q302 258 302 292T299 343ZM403 -75Q403 -50 389 -34T348 -11T299 -2T245 0H218Q151 0 138 -6Q118 -15 107 -34T95 -74Q95 -84 101 -97T122 -127T170 -155T250 -167Q319 -167 361 -139T403 -75Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-6E\" d=\"M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-29\" d=\"M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n <use xlink:href=\"#E1-MJCAL-4F\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-28\" x=\"796\" y=\"0\"></use>\n<g transform=\"translate(1186,0)\">\n <use xlink:href=\"#E1-MJMAIN-6C\"></use>\n <use xlink:href=\"#E1-MJMAIN-6F\" x=\"278\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-67\" x=\"779\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMATHI-6E\" x=\"2632\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-29\" x=\"3232\" y=\"0\"></use>\n</g>\n</svg>",
    L"\mathcal{O}\left(\frac{\log{x}}{2}\right)" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"11.183ex\" height=\"6.176ex\" style=\"vertical-align: -2.505ex;\" viewBox=\"0 -1580.7 4814.8 2659.1\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">script upper O left-parenthesis StartFrobject log x Over 2 EndFrobject right-parenthesis</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJCAL-4F\" d=\"M308 428Q289 428 289 438Q289 457 318 508T378 593Q417 638 475 671T599 705Q688 705 732 643T777 483Q777 380 733 285T620 123T464 18T293 -22Q188 -22 123 51T58 245Q58 327 87 403T159 533T249 626T333 685T388 705Q404 705 404 693Q404 674 363 649Q333 632 304 606T239 537T181 429T158 290Q158 179 214 114T364 48Q489 48 583 165T677 438Q677 473 670 505T648 568T601 617T528 636Q518 636 513 635Q486 629 460 600T419 544T392 490Q383 470 372 459Q341 430 308 428Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-28\" d=\"M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-6C\" d=\"M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-6F\" d=\"M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-67\" d=\"M329 409Q373 453 429 453Q459 453 472 434T485 396Q485 382 476 371T449 360Q416 360 412 390Q410 404 415 411Q415 412 416 414V415Q388 412 363 393Q355 388 355 386Q355 385 359 381T368 369T379 351T388 325T392 292Q392 230 343 187T222 143Q172 143 123 171Q112 153 112 133Q112 98 138 81Q147 75 155 75T227 73Q311 72 335 67Q396 58 431 26Q470 -13 470 -72Q470 -139 392 -175Q332 -206 250 -206Q167 -206 107 -175Q29 -140 29 -75Q29 -39 50 -15T92 18L103 24Q67 55 67 108Q67 155 96 193Q52 237 52 292Q52 355 102 398T223 442Q274 442 318 416L329 409ZM299 343Q294 371 273 387T221 404Q192 404 171 388T145 343Q142 326 142 292Q142 248 149 227T179 192Q196 182 222 182Q244 182 260 189T283 207T294 227T299 242Q302 258 302 292T299 343ZM403 -75Q403 -50 389 -34T348 -11T299 -2T245 0H218Q151 0 138 -6Q118 -15 107 -34T95 -74Q95 -84 101 -97T122 -127T170 -155T250 -167Q319 -167 361 -139T403 -75Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-78\" d=\"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-29\" d=\"M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ3-28\" d=\"M701 -940Q701 -943 695 -949H664Q662 -947 636 -922T591 -879T537 -818T475 -737T412 -636T350 -511T295 -362T250 -186T221 17T209 251Q209 962 573 1361Q596 1386 616 1405T649 1437T664 1450H695Q701 1444 701 1441Q701 1436 681 1415T629 1356T557 1261T476 1118T400 927T340 675T308 359Q306 321 306 250Q306 -139 400 -430T690 -924Q701 -936 701 -940Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ3-29\" d=\"M34 1438Q34 1446 37 1448T50 1450H56H71Q73 1448 99 1423T144 1380T198 1319T260 1238T323 1137T385 1013T440 864T485 688T514 485T526 251Q526 134 519 53Q472 -519 162 -860Q139 -885 119 -904T86 -936T71 -949H56Q43 -949 39 -947T34 -937Q88 -883 140 -813Q428 -430 428 251Q428 453 402 628T338 922T245 1146T145 1309T46 1425Q44 1427 42 1429T39 1433T36 1436L34 1438Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n <use xlink:href=\"#E1-MJCAL-4F\" x=\"0\" y=\"0\"></use>\n<g transform=\"translate(963,0)\">\n <use xlink:href=\"#E1-MJSZ3-28\"></use>\n<g transform=\"translate(736,0)\">\n<g transform=\"translate(120,0)\">\n<rect stroke=\"none\" width=\"2138\" height=\"60\" x=\"0\" y=\"220\"></rect>\n<g transform=\"translate(60,726)\">\n <use xlink:href=\"#E1-MJMAIN-6C\"></use>\n <use xlink:href=\"#E1-MJMAIN-6F\" x=\"278\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-67\" x=\"779\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMATHI-78\" x=\"1446\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"819\" y=\"-687\"></use>\n</g>\n</g>\n <use xlink:href=\"#E1-MJSZ3-29\" x=\"3115\" y=\"-1\"></use>\n</g>\n</g>\n</svg>",
    L"E=mc^2" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"8.976ex\" height=\"2.676ex\" style=\"vertical-align: -0.338ex;\" viewBox=\"0 -1006.6 3864.5 1152.1\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">upper E equals m c squared</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMATHI-45\" d=\"M492 213Q472 213 472 226Q472 230 477 250T482 285Q482 316 461 323T364 330H312Q311 328 277 192T243 52Q243 48 254 48T334 46Q428 46 458 48T518 61Q567 77 599 117T670 248Q680 270 683 272Q690 274 698 274Q718 274 718 261Q613 7 608 2Q605 0 322 0H133Q31 0 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H757Q764 676 764 669Q764 664 751 557T737 447Q735 440 717 440H705Q698 445 698 453L701 476Q704 500 704 528Q704 558 697 578T678 609T643 625T596 632T532 634H485Q397 633 392 631Q388 629 386 622Q385 619 355 499T324 377Q347 376 372 376H398Q464 376 489 391T534 472Q538 488 540 490T557 493Q562 493 565 493T570 492T572 491T574 487T577 483L544 351Q511 218 508 216Q505 213 492 213Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-3D\" d=\"M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-6D\" d=\"M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-63\" d=\"M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n <use xlink:href=\"#E1-MJMATHI-45\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-3D\" x=\"1042\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMATHI-6D\" x=\"2098\" y=\"0\"></use>\n<g transform=\"translate(2977,0)\">\n <use xlink:href=\"#E1-MJMATHI-63\" x=\"0\" y=\"0\"></use>\n <use transform=\"scale(0.707)\" xlink:href=\"#E1-MJMAIN-32\" x=\"613\" y=\"583\"></use>\n</g>\n</g>\n</svg>\n",
    L"8" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1.162ex\" height=\"2.176ex\" style=\"vertical-align: -0.338ex;\" viewBox=\"0 -791.3 500.5 936.9\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">8</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-38\" d=\"M70 417T70 494T124 618T248 666Q319 666 374 624T429 515Q429 485 418 459T392 417T361 389T335 371T324 363L338 354Q352 344 366 334T382 323Q457 264 457 174Q457 95 399 37T249 -22Q159 -22 101 29T43 155Q43 263 172 335L154 348Q133 361 127 368Q70 417 70 494ZM286 386L292 390Q298 394 301 396T311 403T323 413T334 425T345 438T355 454T364 471T369 491T371 513Q371 556 342 586T275 624Q268 625 242 625Q201 625 165 599T128 534Q128 511 141 492T167 463T217 431Q224 426 228 424L286 386ZM250 21Q308 21 350 55T392 137Q392 154 387 169T375 194T353 216T330 234T301 253T274 270Q260 279 244 289T218 306L210 311Q204 311 181 294T133 239T107 157Q107 98 150 60T250 21Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n <use xlink:href=\"#E1-MJMAIN-38\" x=\"0\" y=\"0\"></use>\n</g>\n</svg>\n",
    L"$\begin{equation}\left[\begin{array}{ccc}1 & 2 & 3 \\4 & 5 & 6 \\7 & 8 & 9 \\\end{array}\right]\end{equation}$" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"11.985ex\" height=\"9.176ex\" style=\"vertical-align: -4.005ex;\" viewBox=\"0 -2226.5 5160 3950.7\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">Start 3 By 3 Matrix 1st Row 1st Column 1 2nd Column 2 3rd Column 3 2nd Row 1st Column 4 2nd Column 5 3rd Column 6 3rd Row 1st Column 7 2nd Column 8 3rd Column 9 EndMatrix</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5B\" d=\"M118 -250V750H255V710H158V-210H255V-250H118Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-31\" d=\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-33\" d=\"M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-34\" d=\"M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-35\" d=\"M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-36\" d=\"M42 313Q42 476 123 571T303 666Q372 666 402 630T432 550Q432 525 418 510T379 495Q356 495 341 509T326 548Q326 592 373 601Q351 623 311 626Q240 626 194 566Q147 500 147 364L148 360Q153 366 156 373Q197 433 263 433H267Q313 433 348 414Q372 400 396 374T435 317Q456 268 456 210V192Q456 169 451 149Q440 90 387 34T253 -22Q225 -22 199 -14T143 16T92 75T56 172T42 313ZM257 397Q227 397 205 380T171 335T154 278T148 216Q148 133 160 97T198 39Q222 21 251 21Q302 21 329 59Q342 77 347 104T352 209Q352 289 347 316T329 361Q302 397 257 397Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-37\" d=\"M55 458Q56 460 72 567L88 674Q88 676 108 676H128V672Q128 662 143 655T195 646T364 644H485V605L417 512Q408 500 387 472T360 435T339 403T319 367T305 330T292 284T284 230T278 162T275 80Q275 66 275 52T274 28V19Q270 2 255 -10T221 -22Q210 -22 200 -19T179 0T168 40Q168 198 265 368Q285 400 349 489L395 552H302Q128 552 119 546Q113 543 108 522T98 479L95 458V455H55V458Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-38\" d=\"M70 417T70 494T124 618T248 666Q319 666 374 624T429 515Q429 485 418 459T392 417T361 389T335 371T324 363L338 354Q352 344 366 334T382 323Q457 264 457 174Q457 95 399 37T249 -22Q159 -22 101 29T43 155Q43 263 172 335L154 348Q133 361 127 368Q70 417 70 494ZM286 386L292 390Q298 394 301 396T311 403T323 413T334 425T345 438T355 454T364 471T369 491T371 513Q371 556 342 586T275 624Q268 625 242 625Q201 625 165 599T128 534Q128 511 141 492T167 463T217 431Q224 426 228 424L286 386ZM250 21Q308 21 350 55T392 137Q392 154 387 169T375 194T353 216T330 234T301 253T274 270Q260 279 244 289T218 306L210 311Q204 311 181 294T133 239T107 157Q107 98 150 60T250 21Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-39\" d=\"M352 287Q304 211 232 211Q154 211 104 270T44 396Q42 412 42 436V444Q42 537 111 606Q171 666 243 666Q245 666 249 666T257 665H261Q273 665 286 663T323 651T370 619T413 560Q456 472 456 334Q456 194 396 97Q361 41 312 10T208 -22Q147 -22 108 7T68 93T121 149Q143 149 158 135T173 96Q173 78 164 65T148 49T135 44L131 43Q131 41 138 37T164 27T206 22H212Q272 22 313 86Q352 142 352 280V287ZM244 248Q292 248 321 297T351 430Q351 508 343 542Q341 552 337 562T323 588T293 615T246 625Q208 625 181 598Q160 576 154 546T147 441Q147 358 152 329T172 282Q197 248 244 248Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5D\" d=\"M22 710V750H159V-250H22V-210H119V710H22Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A1\" d=\"M319 -645V1154H666V1070H403V-645H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A3\" d=\"M319 -644V1155H403V-560H666V-644H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A2\" d=\"M319 0V602H403V0H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A4\" d=\"M0 1070V1154H347V-645H263V1070H0Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A6\" d=\"M263 -560V1155H347V-644H0V-560H263Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A5\" d=\"M263 0V602H347V0H263Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n<g transform=\"translate(0,2150)\">\n <use xlink:href=\"#E1-MJSZ4-23A1\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2048.5066225165565) scale(1,0.49337748344370863)\">\n <use xlink:href=\"#E1-MJSZ4-23A2\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A3\" x=\"0\" y=\"-3155\"></use>\n</g>\n<g transform=\"translate(834,0)\">\n<g transform=\"translate(-11,0)\">\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"0\" y=\"1350\"></use>\n <use xlink:href=\"#E1-MJMAIN-34\" x=\"0\" y=\"-50\"></use>\n <use xlink:href=\"#E1-MJMAIN-37\" x=\"0\" y=\"-1450\"></use>\n</g>\n<g transform=\"translate(1490,0)\">\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"0\" y=\"1350\"></use>\n <use xlink:href=\"#E1-MJMAIN-35\" x=\"0\" y=\"-50\"></use>\n <use xlink:href=\"#E1-MJMAIN-38\" x=\"0\" y=\"-1450\"></use>\n</g>\n<g transform=\"translate(2990,0)\">\n <use xlink:href=\"#E1-MJMAIN-33\" x=\"0\" y=\"1350\"></use>\n <use xlink:href=\"#E1-MJMAIN-36\" x=\"0\" y=\"-50\"></use>\n <use xlink:href=\"#E1-MJMAIN-39\" x=\"0\" y=\"-1450\"></use>\n</g>\n</g>\n<g transform=\"translate(4492,2150)\">\n <use xlink:href=\"#E1-MJSZ4-23A4\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2048.5066225165565) scale(1,0.49337748344370863)\">\n <use xlink:href=\"#E1-MJSZ4-23A5\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A6\" x=\"0\" y=\"-3155\"></use>\n</g>\n</g>\n</svg>\n",
    L"$\begin{equation}\left[\begin{array}{ccc}\alpha & \beta & \gamma \\x^{2} & \sqrt{y} & \lambda \\1 & 2 & y \\\end{array}\right]\end{equation}$" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"15.328ex\" height=\"9.843ex\" style=\"vertical-align: -4.338ex;\" viewBox=\"0 -2370 6599.5 4237.8\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">Start 3 By 3 Matrix 1st Row 1st Column alpha 2nd Column beta 3rd Column gamma 2nd Row 1st Column x squared 2nd Column StartRoot y EndRoot 3rd Column lamda 3rd Row 1st Column 1 2nd Column 2 3rd Column y EndMatrix</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5B\" d=\"M118 -250V750H255V710H158V-210H255V-250H118Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B1\" d=\"M34 156Q34 270 120 356T309 442Q379 442 421 402T478 304Q484 275 485 237V208Q534 282 560 374Q564 388 566 390T582 393Q603 393 603 385Q603 376 594 346T558 261T497 161L486 147L487 123Q489 67 495 47T514 26Q528 28 540 37T557 60Q559 67 562 68T577 70Q597 70 597 62Q597 56 591 43Q579 19 556 5T512 -10H505Q438 -10 414 62L411 69L400 61Q390 53 370 41T325 18T267 -2T203 -11Q124 -11 79 39T34 156ZM208 26Q257 26 306 47T379 90L403 112Q401 255 396 290Q382 405 304 405Q235 405 183 332Q156 292 139 224T121 120Q121 71 146 49T208 26Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B2\" d=\"M29 -194Q23 -188 23 -186Q23 -183 102 134T186 465Q208 533 243 584T309 658Q365 705 429 705H431Q493 705 533 667T573 570Q573 465 469 396L482 383Q533 332 533 252Q533 139 448 65T257 -10Q227 -10 203 -2T165 17T143 40T131 59T126 65L62 -188Q60 -194 42 -194H29ZM353 431Q392 431 427 419L432 422Q436 426 439 429T449 439T461 453T472 471T484 495T493 524T501 560Q503 569 503 593Q503 611 502 616Q487 667 426 667Q384 667 347 643T286 582T247 514T224 455Q219 439 186 308T152 168Q151 163 151 147Q151 99 173 68Q204 26 260 26Q302 26 349 51T425 137Q441 171 449 214T457 279Q457 337 422 372Q380 358 347 358H337Q258 358 258 389Q258 396 261 403Q275 431 353 431Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B3\" d=\"M31 249Q11 249 11 258Q11 275 26 304T66 365T129 418T206 441Q233 441 239 440Q287 429 318 386T371 255Q385 195 385 170Q385 166 386 166L398 193Q418 244 443 300T486 391T508 430Q510 431 524 431H537Q543 425 543 422Q543 418 522 378T463 251T391 71Q385 55 378 6T357 -100Q341 -165 330 -190T303 -216Q286 -216 286 -188Q286 -138 340 32L346 51L347 69Q348 79 348 100Q348 257 291 317Q251 355 196 355Q148 355 108 329T51 260Q49 251 47 251Q45 249 31 249Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-78\" d=\"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-79\" d=\"M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-221A\" d=\"M95 178Q89 178 81 186T72 200T103 230T169 280T207 309Q209 311 212 311H213Q219 311 227 294T281 177Q300 134 312 108L397 -77Q398 -77 501 136T707 565T814 786Q820 800 834 800Q841 800 846 794T853 782V776L620 293L385 -193Q381 -200 366 -200Q357 -200 354 -197Q352 -195 256 15L160 225L144 214Q129 202 113 190T95 178Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3BB\" d=\"M166 673Q166 685 183 694H202Q292 691 316 644Q322 629 373 486T474 207T524 67Q531 47 537 34T546 15T551 6T555 2T556 -2T550 -11H482Q457 3 450 18T399 152L354 277L340 262Q327 246 293 207T236 141Q211 112 174 69Q123 9 111 -1T83 -12Q47 -12 47 20Q47 37 61 52T199 187Q229 216 266 252T321 306L338 322Q338 323 288 462T234 612Q214 657 183 657Q166 657 166 673Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-31\" d=\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5D\" d=\"M22 710V750H159V-250H22V-210H119V710H22Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A1\" d=\"M319 -645V1154H666V1070H403V-645H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A3\" d=\"M319 -644V1155H403V-560H666V-644H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A2\" d=\"M319 0V602H403V0H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A4\" d=\"M0 1070V1154H347V-645H263V1070H0Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A6\" d=\"M263 -560V1155H347V-644H0V-560H263Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A5\" d=\"M263 0V602H347V0H263Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n<g transform=\"translate(0,2266)\">\n <use xlink:href=\"#E1-MJSZ4-23A1\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2281.4717520695544) scale(1,0.8797209818732245)\">\n <use xlink:href=\"#E1-MJSZ4-23A2\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A3\" x=\"0\" y=\"-3389\"></use>\n</g>\n<g transform=\"translate(834,0)\">\n<g transform=\"translate(-11,0)\">\n <use xlink:href=\"#E1-MJMATHI-3B1\" x=\"192\" y=\"1466\"></use>\n<g transform=\"translate(0,15)\">\n <use xlink:href=\"#E1-MJMATHI-78\" x=\"0\" y=\"0\"></use>\n <use transform=\"scale(0.707)\" xlink:href=\"#E1-MJMAIN-32\" x=\"809\" y=\"513\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"262\" y=\"-1561\"></use>\n</g>\n<g transform=\"translate(2015,0)\">\n <use xlink:href=\"#E1-MJMATHI-3B2\" x=\"378\" y=\"1466\"></use>\n<g transform=\"translate(0,15)\">\n <use xlink:href=\"#E1-MJMAIN-221A\" x=\"0\" y=\"-175\"></use>\n<rect stroke=\"none\" width=\"497\" height=\"60\" x=\"833\" y=\"566\"></rect>\n <use xlink:href=\"#E1-MJMATHI-79\" x=\"833\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"415\" y=\"-1561\"></use>\n</g>\n<g transform=\"translate(4346,0)\">\n <use xlink:href=\"#E1-MJMATHI-3B3\" x=\"20\" y=\"1466\"></use>\n <use xlink:href=\"#E1-MJMATHI-3BB\" x=\"0\" y=\"15\"></use>\n <use xlink:href=\"#E1-MJMATHI-79\" x=\"43\" y=\"-1561\"></use>\n</g>\n</g>\n<g transform=\"translate(5931,2266)\">\n <use xlink:href=\"#E1-MJSZ4-23A4\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2281.4717520695544) scale(1,0.8797209818732245)\">\n <use xlink:href=\"#E1-MJSZ4-23A5\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A6\" x=\"0\" y=\"-3389\"></use>\n</g>\n</g>\n</svg>\n",
    L"$\begin{equation}\left[\begin{array}{ccc}\alpha & x^{2} & 1 \\\beta & \sqrt{y} & 2 \\\gamma & \lambda & y \\\end{array}\right]\end{equation}$" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"14.239ex\" height=\"9.843ex\" style=\"vertical-align: -4.338ex;\" viewBox=\"0 -2370 6130.5 4237.8\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">Start 3 By 3 Matrix 1st Row 1st Column alpha 2nd Column x squared 3rd Column 1 2nd Row 1st Column beta 2nd Column StartRoot y EndRoot 3rd Column 2 3rd Row 1st Column gamma 2nd Column lamda 3rd Column y EndMatrix</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5B\" d=\"M118 -250V750H255V710H158V-210H255V-250H118Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B1\" d=\"M34 156Q34 270 120 356T309 442Q379 442 421 402T478 304Q484 275 485 237V208Q534 282 560 374Q564 388 566 390T582 393Q603 393 603 385Q603 376 594 346T558 261T497 161L486 147L487 123Q489 67 495 47T514 26Q528 28 540 37T557 60Q559 67 562 68T577 70Q597 70 597 62Q597 56 591 43Q579 19 556 5T512 -10H505Q438 -10 414 62L411 69L400 61Q390 53 370 41T325 18T267 -2T203 -11Q124 -11 79 39T34 156ZM208 26Q257 26 306 47T379 90L403 112Q401 255 396 290Q382 405 304 405Q235 405 183 332Q156 292 139 224T121 120Q121 71 146 49T208 26Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-78\" d=\"M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-31\" d=\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B2\" d=\"M29 -194Q23 -188 23 -186Q23 -183 102 134T186 465Q208 533 243 584T309 658Q365 705 429 705H431Q493 705 533 667T573 570Q573 465 469 396L482 383Q533 332 533 252Q533 139 448 65T257 -10Q227 -10 203 -2T165 17T143 40T131 59T126 65L62 -188Q60 -194 42 -194H29ZM353 431Q392 431 427 419L432 422Q436 426 439 429T449 439T461 453T472 471T484 495T493 524T501 560Q503 569 503 593Q503 611 502 616Q487 667 426 667Q384 667 347 643T286 582T247 514T224 455Q219 439 186 308T152 168Q151 163 151 147Q151 99 173 68Q204 26 260 26Q302 26 349 51T425 137Q441 171 449 214T457 279Q457 337 422 372Q380 358 347 358H337Q258 358 258 389Q258 396 261 403Q275 431 353 431Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-79\" d=\"M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-221A\" d=\"M95 178Q89 178 81 186T72 200T103 230T169 280T207 309Q209 311 212 311H213Q219 311 227 294T281 177Q300 134 312 108L397 -77Q398 -77 501 136T707 565T814 786Q820 800 834 800Q841 800 846 794T853 782V776L620 293L385 -193Q381 -200 366 -200Q357 -200 354 -197Q352 -195 256 15L160 225L144 214Q129 202 113 190T95 178Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3B3\" d=\"M31 249Q11 249 11 258Q11 275 26 304T66 365T129 418T206 441Q233 441 239 440Q287 429 318 386T371 255Q385 195 385 170Q385 166 386 166L398 193Q418 244 443 300T486 391T508 430Q510 431 524 431H537Q543 425 543 422Q543 418 522 378T463 251T391 71Q385 55 378 6T357 -100Q341 -165 330 -190T303 -216Q286 -216 286 -188Q286 -138 340 32L346 51L347 69Q348 79 348 100Q348 257 291 317Q251 355 196 355Q148 355 108 329T51 260Q49 251 47 251Q45 249 31 249Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMATHI-3BB\" d=\"M166 673Q166 685 183 694H202Q292 691 316 644Q322 629 373 486T474 207T524 67Q531 47 537 34T546 15T551 6T555 2T556 -2T550 -11H482Q457 3 450 18T399 152L354 277L340 262Q327 246 293 207T236 141Q211 112 174 69Q123 9 111 -1T83 -12Q47 -12 47 20Q47 37 61 52T199 187Q229 216 266 252T321 306L338 322Q338 323 288 462T234 612Q214 657 183 657Q166 657 166 673Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5D\" d=\"M22 710V750H159V-250H22V-210H119V710H22Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A1\" d=\"M319 -645V1154H666V1070H403V-645H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A3\" d=\"M319 -644V1155H403V-560H666V-644H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A2\" d=\"M319 0V602H403V0H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A4\" d=\"M0 1070V1154H347V-645H263V1070H0Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A6\" d=\"M263 -560V1155H347V-644H0V-560H263Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A5\" d=\"M263 0V602H347V0H263Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n<g transform=\"translate(0,2263)\">\n <use xlink:href=\"#E1-MJSZ4-23A1\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2275.4816858443887) scale(1,0.8697872070387873)\">\n <use xlink:href=\"#E1-MJSZ4-23A2\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A3\" x=\"0\" y=\"-3383\"></use>\n</g>\n<g transform=\"translate(834,0)\">\n<g transform=\"translate(-11,0)\">\n <use xlink:href=\"#E1-MJMATHI-3B1\" x=\"0\" y=\"1429\"></use>\n <use xlink:href=\"#E1-MJMATHI-3B2\" x=\"33\" y=\"29\"></use>\n <use xlink:href=\"#E1-MJMATHI-3B3\" x=\"48\" y=\"-1547\"></use>\n</g>\n<g transform=\"translate(1630,0)\">\n<g transform=\"translate(152,1429)\">\n <use xlink:href=\"#E1-MJMATHI-78\" x=\"0\" y=\"0\"></use>\n <use transform=\"scale(0.707)\" xlink:href=\"#E1-MJMAIN-32\" x=\"809\" y=\"513\"></use>\n</g>\n<g transform=\"translate(0,29)\">\n <use xlink:href=\"#E1-MJMAIN-221A\" x=\"0\" y=\"-175\"></use>\n<rect stroke=\"none\" width=\"497\" height=\"60\" x=\"833\" y=\"566\"></rect>\n <use xlink:href=\"#E1-MJMATHI-79\" x=\"833\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMATHI-3BB\" x=\"373\" y=\"-1547\"></use>\n</g>\n<g transform=\"translate(3961,0)\">\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"0\" y=\"1429\"></use>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"0\" y=\"29\"></use>\n <use xlink:href=\"#E1-MJMATHI-79\" x=\"1\" y=\"-1547\"></use>\n</g>\n</g>\n<g transform=\"translate(5463,2263)\">\n <use xlink:href=\"#E1-MJSZ4-23A4\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2275.4816858443887) scale(1,0.8697872070387873)\">\n <use xlink:href=\"#E1-MJSZ4-23A5\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A6\" x=\"0\" y=\"-3383\"></use>\n</g>\n</g>\n</svg>\n",
    L"$\begin{equation}\left[\begin{array}{cc}2 & -1\\-1 & 2 \\\end{array}\right]\end{equation}$" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"11.47ex\" height=\"6.176ex\" style=\"vertical-align: -2.505ex;\" viewBox=\"0 -1580.7 4938.5 2659.1\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">Start 2 By 2 Matrix 1st Row 1st Column 2 2nd Column negative 1 2nd Row 1st Column negative 1 2nd Column 2 EndMatrix</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5B\" d=\"M118 -250V750H255V710H158V-210H255V-250H118Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-2212\" d=\"M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-31\" d=\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5D\" d=\"M22 710V750H159V-250H22V-210H119V710H22Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ3-5B\" d=\"M247 -949V1450H516V1388H309V-887H516V-949H247Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ3-5D\" d=\"M11 1388V1450H280V-949H11V-887H218V1388H11Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n <use xlink:href=\"#E1-MJSZ3-5B\"></use>\n<g transform=\"translate(695,0)\">\n<g transform=\"translate(-11,0)\">\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"389\" y=\"650\"></use>\n<g transform=\"translate(0,-750)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n</g>\n<g transform=\"translate(2268,0)\">\n<g transform=\"translate(0,650)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"389\" y=\"-750\"></use>\n</g>\n</g>\n <use xlink:href=\"#E1-MJSZ3-5D\" x=\"4410\" y=\"-1\"></use>\n</g>\n</svg>\n",
    L"$\begin{equation}\left[\begin{array}{ccc} 2 & -1 & 0 \\ -1 & 2 & -1 \\ 0 & -1 & 2 \\\end{array}\right]\end{equation}$" =>
        "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"17.409ex\" height=\"9.176ex\" style=\"vertical-align: -4.005ex;\" viewBox=\"0 -2226.5 7495.5 3950.7\" role=\"img\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" aria-labelledby=\"MathJax-SVG-1-Title\">\n<title id=\"MathJax-SVG-1-Title\">Start 3 By 3 Matrix 1st Row 1st Column 2 2nd Column negative 1 3rd Column 0 2nd Row 1st Column negative 1 2nd Column 2 3rd Column negative 1 3rd Row 1st Column 0 2nd Column negative 1 3rd Column 2 EndMatrix</title>\n<defs aria-hidden=\"true\">\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5B\" d=\"M118 -250V750H255V710H158V-210H255V-250H118Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-32\" d=\"M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-2212\" d=\"M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-31\" d=\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-30\" d=\"M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJMAIN-5D\" d=\"M22 710V750H159V-250H22V-210H119V710H22Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A1\" d=\"M319 -645V1154H666V1070H403V-645H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A3\" d=\"M319 -644V1155H403V-560H666V-644H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A2\" d=\"M319 0V602H403V0H319Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A4\" d=\"M0 1070V1154H347V-645H263V1070H0Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A6\" d=\"M263 -560V1155H347V-644H0V-560H263Z\"></path>\n<path stroke-width=\"1\" id=\"E1-MJSZ4-23A5\" d=\"M263 0V602H347V0H263Z\"></path>\n</defs>\n<g stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" transform=\"matrix(1 0 0 -1 0 0)\" aria-hidden=\"true\">\n<g transform=\"translate(0,2150)\">\n <use xlink:href=\"#E1-MJSZ4-23A1\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2048.5066225165565) scale(1,0.49337748344370863)\">\n <use xlink:href=\"#E1-MJSZ4-23A2\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A3\" x=\"0\" y=\"-3155\"></use>\n</g>\n<g transform=\"translate(834,0)\">\n<g transform=\"translate(-11,0)\">\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"389\" y=\"1350\"></use>\n<g transform=\"translate(0,-50)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-30\" x=\"389\" y=\"-1450\"></use>\n</g>\n<g transform=\"translate(2268,0)\">\n<g transform=\"translate(0,1350)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"389\" y=\"-50\"></use>\n<g transform=\"translate(0,-1450)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n</g>\n<g transform=\"translate(4547,0)\">\n <use xlink:href=\"#E1-MJMAIN-30\" x=\"389\" y=\"1350\"></use>\n<g transform=\"translate(0,-50)\">\n <use xlink:href=\"#E1-MJMAIN-2212\" x=\"0\" y=\"0\"></use>\n <use xlink:href=\"#E1-MJMAIN-31\" x=\"778\" y=\"0\"></use>\n</g>\n <use xlink:href=\"#E1-MJMAIN-32\" x=\"389\" y=\"-1450\"></use>\n</g>\n</g>\n<g transform=\"translate(6828,2150)\">\n <use xlink:href=\"#E1-MJSZ4-23A4\" x=\"0\" y=\"-1155\"></use>\n<g transform=\"translate(0,-2048.5066225165565) scale(1,0.49337748344370863)\">\n <use xlink:href=\"#E1-MJSZ4-23A5\"></use>\n</g>\n <use xlink:href=\"#E1-MJSZ4-23A6\" x=\"0\" y=\"-3155\"></use>\n</g>\n</g>\n</svg>\n",
)


text:
import Base: show

abstract type AbstractDependency; end
struct InlineBuildDependency <: AbstractDependency
    script::String
end
struct RemoteBuildDependency <: AbstractDependency
    url::String
    script::Union{String, Nothing}
end

"""
    WizardState

Building large dependencies can take a lot of time. This state object captures
all relevant state of this function. It can be passed back to the function to
resume where we left off. This can aid debugging when code changes are
necessary.  It also holds all necessary metadata such as input/output streams.
"""
mutable struct WizardState
    step::Symbol
    ins::IO
    outs::IO
    global_git_cfg::LibGit2.GitConfig
    # Filled in by step 1
    platforms::Union{Nothing, Vector{P}} where {P <: Platform}
    # Filled in by step 2
    workspace::Union{Nothing, String}
    source_urls::Union{Nothing, Vector{String}}
    source_files::Union{Nothing, Vector{String}}
    source_hashes::Union{Nothing, Vector{String}}
    dependencies::Vector{AbstractDependency}
    # Filled in by step 3
    history::Union{Nothing, String}
    dependency_files::Union{Nothing, Set{String}}
    files::Union{Nothing, Vector{String}}
    file_kinds::Union{Nothing, Vector{Symbol}}
    file_varnames::Union{Nothing, Vector{Symbol}}
    # Filled in by step 5c
    failed_platforms::Set{Any}
    # Used to keep track of which platforms we already visited
    visited_platforms::Set{Any}
    # Used to keep track of which platforms we have shown to work
    # with the current script. This gets reset if the script is edited.
    validated_platforms::Set{Any}
    # Filled in by step 7
    name::Union{Nothing, String}
    version::Union{Nothing, VersionNumber}
    github_api::GitHub.GitHubAPI
    travis_endpoint::String
end

const DEFAULT_TRAVIS_ENDPOINT = "https://api.travis-ci.org/"
function WizardState()
    WizardState(
        :step1,
        stdin,
        stdout,
        LibGit2.GitConfig(),
        nothing,
        nothing,
        nothing,
        nothing,
        nothing,
        Vector{AbstractDependency}(),
        nothing,
        nothing,
        nothing,
        nothing,
        nothing,
        Set{Any}(),
        Set{Any}(),
        Set{Any}(),
        nothing,
        nothing,
        GitHub.DEFAULT_API,
        DEFAULT_TRAVIS_ENDPOINT
    )
end

function show(io::IO, x::WizardState)
    print(io, "WizardState [$(x.step)]")
end


text:
"""
loadSnapshot
Usage: It loads a netcdf snapshot file and a config JSON file that is used in Env.
       If `timestamp` is provided, the function will check if it matches the
       timestamp recorded in the netcdf file.
"""
function loadSnapshot(
    filename   :: AbstractString,   # Field
    timestamp  :: Union{AbstractCFDateTime, Nothing} = nothing;
    overwrite_config :: Union{Dict, Nothing} = nothing,
)

    writeLog("Reading files: {:s}", filename)

    snapshot = JLD2.load(filename)
    if timestamp != nothing

        timestamp_str = Dates.format(timestamp, "yyyy-mm-dd HH:MM:SS")

        if timestamp_str != snapshot["timestamp"]
            throw(ErrorException(format(
                "The provided timestamp is {:s}, but the netcdf file timestamp is {:s}",
                timestamp_str,
                snapshot["timestamp"],
            )))
        end
    end

    cfg = snapshot["ev_config"]

    writeLog("### Loaded config ###")
    println(cfg)

    if overwrite_config != nothing
        writeLog("### Overwriting config ###")
        for (k, v) in overwrite_config
            if haskey(cfg, k)
                if cfg[k] != v
                    writeLog("{:s} is overwritten: {:s} => {:s}", k,  string(cfg[k]), string(v))
                end
            else
                writeLog("{:s} is added: {:s}", k,  string(v))
            end

            cfg[k] = v
        end
    end

    ev = Env(cfg; verbose=true)
    mb = ModelBlock(ev; init_core = false)

    writeLog("### Loading field from snapshot to current model ###")
    loaded_fi = snapshot["fi"]
    for fieldname in fieldnames(Field)

        var = getfield(mb.fi, fieldname)
        loaded_var = getfield(loaded_fi, fieldname)

        if typeof(var) <: Array
            var.= loaded_var
            writeLog("Field loaded: {:s}", string(fieldname))
        else
            writeLog("Field {:s} is not raw array. Skip it.", string(fieldname))
        end
    end

    mb.fi.sv = getSugarView(mb.ev, mb.fi)

    return mb
end

"""
takeSnapshot

Usage: It output netcdf file that is a copy of variables in the given DataTable
       It also converts a config Dict into JSON text file
"""
function takeSnapshot(
    timestamp     :: AbstractCFDateTime,
    mb            :: EMOM.ModelBlock,
    filename      :: AbstractString,   # Field
    missing_value :: Float64=1e20,
)

    JLD2.save(filename, "fi", mb.fi, "ev_config", mb.ev.config, "timestamp", timestamp)

end

max_stars_repo_name: meteorologytoday/IOM

max_issues_repo_name: meteorologytoday/IOM

max_forks_repo_name: meteorologytoday/IOM


text:
###
# This file contains BLAS/BandedMatrix overrides for operators
# that depend on the structure of BandedMatrix
####

# default copy is to loop through
# override this for most operators.
function default_bandedmatrix(S::Operator)
    l,u = bandwidth(S,1),bandwidth(S,2)
    Y=BandedMatrix(eltype(S),size(S,1),size(S,2),l,u)

    for j=1:size(S,2),k=colrange(Y,j)
        @inbounds Y.data[k-j+u+1,j]=S[k,j]
    end

    Y
end

# default copy is to loop through
# override this for most operators.
function default_raggedmatrix(S::Operator)
    data=Array(eltype(S),0)
    cols=Array(Int,size(S,2)+1)
    cols[1]=1
    for j=1:size(S,2)
        cs=colstop(S,j)
        K=cols[j]-1
        cols[j+1]=cs+cols[j]
        resize!(data,cols[j+1]-1)

        for k=1:cs
            data[K+k]=S[k,j]
        end
    end

    RaggedMatrix(data,cols,size(S,1))
end

# The diagonal of the operator may not be the diagonal of the sub
# banded matrix, so the following calculates the row of the
# Banded matrix corresponding to the diagonal of the original operator

diagindrow(S,kr,jr) =
    bandwidth(S,2)+first(jr)-first(kr)+1

diagindrow(S::SubOperator) =
    diagindrow(S,parentindexes(S)[1],parentindexes(S)[2])

#####
# Conversions
#####

function Base.convert{T,DD}(::Type{BandedMatrix},
                        S::SubOperator{T,ConcreteConversion{Chebyshev{DD},Ultraspherical{Int,DD},T},
                                       Tuple{UnitRange{Int},UnitRange{Int}}})
    # we can assume order is 1
    ret=bzeros(S)
    kr,jr=parentindexes(S)

    dat=ret.data
    dg1=diagindrow(S)
    dg3=dg1-2

    @assert 1 ≤ dg1 ≤ size(dat,1)
    @assert 1 ≤ dg3 ≤ size(dat,1)

    @simd for j=1:size(dat,2)
        @inbounds dat[dg1,j]=0.5
        @inbounds dat[dg3,j]=-0.5
    end

    if 1 in kr && 1 in jr
        dat[dg1,1]=1.0
    end

    ret
end

function Base.convert{T,LT,DD}(::Type{BandedMatrix},S::SubOperator{T,ConcreteConversion{Ultraspherical{LT,DD},Ultraspherical{LT,DD},T},
                                                                              Tuple{UnitRange{Int},UnitRange{Int}}})
    # we can assume order is
    λ = order(rangespace(parent(S)))
    ret=bzeros(S)

    kr,jr=parentindexes(S)
    dat=ret.data

    shft = first(jr)-1

    dg1=diagindrow(S)
    dg3=dg1-2

    c=λ-one(T)  # this supports big types
    @simd for j=1:size(dat,2)
        @inbounds dat[dg1,j]=c/(j+shft - 2 + λ)
    end

    @simd for j=max(1,3-shft):size(dat,2)
        @inbounds dat[dg3,j]=-c/(j+shft - 2 + λ)
    end

    ret
end

#####
# Derivatives
#####

function Base.convert{T,K,DD}(::Type{BandedMatrix},S::SubOperator{T,ConcreteDerivative{Chebyshev{DD},K,T},
                                                                Tuple{UnitRange{Int},UnitRange{Int}}})
    D=parent(S)
    m=D.order
    d=domain(D)

    ret=bzeros(S)
    u=bandwidth(ret,2)

    kr,jr=parentindexes(S)
    dat=ret.data

    shft = first(jr)-1

    dg=diagindrow(S)-m   # mth superdiagonal

    C=(.5pochhammer(one(T),m-1)*(4./(d.b-d.a)).^m)::T
    @simd for j=max(m+1-shft,1):size(dat,2)
        @inbounds dat[dg,j]=C*(j+shft-one(T))
    end

    ret
end

function Base.convert{T,K,DD,LT}(::Type{BandedMatrix},S::SubOperator{T,ConcreteDerivative{Ultraspherical{LT,DD},K,T},
                                                                Tuple{UnitRange{Int},UnitRange{Int}}})

    λ = order(domainspace(parent(S)))
    D=parent(S)
    m=D.order
    d=domain(D)

    ret=bzeros(S)
    u=bandwidth(ret,2)

    kr,jr=parentindexes(S)
    dat=ret.data

    shft = first(jr)-1

    dg=diagindrow(S)-m   # mth superdiagonal

    C=(pochhammer(one(T)*λ,m)*(4./(d.b-d.a)).^m)::T
    @simd for j=max(m+1-shft,1):size(dat,2)
        @inbounds dat[dg,j]=C
    end

    ret
end

####
# Toeplitz/Hankel
####

# αn,α0,αp give the constant for the negative, diagonal and positive
# entries.  The usual case is 1,2,1
function toeplitz_axpy!(αn,α0,αp,neg,pos,kr,jr,ret)
    dat=ret.data
    m=size(dat,2)

    dg=diagindrow(ret,kr,jr)

    # diagonal
    if dg ≥ 1
        α0p=α0*pos[1]
        @simd for j=1:m
            @inbounds dat[dg,j]+=α0p
        end
    end

    # positive entries
    for k=2:min(length(pos),dg)
        αpp=αp*pos[k]
        @simd for j=1:m
            @inbounds dat[dg-k+1,j]+=αpp
        end
    end

    # negative entries
    for k=1:min(length(neg),size(dat,1)-dg)
        αnn=αn*neg[k]
        @simd for j=1:m
            @inbounds dat[dg+k,j]+=αnn
        end
    end

    ret
end

# this routine is for when we want a symmetric toeplitz
function sym_toeplitz_axpy!(αn,α0,αp,cfs,kr,jr,ret)
    dg=diagindrow(ret,kr,jr)

    dat=ret.data
    m=size(dat,2)
    # diagonal
    if dg ≥ 1
        α0p=α0*cfs[1]
        @simd for j=1:m
            @inbounds dat[dg,j]+=α0p
        end
    end

    # positive entries
    for k=2:min(length(cfs),dg)
        αpp=αp*cfs[k]
        @simd for j=1:m
            @inbounds dat[dg-k+1,j]+=αpp
        end
    end

    # negative entries
    for k=2:min(length(cfs),size(dat,1)-dg+1)
        αnn=αn*cfs[k]
        @simd for j=1:m
            @inbounds dat[dg+k-1,j]+=αnn
        end
    end

    ret
end

toeplitz_axpy!(α,neg,pos,kr,jr,ret) =
    toeplitz_axpy!(α,α,α,neg,pos,kr,jr,ret)

sym_toeplitz_axpy!(α0,αp,cfs,kr,jr,ret) =
    sym_toeplitz_axpy!(αp,α0,αp,cfs,kr,jr,ret)

function hankel_axpy!(α,cfs,kr,jr,ret)
    dat=ret.data

    st=stride(dat,2)-2
    mink=first(kr)+first(jr)-1

    N=length(dat)

    # dg gives the row corresponding to the diagonal of the original operator
    dg=diagindrow(ret,kr,jr)

    # we need the entry where the first entry is written to
    # this is going to be a shift of the diagonal of the true operator
    dg1=dg+first(kr)-first(jr)

    for k=mink:min(length(cfs),size(dat,1)+mink-dg1)
        dk=k-mink+dg1
        nk=k-mink
        αc=α*cfs[k]
        @simd for j=dk:st:min(dk+nk*st,N)
            @inbounds dat[j]+=αc
        end
    end

    ret
end


text:
"""
     build_globalpb!(OPFpbs)

Return a polynomial problem in complex variables with polynomial constraints combining all scenarios contained in `OPFpbs`

# Arguments
- `OPFpbs` : dictionary of scenario (string)

# Output
- `pb_opt` : a polynomial optimization problem

# Example
```
julia > OPFpbs = build_OPFproblems(MatpowerInput, "instances\\matpower\\WB2.m")
julia > pb = build_globalpb!(OPFpbs)
```
"""

function build_globalpb!(OPFpbs)
      constraints = SortedDict{String,SortedDict{String,Constraint}}()
      variables = SortedDict{String,SortedDict{String, Type}}()
      pb_global = Problem()
      pb_global = build_Problem!(OPFpbs, basecase_scenario_name())
      for scenario in setdiff(collect(keys(OPFpbs)), [basecase_scenario_name()])
            pb_scenario = build_Problem!(OPFpbs, scenario)
            constraints[scenario] = pb_scenario.constraints
            variables[scenario] = pb_scenario.variables
      end
      for (scenario, vars) in variables
            for var in vars
                  add_variable!(pb_global, var)
            end
      end
      for (scenario, constraints) in constraints
            for (ctr_name, ctr) in constraints
                  add_constraint!(pb_global, ctr_name, ctr)
            end
      end
      return pb_global
end


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg

name = "zrl"
version = v"1.1.1"

# Collection of sources required to complete build
sources = [
    GitSource("https://github.com/StefanKarpinski/zrl.git", "2ae37960f4c96b61ebb6f217bde1a3ddbe48f8d1"),
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/zrl
if [[ "${target}" == *-mingw* ]]; then
    export CPP_DEFINES="-DIO_NOLOCK"
else
    export CPP_DEFINES="-DIO_UNLOCKED"
fi
make
mkdir -p "${bindir}"
cp zrle "${bindir}/zrle${exeext}"
cp zrld "${bindir}/zrld${exeext}"
"""

platforms = supported_platforms()

# The products that we will ensure are always built
products = [
    ExecutableProduct("zrle", :zrle),
    ExecutableProduct("zrld", :zrld),
]

# Dependencies that must be installed before this package can be built
dependencies = []

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
# Conditionals

for op ∈ (:(==), :(!=), :(<), :(<=), :(>), :(>=) )
    rename = VECTOR_SYMBOLS[op]
    erename = Symbol(:e, rename)
    # rename_mask = Symbol(rename, :_mask)
    @eval begin
        # scalar versions handled in floating_point_arithmetic.jl
        # @inline $rename(s1::ScalarTypes, s2::ScalarTypes) = $op(s1,s2)
        @vectordef $rename function Base.$op(v1, v2) where {W,T}
            llvmwrap_bitmask(Val{$(QuoteNode(op))}(), extract_data(v1), extract_data(v2))
        end
        @vectordef $rename function Base.$op(v1, v2::T) where {W,T}
            $rename(extract_data(v1), v2)
        end
        @vectordef $rename function Base.$op(v1::T, v2) where {W,T}
            $rename(extract_data(v1), v2)
        end
        @evectordef $erename function Base.$op(v1, v2) where {W,T <: FloatingTypes}
            llvmwrap_bitmask_notfast(Val{$(QuoteNode(op))}(), extract_data(v1), extract_data(v2))
        end
    end
end
@inline visfinite(s::ScalarTypes) = isfinite(s)
@inline function visfinite(v1::_Vec{_W,T}) where {_W,T<:FloatingTypes}
    W = _W + 1
    U = uint_type(T)
    em = vbroadcast(Vec{W,U}, exponent_mask(T))
    iv = vreinterpret(Vec{W,U}, v1)
    # evnot_equal(vand(iv, em), em)
    vnot_equal(vand(iv, em), em)
end
@inline visfinite(v1::SVec{W}) where {W} = SVec{W}(visfinite(extract_data(v1)))
@inline Base.isfinite(v1::SVec{W}) where {W} = SVec{W}(visfinite(extract_data(v1)))

@inline visinf(s1::ScalarTypes) = isinf(s1)
@inline visinf(v1::_Vec{W,T}) where {W,T<:FloatingTypes} = evisequal(vabs(v1), vbroadcast(_Vec{W,T},typemax(T)))
@inline visinf(v1::SVec{W}) where {W} = SVec{W}(visinf(extract_data(v1)))
@inline Base.isinf(v1::SVec{W}) where {W} = SVec{W}(visinf(extract_data(v1)))

@inline visnan(s1::ScalarTypes) = isnan(s1)
# @inline visnan(v1::_Vec{W,T}) where {W,T<:FloatingTypes} = evnot_equal(v1, v1)
@inline visnan(v1::_Vec{W,T}) where {W,T<:FloatingTypes} = vnot_equal(v1, v1)
@inline visnan(v1::SVec{W}) where {W} = SVec{W}(visnan(extract_data(v1)))
@inline Base.isnan(v1::SVec{W}) where {W} = SVec{W}(visnan(extract_data(v1)))

@inline vissubnormal(s1::ScalarTypes) = issubnormal(s1)
@inline function vissubnormal(v1::_Vec{_W,T}) where {_W,T<:FloatingTypes}
    W = _W + 1
    U = uint_type(T)
    em = vbroadcast(Vec{W,U}, exponent_mask(T))
    sm = vbroadcast(Vec{W,U}, significand_mask(T))
    iv = vreinterpret(Vec{W,U}, v1)
    vand(evisequal(vand(iv, em), vbroadcast(Vec{W,U}, 0)), evnot_equal(vand(iv, sm), vbroadcast(Vec{W,U}, 0)))
end
@inline vissubnormal(v1::SVec{W}) where {W} = SVec{W}(vissubnormal(extract_data(v1)))
@inline Base.issubnormal(v1::SVec{W}) where {W} = SVec{W}(vissubnormal(extract_data(v1)))

@inline signbit(s1::ScalarTypes) = signbit(s1)
@inline function vsignbit(v1::_Vec{W,T}) where {W,T<:FloatingTypes}
    U = uint_type(T)
    sm = vbroadcast(_Vec{W,U}, sign_mask(T))
    iv = vreinterpret(_Vec{W,U}, v1)
    vnot_equal(vand(iv, sm), vbroadcast(_Vec{W,U}, 0))
end
@inline function vsignbit(v1::SVec{W,T}) where {W,T<:FloatingTypes}
    SVec{W}(vsignbit(extract_data(v1)))
end
@inline function Base.signbit(v1::SVec{W,T}) where {W,T<:FloatingTypes}
    SVec{W}(vsignbit(extract_data(v1)))
end

# @inline vifelse(c::Bool, x, y) = c ? x : y
@inline vifelse(c::Bool, x, y) = ifelse(c, x, y)
@generated function vifelse(v1::_Vec{_W,Bool}, v2::_Vec{_W,T}, v3::_Vec{_W,T}) where {_W,T}
    W = _W + 1
    btyp = llvmtype(Bool)
    vbtyp = "<$W x $btyp>"
    abtyp = "[$W x $btyp]"
    typ = llvmtype(T)
    vtyp = "<$W x $typ>"
    atyp = "[$W x $typ]"
    decls = String[]
    instrs = String[]
    push!(instrs, "%cond = trunc $vbtyp %0 to <$W x i1>")
    if T <: FloatingTypes && Base.libllvm_version >= v"9"
        push!(instrs, "%res = select $(fastflags(T)) <$W x i1> %cond, $vtyp %1, $vtyp %2")
    else
        push!(instrs, "%res = select <$W x i1> %cond, $vtyp %1, $vtyp %2")
    end
    push!(instrs, "ret $vtyp %res")
    quote
        $(Expr(:meta, :inline))
        llvmcall(
            $((join(decls, "\n"), join(instrs, "\n"))),
            Vec{$W,$T},
            Tuple{Vec{$W,Bool}, Vec{$W,T}, Vec{$W,$T}},
            v1, v2, v3
        )
    end
end
@inline function vifelse(
    v1::_Vec{W,Bool}, v2::AbstractSIMDVector{W}, v3::AbstractSIMDVector{W}
) where {W}
    vifelse(extract_data(v1), extract_data(v2), extract_data(v3))
end
@inline function vifelse(
    v1::AbstractStructVec{W,Bool}, v2::AbstractStructVec{W,T}, v3::AbstractStructVec{W,T}
) where {W,T}
    SVec(vifelse(extract_data(v1), extract_data(v2), extract_data(v3)))
end
# @inline function vifelse(v1::VecOrProd{W,Bool},
#         v2::VecOrProd{W,T}, v3::VecOrProd{W,T}) where {W,T}
#     vifelse(extract_data(v1), extract_data(v2), extract_data(v3))
# end
# @inline function Base.ifelse(v1::SVec{W,Bool},
#         v2::SVec{W,T}, v3::SVec{W,T}) where {W,T}
#     SVec(vifelse(extract_data(v1), extract_data(v2), extract_data(v3)))
# end

@generated function vifelse(mask::U, v2::_Vec{_W,T}, v3::_Vec{_W,T}) where {_W,T,U<:Unsigned}
    W = _W + 1
    @assert 8sizeof(U) >= W
    btyp = llvmtype(Bool)
    vbtyp = "<$W x $btyp>"
    abtyp = "[$W x $btyp]"
    typ = llvmtype(T)
    vtyp = "<$W x $typ>"
    atyp = "[$W x $typ]"
    decls = String[]
    instrs = String[]

    mtyp_input = llvmtype(U)
    mtyp_trunc = "i$W"

    if mtyp_input == mtyp_trunc
        push!(instrs, "%cond = bitcast $mtyp_input %0 to <$W x i1>")
    else
        push!(instrs, "%condtrunc = trunc $mtyp_input %0 to $mtyp_trunc")
        push!(instrs, "%cond = bitcast $mtyp_trunc %condtrunc to <$W x i1>")
    end
    # push!(instrs, "%cond = trunc $vbtyp %0 to <$W x i1>")
    if T <: FloatingTypes && Base.libllvm_version >= v"9"
        push!(instrs, "%res = select $(fastflags(T)) <$W x i1> %cond, $vtyp %1, $vtyp %2")
    else
        push!(instrs, "%res = select <$W x i1> %cond, $vtyp %1, $vtyp %2")
    end
    push!(instrs, "ret $vtyp %res")
    quote
        $(Expr(:meta, :inline))
        llvmcall($((join(decls, "\n"), join(instrs, "\n"))),
            Vec{$W,$T},
            Tuple{$U, Vec{$W,$T}, Vec{$W,$T}},
            mask, v2, v3)
    end
end

@vpromote vifelse 3

@inline vifelse(b::Bool, v2::_Vec{W,T}, s::Union{T,Int}) where {W,T} = ifelse(b, extract_data(v2), vbroadcast(_Vec{W,T}, s))
@inline vifelse(b::Bool, v2::AbstractStructVec{W,T}, s::Union{T,Int}) where {W,T} = SVec(ifelse(b, extract_data(v2), vbroadcast(Vec{W,T}, s)))
@inline vifelse(b::Bool, s::Union{T,Int}, v2::_Vec{W,T}) where {W,T} = ifelse(b, vbroadcast(_Vec{W,T}, s), v2)
@inline vifelse(b::Bool, s::Union{T,Int}, v2::AbstractStructVec{W,T}) where {W,T} = SVec(ifelse(b, vbroadcast(Vec{W,T}, s), extract_data(v2)))

@inline vifelse(U::Unsigned, v2::AbstractSIMDVector, v3::AbstractSIMDVector) = SVec(vifelse(U, extract_data(v2), extract_data(v3)))
@inline vifelse(U::Unsigned, v2::_Vec{W,T}, s::Union{T,Int}) where {W,T} = vifelse(U, extract_data(v2), vbroadcast(_Vec{W,T}, s))
@inline vifelse(U::Unsigned, v2::AbstractStructVec{W,T}, s::Union{T,Int}) where {W,T} = SVec(vifelse(U, extract_data(v2), vbroadcast(Vec{W,T}, s)))
@inline vifelse(U::Unsigned, s::Union{T,Int}, v2::_Vec{W,T}) where {W,T} = vifelse(U, vbroadcast(_Vec{W,T}, s), v2)
@inline vifelse(U::Unsigned, s::Union{T,Int}, v2::AbstractStructVec{W,T}) where {W,T} = SVec(vifelse(U, vbroadcast(Vec{W,T}, s), extract_data(v2)))
@inline vifelse(m::Mask{W}, v1::Vec{W}, v2::Vec{W}) where {W} = vifelse(m.u, v1, v2)

@inline function vifelse(f::F, m::AbstractMask{W}, vargs::Vararg{<:Any,N}) where {F<:Function,W,N}
    vifelse(m, f(vargs...), @inbounds(vargs[N]))
end

@vectordef visodd function Base.isodd(v) where {W,T<:Integer}
    visequal(vand(v, one(T)), one(T))
end

# @inline vand(U::Unsigned, vb::Vec{W,Bool}) where {W} = U & vecbool_to_unsigned(vb)
# @inline vand(vb::Vec{W,Bool}, U::Unsigned) where {W} = U & vecbool_to_unsigned(vb)


text:
using DashBootstrapComponents

button_group = dbc_buttongroup(
    [
        dbc_button("First"),
        dbc_button("Second"),
        dbc_dropdownmenu(
            [dbc_dropdownmenuitem("Item 1"), dbc_dropdownmenuitem("Item 2")],
            label = "Dropdown",
            group = true,
        ),
    ],
    vertical = true,
);

max_stars_repo_name: glsdown/dash-bootstrap-components

max_issues_repo_name: glsdown/dash-bootstrap-components

max_forks_repo_name: glsdown/dash-bootstrap-components


text:
if basename(pwd()) == "aoc"
    cd("2017/9")
end

function score(stream::AbstractString)
    iter = Iterators.Stateful(stream)
    level = 0
    total = 0
    garbagemode = false
    garbagetotal = 0
    for c in iter
        if garbagemode
            if c == '!'
                popfirst!(iter)
            elseif c == '>'
                garbagemode = false
            else
                garbagetotal += 1
            end
        else
            if c == '<'
                garbagemode = true
            elseif c == '{'
                level += 1
                total += level
            elseif c == '}'
                level -= 1
            end
        end
    end
    total, garbagetotal
end

@assert score("{}") == (1, 0)
@assert score("{{{}}}") == (6, 0)
@assert score("{{},{}}") == (5, 0)
@assert score("{{{},{},{{}}}}") == (16, 0)
@assert score("{<{},{},{{}}>}") == (1, 10)
@assert score("{<a>,<a>,<a>,<a>}") == (1, 4)
@assert score("{{<a>},{<a>},{<a>},{<a>}}") == (9, 4)
@assert score("{{<!!>},{<!!>},{<!!>},{<!!>}}") == (9, 0)
@assert score("{{<a!>},{<a!>},{<a!>},{<ab>}}") == (3, 17)

score(readline("input.txt"))

max_stars_repo_name: stellartux/advent-of-code

max_issues_repo_name: stellartux/advent-of-code

max_forks_repo_name: stellartux/advent-of-code