text:
    const language_codes = ("cn", "de", "el", "en", "es", "fr", "it", "pt", "ru")

    boolean(;chance_of_getting_true::Int=50)::Bool = rand(1:100) <= chance_of_getting_true

    null_boolean()::Union{Bool,String} = Dict{Int64,Any}( 0=> "none", 1=> true, -1=> false)[rand(-1:1)]

    #md5() = hexdigest("md5", "$(rand())")

    #sha1() = hexdigest("sha1", "$(rand())")

    #sha256() = hexdigest("sha256", "$(rand())")

    country_code()::String = rand(data["faker"]["address"]["country_code"])
    language_code()::String = rand(language_codes)
    locale(items::Tuple=(language_code(),"_",country_code()))::String = reduce(string, items )

    #=uuid4()==#

    function password(; longitud::Int=10, special_caracteres::Bool=true, digitos::Bool=true, upper_case::Bool=true, lower_case::Bool=true)::String
        functions::Tuple = ();

        if special_caracteres==true
            functions = (functions..., random_special_caracteres )
        end

        if digitos==true
            functions = (functions..., random_digit )
        end

        if upper_case==true
            functions = (functions..., random_uppercase_letter)
        end

        if lower_case==true
            functions = (functions..., random_lowercase_letter)
        end

         return join(map( x -> rand(functions)(), 1:longitud),"")

 end


text:
"""
    exportKnapsackResults(problemDescriptor, αs, results)

Saves results of minimum knapsack problem experiments to CSV files and as PDF plots.

# Arguments
- `problemDescriptor::ProblemDescriptor`: implementation of [`ProblemDescriptor`](@ref) for this problem.
- `αs::Array{Integer, 1}`: list of values of α.
- `results::Array{Float64, 1}`: three-dimentional array of results, where first
    dimention specify problem, second dimention specify ratios or times results,
    the third one contain results for each value of α.
"""
function exportKnapsackResults(n, limit, αs, results)
    @assert size(αs, 1) == size(results, 3)

    pyplot()

    n = getProblemSize(problemDescriptor)
    limit = getSaneComputationLimit(problemDescriptor)
    suffix = Dates.format(Dates.now(), "duyyyy@HH_MM")

    df = DataFrame(a = αs, b = results[1, 1, :])
    saveCsv("kn-plot-ratios-rec-$n-$suffix.csv", df, ["α", "ρ(c_0)"])
    drawAndSavePlot("kn-plot-ratios-rec-$n-$suffix.pdf", αs, results[1, 1, :], "α", "average ratio ρ(c₀)", "n = $n")

    df = DataFrame(a = αs, b = results[1, 2, :])
    saveCsv("kn-plot-times-rec-$n-$suffix.csv", df, ["α", "ρ(c_0)"])
    drawAndSavePlot("kn-plot-times-rec-$n-$suffix.pdf", αs, results[1, 2, :], "α", "average time (s)", "n = $n")

    if n ≤ limit
        df = DataFrame(a = αs, ra = results[2, 1, :], rh = results[3, 1, :], rs = results[4, 1, :])
        saveCsv("kn-plot-ratios-adv_rec_sel-$n-$suffix.csv", df, ["α", "ρ_Adv",  "ρ_h",  "ρ_Sel"])
        drawAndSavePlot("kn-plot-ratios-adv_rec_sel-$n-$suffix.pdf", αs, results[2:4, 1, :].', "α", "average ratio ρₖ", [L"\rho_{Adv}" L"\rho_h" L"\rho_{Sel}"])

        df = DataFrame(a = αs, ra = results[2, 2, :], rh = results[3, 2, :], rs = results[4, 2, :])
        saveCsv("kn-plot-times-adv_rec_sel-$n-$suffix.csv", df, ["α", "ρ_Adv",  "ρ_h",  "ρ_Sel", "Eval."])
        drawAndSavePlot("kn-plot-times-adv_rec_sel-$n-$suffix.pdf", αs, results[2:4, 2, :].', "α", "average time (s)", [L"\rho_{Adv}" L"\rho_h" L"\rho_{Sel}"])
    end
end

"""
    exportAssignmentResults(problemDescriptor, αs, results)

Saves results of minimum assignment problem experiments to CSV files and as PDF plots.

# Arguments
- `problemDescriptor::ProblemDescriptor`: implementation of [`ProblemDescriptor`](@ref) for this problem.
- `αs::Array{Integer, 1}`: list of values of α.
- `results::Array{Float64, 1}`: three-dimentional array of results, where first
    dimention specify problem, second dimention specify ratios or times results,
    the third one contain results for each value of α.
"""
function exportAssignmentResults(problemDescriptor, αs, results)
    @assert size(αs, 1) == size(results, 3)

    pyplot()

    m = getProblemSize(problemDescriptor)
    limit = getSaneComputationLimit(problemDescriptor)
    suffix = Dates.format(Dates.now(), "duyyyy@HH_MM")

    df = DataFrame(a = αs, b = results[1, 1, :])
    saveCsv("as-plot-ratios-rec-$m-$suffix.csv", df, ["α", "ρ(c_0)"])
    drawAndSavePlot("as-plot-ratios-rec-$m-$suffix.pdf", αs, results[1, 1, :], "α", "average ratio ρ(c₀)", "m = $m")

    df = DataFrame(a = αs, b = results[1, 2, :])
    saveCsv("as-plot-times-rec-$m-$suffix.csv", df, ["α", "ρ(c_0)"])
    drawAndSavePlot("as-plot-times-rec-$m-$suffix.pdf", αs, results[1, 2, :], "α", "average time (s)", "m = $m")

    if m ≤ limit
        df = DataFrame(a = αs, ra = results[2, 1, :], rh = results[3, 1, :], rs = results[4, 1, :], rl = results[5, 1, :])
        saveCsv("as-plot-ratios-adv_rec_sel-$m-$suffix.csv", df, ["α", "ρ_Adv",  "ρ_h",  "ρ_Sel", "ρ_Lag"])
        drawAndSavePlot("as-plot-ratios-adv_rec_sel-$m-$suffix.pdf", αs, results[2:5, 1, :].', "α", "average ratio ρₖ", [L"\rho_{Adv}" L"\rho_h" L"\rho_{Sel}" L"\rho_{Lag}"])

        df = DataFrame(a = αs, ra = results[2, 2, :], rh = results[3, 2, :], rs = results[4, 2, :], rl = results[5, 2, :])
        saveCsv("as-plot-times-adv_rec_sel-$m-$suffix.csv", df, ["α", "ρ_Adv",  "ρ_h",  "ρ_Sel", "ρ_Lag"])
        drawAndSavePlot("as-plot-times-adv_rec_sel-$m-$suffix.pdf", αs, results[2:5, 2, :].', "α", "average time (s)", [L"\rho_{Adv}" L"\rho_h" L"\rho_{Sel}" L"\rho_{Lag}"])
    end
end

"""
    saveCsv(filename, data, columnNames)

Saves `data` described by `columnNames` to CSV file with name`filename`.

# Examples:
```
julia> using RobRecSolver
julia> Experiments.saveCsv("item_prices.csv", ["milk" 100; "ham" 250], ["item", "price"])
```
The above command will create file `item_prices.csv` with the following content:
```csv
item,price
milk,100
ham,250
```
"""
function saveCsv(filename, data, columnNames)
    df = DataFrame(data)
    CSV.write(filename, df; colnames = columnNames)
end

"""
    drawAndSavePlot(filename, x, ys, xlabel, ylabel, yslabels; linewidth=2, linestyles = [:solid :dash :dashdot :dot :solid], shape = [:diamond :pentagon :star4 :utriangle :square], palette=cgrad([:black, :grey]), annotations = [])

Draws plot and saves it to PDF file with name `filename`. Here `x` is a values of 0X axis,
`ys` is a columns of series, `xlabel` is label of 0X axis, `ylabel` is label of 0Y axis
and `yslabels` is a labels of individual series.

# Examples:
```
julia> using RobRecSolver, Plots
julia> pyplot()
julia> Experiments.drawAndSavePlot("plot.pdf", [0.1, 0.2, 0.3], [21, 15, 12], "α", "average time (s)", "m=100")
```
The above command will draw the plot shown below and save it as `plot.pdf`.
![Example output](assets/plot.png)

The rest of the arguments function uses is self-descriptive and is based on the ones from
the [`Plots.jl`](http://docs.juliaplots.org/latest/) package. Default values of arguments
are adjusted to the needs of the _publication_.
"""
function drawAndSavePlot(filename, x, ys, xlabel, ylabel, yslabels; linewidth=2, linestyles = [:solid :dash :dashdot :dot :solid], shape = [:diamond :pentagon :star4 :utriangle :square], palette=cgrad([:black, :grey]), annotations = [])
    p = plot(x, ys, linewidth=linewidth, xlabel = xlabel, ylabel = ylabel, lab = yslabels, linestyle = linestyles, shape = shape, markersize = 8, palette = palette, annotations = annotations)
    savefig(p, filename) # Default values selected in a way to produce the most readible charts
end

ext: jl


text:
"""
    greenspline(cmd0::String="", arg1=[]; kwargs...)

Reads randomly-spaced (x,y,z) triples and produces a binary grid file of gridded values z(x,y) by solving:

		(1 - T) * L (L (z)) + T * L (z) = 0

Full option list at [`greenspline`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html)

Parameters
----------

- $(GMT.opt_R)
- **I** : **inc** : -- Str or Number --

	*x_inc* [and optionally *y_inc*] is the grid spacing.
    [`-I`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#i)
- **A** : **gradient** : -- Str --		Flags = gradfile+f1|2|3|4|5

	The solution will partly be constrained by surface gradients v = v*n, where v is the
	gradient magnitude and n its unit vector direction.
    [`-A`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#a)
- **C** : **approx** : **approximate** : -- Str or Number --	Flags = [n]value[+ffile]

	Find an approximate surface fit: Solve the linear system for the spline coefficients by
	SVD and eliminate the contribution from all eigenvalues whose ratio to the largest
	eigenvalue is less than value.
    [`-C`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#c)
- **G** : **grid** : -- Str or [] --

	Output grid file name. Note that this is optional and to be used only when saving
    the result directly on disk. Otherwise, just use the G = greenspline(....) form.
    [`-G`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#g)
- **D** : **mode** : -- Number --

	Sets the distance flag that determines how we calculate distances between data points.
    [`-D`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#d)
- **E** : **misfit** : -- Str or [] --		Flags = [misfitfile]

	Evaluate the spline exactly at the input data locations and report statistics of
	the misfit (mean, standard deviation, and rms).
    [`-E`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#e)
- **L** : **leave_trend** : -- Bool or [] --

	Do not remove a linear (1-D) or planer (2-D) trend when -D selects mode 0-3.
    [`-L`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#L)
- **N** : **nodes** : -- Number --			Flags = nodefile

	ASCII file with coordinates of desired output locations x in the first column(s).
    [`-N`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#n)
- **Q** : **dir_derivative** : -- Str --		Flags = az|x/y/z

	Rather than evaluate the surface, take the directional derivative in the az azimuth and
	return the magnitude of this derivative instead.
    [`-Q`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#q)
- **S** : **splines** : -- Str --				Flags = c|t|l|r|p|q[pars]

    Select one of six different splines. The first two are used for 1-D, 2-D, or 3-D Cartesian splines.
    [`-S`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#s)

- **T** : **mask** : -- Str --					Flags = maskgrid

	For 2-D interpolation only. Only evaluate the solution at the nodes in the maskgrid that are
	not equal to NaN.
    [`-T`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#t)
- $(GMT.opt_V)
- **W** : **uncertainties** : -- Str or [] --	Flags = [w]

	Data one-sigma uncertainties are provided in the last column. We then compute weights that
	are inversely proportional to the uncertainties squared.
    [`-W`](http://gmt.soest.hawaii.edu/doc/latest/greenspline.html#w)
- $(GMT.opt_b)
- $(GMT.opt_d)
- $(GMT.opt_e)
- $(GMT.opt_f)
- $(GMT.opt_h)
- $(GMT.opt_i)
- $(GMT.opt_o)
- $(GMT.opt_x)
- $(GMT.opt_swap_xy)
"""
function greenspline(cmd0::String="", arg1=[]; kwargs...)

	length(kwargs) == 0 && return monolitic("greenspline", cmd0, arg1)	# Speedy mode

	d = KW(kwargs)
	cmd, = parse_R("", d)
	cmd = parse_V_params(cmd, d)
	cmd, = parse_bi(cmd, d)
	cmd, = parse_d(cmd, d)
	cmd, = parse_e(cmd, d)
	cmd, = parse_f(cmd, d)
	cmd, = parse_h(cmd, d)
	cmd, = parse_i(cmd, d)
	cmd, = parse_o(cmd, d)
	cmd, = parse_x(cmd, d)
	cmd, = parse_swap_xy(cmd, d)

	cmd = add_opt(cmd, 'A', d, [:A :gradient])
	cmd = add_opt(cmd, 'C', d, [:C :approx :approximate])
	cmd = add_opt(cmd, 'D', d, [:D :mode])
	cmd = add_opt(cmd, 'E', d, [:E :misfit])
	cmd = add_opt(cmd, 'G', d, [:G :grid])
	cmd = add_opt(cmd, 'I', d, [:I :inc])
	cmd = add_opt(cmd, 'L', d, [:L :leave_trend])
	cmd = add_opt(cmd, 'N', d, [:N :nodes])
	cmd = add_opt(cmd, 'Q', d, [:Q :dir_derivative])
	cmd = add_opt(cmd, 'S', d, [:S :splines])
	cmd = add_opt(cmd, 'T', d, [:T :mask])
	cmd = add_opt(cmd, 'W', d, [:W :uncertainties])

	cmd, got_fname, arg1 = find_data(d, cmd0, cmd, 1, arg1)
	return common_grd(d, cmd, got_fname, 1, "greenspline", arg1)		# Finish build cmd and run it
end

# ---------------------------------------------------------------------------------------------------
greenspline(arg1=[], cmd0::String=""; kw...) = greenspline(cmd0, arg1; kw...)


text:
module RulesNormalMeanPrecisionMeanTest

using Test
using ReactiveMP
using Random

import ReactiveMP: @test_rules

@testset "rules:NormalMeanPrecision:mean" begin

    @testset "Belief Propagation: (m_out::PointMass, m_τ::PointMass)" begin

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (m_out = PointMass(-1.0), m_τ = PointMass(2.0)), output = NormalMeanPrecision(-1.0, 2.0)),
            (input = (m_out = PointMass(1.0), m_τ = PointMass(2.0)),  output = NormalMeanPrecision(1.0, 2.0)),
            (input = (m_out = PointMass(2.0), m_τ = PointMass(1.0)),  output = NormalMeanPrecision(2.0, 1.0))
        ]

    end

    @testset "Belief Propagation: (m_out::UnivariateNormalDistributionsFamily, m_τ::PointMass)" begin

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (m_out = NormalMeanPrecision(0.0, 1.0),  m_τ = PointMass(2.0)), output = NormalMeanPrecision(0.0, 2.0 / 3.0)),
            (input = (m_out = NormalMeanPrecision(-1.0, 1.0), m_τ = PointMass(1.5)), output = NormalMeanPrecision(-1.0, 0.6)),
            (input = (m_out = NormalMeanPrecision(2.0, 0.5),  m_τ = PointMass(1.0)), output = NormalMeanPrecision(2.0, 1.0 / 3.0)),
        ]

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (m_out = NormalMeanVariance(0.0, 1.0),  m_τ = PointMass(2.0)), output = NormalMeanPrecision(0.0, 2.0 / 3.0)),
            (input = (m_out = NormalMeanVariance(-1.0, 1.0), m_τ = PointMass(1.5)), output = NormalMeanPrecision(-1.0, 0.6)),
            (input = (m_out = NormalMeanVariance(2.0, 0.5),  m_τ = PointMass(1.0)), output = NormalMeanPrecision(2.0, 2.0 / 3.0)),
        ]

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (m_out = NormalWeightedMeanPrecision(0.0, 1.0),  m_τ = PointMass(2.0)), output = NormalMeanPrecision(0.0, 2.0 / 3.0)),
            (input = (m_out = NormalWeightedMeanPrecision(-1.0, 1.0), m_τ = PointMass(1.5)), output = NormalMeanPrecision(-1.0, 0.6)),
            (input = (m_out = NormalWeightedMeanPrecision(2.0, 0.5),  m_τ = PointMass(1.0)), output = NormalMeanPrecision(4.0, 1.0 / 3.0)),
        ]

    end

    @testset "Variational: (q_out::Any, q_τ::Any)" begin

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (q_out = PointMass(-1.0), q_τ = PointMass(2.0)), output = NormalMeanPrecision(-1.0, 2.0)),
            (input = (q_out = PointMass(1.0), q_τ = PointMass(2.0)),  output = NormalMeanPrecision(1.0, 2.0)),
            (input = (q_out = PointMass(2.0), q_τ = PointMass(1.0)),  output = NormalMeanPrecision(2.0, 1.0)),
        ]

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (q_out = NormalMeanVariance(-1.0, 2.0), q_τ = PointMass(2.0)), output = NormalMeanPrecision(-1.0, 2.0)),
            (input = (q_out = NormalMeanPrecision(1.0, 4.0), q_τ = PointMass(3.0)),  output = NormalMeanPrecision(1.0, 3.0)),
            (input = (q_out = NormalWeightedMeanPrecision(2.0, 4.0), q_τ = PointMass(1.0)),  output = NormalMeanPrecision(0.5, 1.0))
        ]

        @test_rules [ with_float_conversions = true ] NormalMeanPrecision(:μ, Marginalisation) [
            (input = (q_out = PointMass(-1.0), q_τ = Gamma(2.0, 1.0)), output = NormalMeanPrecision(-1.0, 2.0)),
            (input = (q_out = PointMass(1.0), q_τ = Gamma(4.0, 2.0)),  output = NormalMeanPrecision(1.0, 8.0)),
            (input = (q_out = PointMass(2.0), q_τ = Gamma(4.0, 6.0)),  output = NormalMeanPrecision(2.0, 24.0))
        ]

    end

end

end


text:
### A Pluto.jl notebook ###
# v0.18.1

using Markdown
using InteractiveUtils

# ╔═╡ 0427af5a-a14a-11ec-3cd4-a92623da9071
md"# 3월 10일 통계전산"

# ╔═╡ 423bcae3-9d56-4b75-91a8-9e6411eb2df3

# ╔═╡ 03d197c0-534a-4a84-ae44-570885cadee7
md"# 변수"

# ╔═╡ f1205397-2f27-49c6-ae4f-f92c0122bd5a
x=1.0

# ╔═╡ 2accb946-ae01-4b53-926e-6df942bb938c
md"# 수학적 기호와 같은 변수 사용하는 방법"

# ╔═╡ 5816bab8-0a50-4e3c-b985-78555470c0f4
α =3 # \alpha + tap 버튼을 누르면 된다.

# ╔═╡ bec73ac1-3746-47de-953c-2a9a2664520d
β = 4 #\beta + tap  버튼을 누른다.

# ╔═╡ d42e8e3e-87c0-427b-814c-b5ae7fa2f052
β̂= 4.0 #\beta + tap 을 하고 다시 \hat 을 입력후 tap을 누른다.

# ╔═╡ eb4820ca-4d1d-46ba-833c-bec6bc7fb82b
ℯ #\euler

# ╔═╡ c6dd1d4c-e391-4554-b86c-bb888f0747cd
π # \pi + tap

# ╔═╡ 1bdef2de-7054-4b99-8e3e-eea8d7457970
☼ = 3.0 #\sun + tap

# ╔═╡ 51c83c70-0ba3-4932-ad91-0547d73dcfe7
xₜ= 2.0 # x\_t 을 누르고 tap을 누른다.

# ╔═╡ 0a039a94-71da-407f-ba58-a10f1b2c2dac
♂ ="male " #\male + tap

# ╔═╡ b4dae09e-328e-4a0d-bdb6-232f2cd6db39
♀ = "female" #\female + tap

# ╔═╡ 9164a3e6-0a77-437a-b6f4-05b7a5ffa19e
정찬우= "Jeongchanwoo"

# ╔═╡ 12d2b2f2-ad54-4e9d-9b54-6300c4b42621
md"# 자료형 "

# ╔═╡ 27bc2e69-48ea-4360-9e1e-70be0d119538
123 # int형

# ╔═╡ 933a9ddb-7bdb-42d0-9627-026e836ec54c
123.123 # float 형

# ╔═╡ bbd673ee-f456-48da-8f84-11f27b783c93
[123]  #vectro 형

# ╔═╡ d6005975-5910-4424-b9f4-3fb74796414e

md"   ### 자료형을 보려면? "

# ╔═╡ 44c831d5-c933-44c0-9678-5f74d8eb2da0
typeof(123)

# ╔═╡ efc18e7f-dcee-41e5-baa3-41639512fcb9
typeof(123.123)

# ╔═╡ a52684e4-00d6-4983-bbe1-e6dd60151cda
typeof([123])

# ╔═╡ 78bd7b91-1e39-4965-96e1-ea07f7d4bcd3
md" # Inf 와 NaN"

# ╔═╡ 275a1b8a-c117-49df-a763-bf6204368e01
Inf # 무한대

# ╔═╡ cb64a3ad-2127-4b1c-843f-55a6ab124855
typeof(Inf)

# ╔═╡ 97d834f2-179b-45b9-a699-745dfb8abc21
Inf + Inf

# ╔═╡ 5932b481-11e0-43ab-90aa-088c142bbdab
Inf- Inf

# ╔═╡ 561045ad-2441-4fa5-abd3-4b935fb36e61
typeof(NaN)

# ╔═╡ 902b81f7-499f-428c-918c-0a7d019f65fe
1/Inf #상수 / 무한대 = 0

# ╔═╡ 1fe8d1bb-51f0-4e6a-a011-e468576d3b28
1/NaN

# ╔═╡ c16768cb-b8b8-4dc8-981b-f107882d6b3b
md"""
### 문자열
"""

# ╔═╡ 06e12df0-f871-4b64-af54-8ac5a28354bb
str1 = "apple"

# ╔═╡ 5986ef94-dfe1-41e8-bd50-28724dc6194c
str1

# ╔═╡ 327aea28-64b7-4f56-9203-f56117bd7ffc
str1[1] #파이썬과 다르게 1번쪠 문자가 1라고 잘 표시 됨.

# ╔═╡ 46c5401a-5e94-4dff-9447-8f8fd79a8e0a
length(str1) #str1의 길이

# ╔═╡ c6307db0-5b7e-4b25-bbdf-8fee7d90e95e
str1[2], str1[1:2]

# ╔═╡ bb71aaea-d562-44b2-867f-0fc0846b50a8
md" #### 튜플 언팩킹이 자동으로 됨. "

# ╔═╡ 91c7b5a5-0b79-4ada-ab48-885d0ff672c2
str2= "pie"

# ╔═╡ 0d931a18-8d7f-4337-a4e1-4ab355a10623
md" ## 문자를 합치는 방법."

# ╔═╡ c919df46-909c-41dd-b2d0-45ffe0415fd9
str1+ str2 #에러가 난다#

# ╔═╡ 66549bb4-e139-43a8-9a80-2c114083380c
string(str1,str2) #1번째 방법#

# ╔═╡ 58bc9bc8-45f6-4651-8395-53120e15a684
string(str1, "cake") # 2번째 방법

# ╔═╡ 59e8784e-d82c-465a-9cbe-ec570eb59f93
"10+20=$(10+20)" # 문자열 끼워넣기

# ╔═╡ cc5cca1f-f811-4e9f-b3a4-7017d9acdedc
begin
	word1= "chanwoo"
	word2= "studying"
	word3= "Julia"
end

# ╔═╡ afa02578-8245-4d8c-8cf7-b5006b44920a
"$word1 is $word2 $word3" #이렇게 쓸 수 도 있다.

# ╔═╡ 2129ce29-63ed-454b-b027-91c0721f4d9b
md" #### 튜플"

# ╔═╡ cd1a27e6-3a62-4ef0-9d3c-e809f7469e65
(1,2,3)

# ╔═╡ 983713b5-8e69-456c-9ba3-81eab3ebf3ca
a= 1,2,3 #괄호는 생략가능하다.

# ╔═╡ b9228d03-ce07-4291-af84-8a0a5f9de752
a[1]

# ╔═╡ 927ab9dc-b4e5-4d42-b9ac-2818d6faecf6
a[1:2]

# ╔═╡ 12218860-fe82-46e0-9959-eebf59ce256c
a[1]=10 # 튜플은 a의 원소의 값을 변경할 수 없다.

# ╔═╡ a44a15e2-035b-4e5a-8b13-247369185076
a1,a2,a3= 1,2,3
#(a1,a3,a3)=(1,2,3)
#a1=1,a2=2,a3=3)

# ╔═╡ 8b25f311-a5c5-486d-83fd-ac91130631f7
md" ### Array"

# ╔═╡ 73ffaa05-4bcb-4e74-9d28-b8550c12c7e1
b=[123,456,789]

# ╔═╡ 9593651a-6ef6-48b0-973f-1a03b4eb1969

# ╔═╡ 4f0bb494-65c0-4478-b025-2b6f9dfedebf
b[1]

# ╔═╡ d64de24b-2e51-4eca-b6d2-bc52b5256b6c
b[1:2]

# ╔═╡ cda2779d-cb61-4506-a3bb-9c07878d9ab1
b[1]=100 #array는 값을 변경할 수 있다.

# ╔═╡ f3e885d3-8dc6-4162-ab59-7551fffd7785
md" ### 브로드 캐스팅"

# ╔═╡ f7cf6562-5a19-4f52-b217-b3ff926e134a
b+1 #b의 각 원소에 1을 더하고 싶지만 에러가 난다.

# ╔═╡ 0adee737-9ed5-4775-9169-9332981ea296
broadcast(+,b,1) #방법1

# ╔═╡ 2c94b35b-565e-4c2f-855d-2eba10711bf0
b.+1 #방법2

# ╔═╡ b28f76ff-b5c5-4491-b7a8-460e1de523a9

# ╔═╡ 8d800aa5-ed06-4e3f-a091-940be267d68d
b1 = [1,2,3] # 3 x 1 의 행렬이라 생각하면 된다,

# ╔═╡ cd951867-49a7-4c09-b305-afe3227730f2
typeof(b1)

# ╔═╡ c5ed5758-7f38-4b18-8b2a-4a298d56930d
b2= [1 2 3] # 1 x 3 행렬이라 생각하면 된다.

# ╔═╡ ffebff79-cd16-453c-9378-64c77519b8ab
typeof(b2)

# ╔═╡ c7eac59f-6921-4aaf-b418-4e0a97cb5de4
md" #b1과 b2의 타입은 다르다."

# ╔═╡ 9299a3cd-1134-4917-b5b8-8f814a57e455
md" #b1과 b2를 브로드캐스팅 해보자 "

# ╔═╡ e9718246-1fbb-4542-aecd-b895f6c4f130
#b1=[1,1,1,
#    2,2,2, #이렇게 생각하면 된다. 3 x 1 행렬이 3x 3 으로 확장
#	 3,3,3]

# ╔═╡ 44860e08-529c-4893-ad3d-1430884259a6
#b2= [1, 2, 3,
#  	  1, 2, 3, #이렇게 생각하면 된다. 1 x 3 행렬이 3x 3 으로 확장
#	  1, 2, 3]

# ╔═╡ 3adcdebe-0b98-490a-9b1c-859e0708dd17
b1.+b2

# ╔═╡ c4b41fc9-6579-455f-87b8-9f601e389f30
b1.*b2

# ╔═╡ 6b57f51a-e796-441b-807d-241cb9d7e6e6
md" ### 브로드 캐스팅의 응용"

# ╔═╡ d6e06dea-ef8a-481e-a76c-dd0ba5c57205
[1,2]==[1,2]

# ╔═╡ ace8d7f2-e9ee-4502-bf44-488482302aaf
[1,2]==[1,3]

# ╔═╡ b76682a1-0c80-4582-9e2b-5fbfe7782504
[2,2]==[1,2]

# ╔═╡ b990ea59-86ee-47c3-9da0-edbf0ce73f00
[1,2] .==[1,2] #각 원소가 같는 지 확인할 수 있다.

# ╔═╡ f38550d2-77d5-42fd-8f9a-15a1a1b029bb
[1,2].==[1,3]

# ╔═╡ 89539414-67c1-4ccd-9438-3e3e41b42ada
[2,2].==[1,2]

# ╔═╡ 82046e59-da76-43a5-a82b-5c696007442d

# ╔═╡ 2cf67fbf-a984-4313-9ffb-81bd7481f34a
md" ### 난수로 벡터를 선헌하는 방법"

# ╔═╡ 15bbb300-f2c3-4caa-9aae-ce1bbf7bde35
randn(4) #정규분포

# ╔═╡ 08365a07-d633-44c1-8586-08a0e7ce7f23
 rand(4) #유니폼 분포

# ╔═╡ 2102e38a-9e6d-4b71-a003-346b31091a08
rand([1,2,3,4],3) #rand의 두번쨰 기능 : sample= 무작위로 3번의 복원추출

# ╔═╡ 6ab29751-989a-4ca8-bc8f-bacc1fe3be74

md" ### 리스트 컴프리헨션"

# ╔═╡ 3c97feeb-cf05-48a0-b765-cc779a026f57
√1, √2,√3, √4

# ╔═╡ 756bd1e6-dce4-4bca-a4c2-89421ba069f4
[√i for i in [1,2,3,4]] #다른 표햔

# ╔═╡ 13fe15d6-6ee2-4503-8254-e08fcdb9f7a9
md"""
$\{\sqrt{1},\sqrt{2},\sqrt{3},\sqrt{4} \}= \{\sqrt{i}: i=1,2,3,4 \}$"""

# ╔═╡ 0f5fbd3c-4fdc-4d46-981a-ba52fec072e0

# ╔═╡ 71bdb5fb-f977-4ecc-b43f-bebce77d3b52

# ╔═╡ fcc4ecf8-e4e8-4dd7-88e4-6c28a8f31933

# ╔═╡ 543e5600-d94c-4ef2-8f27-38ab3b011061

# ╔═╡ 37ec1f97-c1c0-4f62-842c-07f986edb34e

# ╔═╡ b2e7435d-d408-441c-a30e-5cef3314cade

# ╔═╡ f8da476f-1e73-42d1-960a-9f5f3b71c237

# ╔═╡ b2a5908f-7532-44fd-add2-28c55b38414d

# ╔═╡ 28baeb0d-fc34-4e12-bb64-65bc7175249e

# ╔═╡ 2668701d-d940-4aab-8c0d-c727f2d28c20

# ╔═╡ d8d2579b-fcec-4177-977b-aee79731b826

# ╔═╡ a0755748-8636-4a05-b633-5b6203c71342

# ╔═╡ 07f9ddc6-fe18-4fb8-9040-3bb2525ceb91

# ╔═╡ cefc23a5-27aa-4ae3-a961-8c8977690015

# ╔═╡ 55bc2c22-6cda-4cdb-b2d3-bddcc3e397d4

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

julia_version = "1.7.2"
manifest_format = "2.0"

[deps]
"""

# ╔═╡ Cell order:
# ╠═0427af5a-a14a-11ec-3cd4-a92623da9071
# ╠═423bcae3-9d56-4b75-91a8-9e6411eb2df3
# ╠═03d197c0-534a-4a84-ae44-570885cadee7
# ╠═f1205397-2f27-49c6-ae4f-f92c0122bd5a
# ╠═2accb946-ae01-4b53-926e-6df942bb938c
# ╠═5816bab8-0a50-4e3c-b985-78555470c0f4
# ╠═bec73ac1-3746-47de-953c-2a9a2664520d
# ╠═d42e8e3e-87c0-427b-814c-b5ae7fa2f052
# ╠═eb4820ca-4d1d-46ba-833c-bec6bc7fb82b
# ╠═c6dd1d4c-e391-4554-b86c-bb888f0747cd
# ╠═1bdef2de-7054-4b99-8e3e-eea8d7457970
# ╠═51c83c70-0ba3-4932-ad91-0547d73dcfe7
# ╠═0a039a94-71da-407f-ba58-a10f1b2c2dac
# ╠═b4dae09e-328e-4a0d-bdb6-232f2cd6db39
# ╠═9164a3e6-0a77-437a-b6f4-05b7a5ffa19e
# ╠═12d2b2f2-ad54-4e9d-9b54-6300c4b42621
# ╠═27bc2e69-48ea-4360-9e1e-70be0d119538
# ╠═933a9ddb-7bdb-42d0-9627-026e836ec54c
# ╠═bbd673ee-f456-48da-8f84-11f27b783c93
# ╠═d6005975-5910-4424-b9f4-3fb74796414e
# ╠═44c831d5-c933-44c0-9678-5f74d8eb2da0
# ╠═efc18e7f-dcee-41e5-baa3-41639512fcb9
# ╠═a52684e4-00d6-4983-bbe1-e6dd60151cda
# ╠═78bd7b91-1e39-4965-96e1-ea07f7d4bcd3
# ╠═275a1b8a-c117-49df-a763-bf6204368e01
# ╠═cb64a3ad-2127-4b1c-843f-55a6ab124855
# ╠═97d834f2-179b-45b9-a699-745dfb8abc21
# ╠═5932b481-11e0-43ab-90aa-088c142bbdab
# ╠═561045ad-2441-4fa5-abd3-4b935fb36e61
# ╠═902b81f7-499f-428c-918c-0a7d019f65fe
# ╠═1fe8d1bb-51f0-4e6a-a011-e468576d3b28
# ╠═c16768cb-b8b8-4dc8-981b-f107882d6b3b
# ╠═06e12df0-f871-4b64-af54-8ac5a28354bb
# ╠═5986ef94-dfe1-41e8-bd50-28724dc6194c
# ╠═327aea28-64b7-4f56-9203-f56117bd7ffc
# ╠═46c5401a-5e94-4dff-9447-8f8fd79a8e0a
# ╠═c6307db0-5b7e-4b25-bbdf-8fee7d90e95e
# ╠═bb71aaea-d562-44b2-867f-0fc0846b50a8
# ╠═91c7b5a5-0b79-4ada-ab48-885d0ff672c2
# ╠═0d931a18-8d7f-4337-a4e1-4ab355a10623
# ╠═c919df46-909c-41dd-b2d0-45ffe0415fd9
# ╠═66549bb4-e139-43a8-9a80-2c114083380c
# ╠═58bc9bc8-45f6-4651-8395-53120e15a684
# ╠═59e8784e-d82c-465a-9cbe-ec570eb59f93
# ╠═cc5cca1f-f811-4e9f-b3a4-7017d9acdedc
# ╠═afa02578-8245-4d8c-8cf7-b5006b44920a
# ╠═2129ce29-63ed-454b-b027-91c0721f4d9b
# ╠═cd1a27e6-3a62-4ef0-9d3c-e809f7469e65
# ╠═983713b5-8e69-456c-9ba3-81eab3ebf3ca
# ╠═b9228d03-ce07-4291-af84-8a0a5f9de752
# ╠═927ab9dc-b4e5-4d42-b9ac-2818d6faecf6
# ╠═12218860-fe82-46e0-9959-eebf59ce256c
# ╠═a44a15e2-035b-4e5a-8b13-247369185076
# ╠═8b25f311-a5c5-486d-83fd-ac91130631f7
# ╠═73ffaa05-4bcb-4e74-9d28-b8550c12c7e1
# ╠═9593651a-6ef6-48b0-973f-1a03b4eb1969
# ╠═4f0bb494-65c0-4478-b025-2b6f9dfedebf
# ╠═d64de24b-2e51-4eca-b6d2-bc52b5256b6c
# ╠═cda2779d-cb61-4506-a3bb-9c07878d9ab1
# ╠═f3e885d3-8dc6-4162-ab59-7551fffd7785
# ╠═f7cf6562-5a19-4f52-b217-b3ff926e134a
# ╠═0adee737-9ed5-4775-9169-9332981ea296
# ╠═2c94b35b-565e-4c2f-855d-2eba10711bf0
# ╠═b28f76ff-b5c5-4491-b7a8-460e1de523a9
# ╠═8d800aa5-ed06-4e3f-a091-940be267d68d
# ╠═cd951867-49a7-4c09-b305-afe3227730f2
# ╠═c5ed5758-7f38-4b18-8b2a-4a298d56930d
# ╠═ffebff79-cd16-453c-9378-64c77519b8ab
# ╠═c7eac59f-6921-4aaf-b418-4e0a97cb5de4
# ╠═9299a3cd-1134-4917-b5b8-8f814a57e455
# ╠═e9718246-1fbb-4542-aecd-b895f6c4f130
# ╠═44860e08-529c-4893-ad3d-1430884259a6
# ╠═3adcdebe-0b98-490a-9b1c-859e0708dd17
# ╠═c4b41fc9-6579-455f-87b8-9f601e389f30
# ╠═6b57f51a-e796-441b-807d-241cb9d7e6e6
# ╠═d6e06dea-ef8a-481e-a76c-dd0ba5c57205
# ╠═ace8d7f2-e9ee-4502-bf44-488482302aaf
# ╠═b76682a1-0c80-4582-9e2b-5fbfe7782504
# ╠═b990ea59-86ee-47c3-9da0-edbf0ce73f00
# ╠═f38550d2-77d5-42fd-8f9a-15a1a1b029bb
# ╠═89539414-67c1-4ccd-9438-3e3e41b42ada
# ╠═82046e59-da76-43a5-a82b-5c696007442d
# ╠═2cf67fbf-a984-4313-9ffb-81bd7481f34a
# ╠═15bbb300-f2c3-4caa-9aae-ce1bbf7bde35
# ╠═08365a07-d633-44c1-8586-08a0e7ce7f23
# ╠═2102e38a-9e6d-4b71-a003-346b31091a08
# ╠═6ab29751-989a-4ca8-bc8f-bacc1fe3be74
# ╠═3c97feeb-cf05-48a0-b765-cc779a026f57
# ╠═756bd1e6-dce4-4bca-a4c2-89421ba069f4
# ╠═13fe15d6-6ee2-4503-8254-e08fcdb9f7a9
# ╠═0f5fbd3c-4fdc-4d46-981a-ba52fec072e0
# ╠═71bdb5fb-f977-4ecc-b43f-bebce77d3b52
# ╠═fcc4ecf8-e4e8-4dd7-88e4-6c28a8f31933
# ╠═543e5600-d94c-4ef2-8f27-38ab3b011061
# ╠═37ec1f97-c1c0-4f62-842c-07f986edb34e
# ╠═b2e7435d-d408-441c-a30e-5cef3314cade
# ╠═f8da476f-1e73-42d1-960a-9f5f3b71c237
# ╠═b2a5908f-7532-44fd-add2-28c55b38414d
# ╠═28baeb0d-fc34-4e12-bb64-65bc7175249e
# ╠═2668701d-d940-4aab-8c0d-c727f2d28c20
# ╠═d8d2579b-fcec-4177-977b-aee79731b826
# ╠═a0755748-8636-4a05-b633-5b6203c71342
# ╠═07f9ddc6-fe18-4fb8-9040-3bb2525ceb91
# ╠═cefc23a5-27aa-4ae3-a961-8c8977690015
# ╠═55bc2c22-6cda-4cdb-b2d3-bddcc3e397d4
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
const TO = TrajectoryOptimization

# Car escape
T = Float64

# options
max_con_viol = 1.0e-8
verbose=false

opts_al = AugmentedLagrangianSolverOptions{T}(verbose=verbose,
    cost_tolerance=1.0e-6,
    cost_tolerance_intermediate=1.0e-2,
    constraint_tolerance=max_con_viol,
    penalty_scaling=50.,
    penalty_initial=10.)

opts_pn = ProjectedNewtonSolverOptions{T}(verbose=verbose,
    feasibility_tolerance=max_con_viol,
    solve_type=:feasible)

opts_altro = ALTROSolverOptions{T}(verbose=verbose,
    opts_al=opts_al,
    R_inf=1.0e-1,
    resolve_feasible_problem=false,
    opts_pn=opts_pn,
    projected_newton=true,
    projected_newton_tolerance=1.0e-3);

opts_ipopt = DIRCOLSolverOptions{T}(verbose=verbose,
    nlp=Ipopt.Optimizer(),
    feasibility_tolerance=max_con_viol)

prob = copy(Problems.car_escape_static)

# ALTRO
altro = ALTROSolver(prob, opts_altro, infeasible=true)
Z0 = copy(get_trajectory(altro))
initial_trajectory!(altro, Z0)
solve!(altro)
max_violation(altro)

@btime begin
    initial_trajectory!($altro, $Z0)
    solve!($altro)
end
max_violation(altro)

# Ipopt
prob_ipopt = copy(Problems.car_escape_static)
prob_ipopt = TO.change_integration(prob_ipopt, HermiteSimpson)
ipopt = DIRCOLSolver(prob_ipopt, opts_ipopt)
ipopt.opts.verbose = true
solve!(ipopt)
max_violation(ipopt)
Problems.plot_escape(states(ipopt))

ipopt.opts.verbose = false
@btime solve!($ipopt)


text:
"""
    StaticStorages.BucketKey()

Generate a unique bucket key.

Typically, this should be called at top-level scope and assigned to a constant
for later use.

```julia
const MY_BUCKET_KEY = StaticStorages.BucketKey()
```
"""
StaticStorages.BucketKey

"""
    StaticStorages.put!(__module__, [bucket::BucketKey,] value) -> key

Put `value` in a static storage.  This is typically done during macro expansion
time.
"""
StaticStorages.put!

"""
    StaticStorages.get([bucketkey::BucketKey,] key::StorageKey) -> value or nothing

Retrieve the object inserted by `StaticStorages.put!`.
"""
StaticStorages.get

"""
    StaticStorages.getbucket(bucketkey::BucketKey) -> dict or nothing
"""
StaticStorages.getbucket

StorageKey() = StorageKey(uuid4())

BucketKey() = BucketKey(uuid4())
const DEFAULT_BUCKET_KEY = BucketKey()

const StorageDict = Dict{StorageKey,Any}
const BucketDict = Dict{BucketKey,StorageDict}
const BUCKETS = BucketDict()

const EMPTY_DICT = Dict{Union{},Union{}}()

StaticStorages.get(bucketkey::BucketKey, key::StorageKey) =
    get(get(BUCKETS, bucketkey, EMPTY_DICT), key, nothing)
StaticStorages.get(key::StorageKey) = StaticStorages.get(DEFAULT_BUCKET_KEY, key)

StaticStorages.getbucket(bucketkey::BucketKey) = get(BUCKETS, bucketkey, nothing)

#=
StaticStorages.getbucket!(bucketkey::BucketKey) = get!(StorageDict, BUCKETS, bucketkey)
=#

const LOCAL_BUCKETS_NAME = gensym("LOCAL_BUCKETS_NAME")

StaticStorages.put!(__module__::Module, value) =
    StaticStorages.put!(__module__, DEFAULT_BUCKET_KEY, value)

function StaticStorages.put!(__module__::Module, bucketkey::BucketKey, value)
    key = StorageKey()
    get!(StorageDict, BUCKETS, bucketkey)[key] = value

    # Precompilation support
    local_buckets = try
        getfield(__module__, LOCAL_BUCKETS_NAME)
    catch
        nothing
    end
    if local_buckets === nothing
        local_buckets = BucketDict()
        @gensym StaticStoragesInit
        expr = quote
            module $StaticStoragesInit
            __init__() = merge!(merge!, $(@__MODULE__).BUCKETS, LOCAL_BUCKETS)
            const LOCAL_BUCKETS = $(QuoteNode(local_buckets))
            end
            const $LOCAL_BUCKETS_NAME = $StaticStoragesInit.LOCAL_BUCKETS
        end
        Base.eval(__module__, Expr(:toplevel, expr.args...))
    end
    get!(StorageDict, local_buckets, bucketkey)[key] = value

    return key
end


text:
function findMatch(pattern::Regex, myString::AbstractString)
   if match(pattern, myString) == nothing
       return("")
   else
       return(myString)
   end
end
findMatch(pattern::Regex, mySymbol::Symbol) = findMatch(pattern, string(mySymbol))

function queryColumns(pattern, col_names; logic = "", level = "outer")
    matches = Symbol[]
    if logic == "anti"
        op = ==
    else
        op = !=
    end

    #Return the whole string (outer), the actual match(inner), or the nth element of a split?
    if level == "inner"
        extract(pattern, s) = symbol(match(pattern, s).match)
    #nth half
    elseif typeof(level) == Int
        extract(pattern, s) = split(s, pattern)[level]
    #Outer
    else
        extract(pattern, s) = symbol(s)
    end

    for s in col_names
        s = string(s)
        if op(findMatch(pattern, s), "")
            push!(matches, extract(pattern, s))
        end
    end
    return(matches)
end
queryColumns(pattern, table::DataFrame; logic = "", level = "outer") = queryColumns(pattern, String[string(name) for name in names(table)]; logic = logic, level = level)

#Convert a string of booleans to an array of 0 and 1
function convertPattern(a::AbstractString)
    pat = []
    for c in a
        if c == '0'
            pat = [pat; [0]]
        elseif c == '1'
            pat = [pat; [1]]
        end
    end
    return(pat)
end
#Convert an array of 0 and 1 to a string of booleans
function convertPattern(a::DataArray{Bool})
    pat = ""
    for c in a
        pat = pat * string(convert(Int, c))
    end
    return(pat)
end

max_stars_repo_name: el-uhu/PPSIM

max_issues_repo_name: el-uhu/PPSIM

max_forks_repo_name: el-uhu/PPSIM


text:
"""
QQQQ
"""
mutable struct PHDist
    α::Adjoint{Float64, Vector{Float64}}
    T::Matrix{Float64}
end

"""
QQQQ
"""
mutable struct MAPHDist
    α::Adjoint{Float64, Vector{Float64}}
    T::Matrix{Float64}
    T0::Matrix{Float64}

    function MAPHDist(α::Adjoint{Float64, Vector{Float64}}, T::Matrix{Float64},T0::Matrix{Float64})
        @assert size(T)[1] == size(T0)[1]

        ## todo clean..
        #@assert sum(sum(T, dims=2) + sum(T0, dims=2)) ≈ 0.0
        @assert isapprox(sum(sum(T, dims=2) + sum(T0, dims=2)),0,atol = 10e-12)
        return new(α, T, T0)
    end
end

"""
QQQQ
"""
mutable struct MAPHSufficientStats
    B::Vector{Float64} #initial starts
    Z::Vector{Float64} #time spent
    N::Matrix{Float64} #transitions
    MAPHSufficientStats(B::Vector{Float64}, Z::Vector{Float64}, N::Matrix{Float64}) = new(B,Z,N)
    function MAPHSufficientStats(maph::MAPHDist)
        p, q = model_size(maph)
        new(zeros(p), zeros(p), zeros(p,p+q))
    end
end

"""
QQQQ
"""
SingleObs = NamedTuple{(:y, :a), Tuple{Float64, Int64}}

"""
QQQQ
"""
MAPHObsData = Vector{SingleObs}

+(ss1::MAPHSufficientStats, ss2::MAPHSufficientStats) = MAPHSufficientStats(ss1.B+ss2.B, ss1.Z+ss2.Z, ss1.N+ ss2.N)
/(ss::MAPHSufficientStats,n::Real) = MAPHSufficientStats(ss.B/n,ss.Z/n,ss.N/n)
/(ss1::MAPHSufficientStats,ss2::MAPHSufficientStats) = MAPHSufficientStats(ss1.B ./ ss2.B, ss1.Z ./  ss2.Z, ss1.N ./  ss2.N)
-(ss1::MAPHSufficientStats, ss2::MAPHSufficientStats) = MAPHSufficientStats(ss1.B-ss2.B, ss1.Z-ss2.Z, ss1.N - ss2.N)

"""
QQQQ - put doc string
"""
model_size(ph::PHDist) = length(ph.α)

"""
QQQQ - put doc string
"""
model_size(maph::MAPHDist) = (p = size(maph.T,1), q = size(maph.T0,2)) #transient is p and abosrbing is q

"""
QQQQ
"""
function non_degenerate_maph(maph::MAPHDist)::MAPHDist
    valid_states = abs.(diag(maph.T)) .> sqrt(eps())
    return MAPHDist(maph.α[valid_states]', maph.T[valid_states,valid_states], maph.T0[valid_states,:])
end


text:
# Autogenerated wrapper script for BLST_jll for aarch64-linux-musl
export libblst

JLLWrappers.@generate_wrapper_header("BLST")
JLLWrappers.@declare_library_product(libblst, "libblst.so")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libblst,
        "lib/libblst.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()