text:
############################### Semi-discrete Build functions ###########################

function add_device_ct(bus::PSY.Bus, capacity::Float64, name::String)
    return PSY.ThermalStandard(
        name,
        true,
        true,
        bus,
        capacity * 0.4,
        0.0496,
        0.223606797749979,
        PSY.PrimeMovers.CT,
        PSY.ThermalFuels.OTHER,
        (min = capacity * 0.4, max = capacity),
        (min = 0.0, max = 0.1),
        (up = 0.03, down = 0.03),
        (up = 1.0, down = 1.0),
        PSY.ThreePartCost(
            PSY.VariableCost([
                (782.911, 0.4 * capacity),
                (1174.36, 0.6 * capacity),
                (1566.65, 0.8 * capacity),
                (1995.198, capacity),
            ],),
            302.864,
            51.747,
            0.0,
        ),
        0.24,
    )
end

function make_semi_discrete_ct(sys::PSY.System, capacity::Float64)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:CT]
    remainder_cap = capacity_per_bus % unit_capacity[:CT]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_ct(bus, unit_capacity[:CT], "new_CT_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_ct(bus, remainder_cap, "new_CT_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function add_device_cc(bus::PSY.Bus, capacity::Float64, name::String)
    return PSY.ThermalStandard(
        name,
        true,
        true,
        bus,
        capacity * 0.47,
        0.6843,
        3.853894134508627,
        PSY.PrimeMovers.CC,
        PSY.ThermalFuels.NATURAL_GAS,
        (min = capacity * 0.47, max = capacity),
        (min = -0.25, max = 1.5),
        (up = 0.0414, down = 0.0414),
        (up = 8.0, down = 4.5),
        PSY.ThreePartCost(
            PSY.VariableCost([
                (3838.085535700569, 0.47 * capacity),
                (5230.332257410263, 0.65 * capacity),
                (6941.875221559945, 0.82 * capacity),
                (8943.709296295801, capacity),
            ],),
            957.5389017269495,
            28046.681022000004,
            0.0,
        ),
        4.14,
    )
end

function make_semi_discrete_cc(sys::PSY.System, capacity::Float64)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:CC]
    remainder_cap = capacity_per_bus % unit_capacity[:CC]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_cc(bus, unit_capacity[:CC], "new_CC_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_cc(bus, remainder_cap, "new_CC_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function add_device_st(bus::PSY.Bus, capacity::Float64, name::String)
    return PSY.ThermalStandard(
        name,
        true,
        true,
        bus,
        capacity * 0.39,
        0.0014,
        0.8170,
        PSY.PrimeMovers.ST,
        PSY.ThermalFuels.NATURAL_GAS,
        (min = capacity * 0.39, max = capacity),
        (min = -0.25, max = 0.3),
        (up = 0.02, down = 0.02),
        (up = 8.0, down = 4.0),
        PSY.ThreePartCost(
            PSY.VariableCost([
                (553.9076596522913, 0.39 * capacity),
                (837.0160191548608, 0.58 * capacity),
                (1156.6555351904503, 0.79 * capacity),
                (1501.9025167638265, capacity),
            ],),
            415.84297278910844,
            11172.014351999998,
            0.0,
        ),
        0.89,
    )
end

function make_semi_discrete_st(sys::PSY.System, capacity::Float64)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:ST]
    remainder_cap = capacity_per_bus % unit_capacity[:ST]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_st(bus, unit_capacity[:ST], "new_ST_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_st(bus, remainder_cap, "new_ST_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function add_device_renewable(
    base_device::PSY.Device,
    bus::PSY.Bus,
    capacity::Float64,
    name::String,
)
    device = deepcopy(base_device)
    IS.clear_forecasts!(device)
    set_device_name!(device, name)
    set_uuid!(device)
    device.rating = capacity
    PSY.set_bus!(device, bus)
    IS.copy_forecasts!(base_device, device)
    IS.set_time_series_storage!(device, nothing)
    services = PSY.get_services(device)
    while !isempty(services)
        PSY._remove_service!(device, services[1])
    end
    return device
end

function make_semi_discrete_wt(
    sys::PSY.System,
    capacity::Float64,
    base_device = "309_WIND_1",
)
    devices = []
    base_device = PSY.get_components_by_name(PSY.RenewableGen, sys, base_device)[1]
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:WT]
    remainder_cap = capacity_per_bus % unit_capacity[:WT]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_renewable(
                base_device,
                bus,
                unit_capacity[:WT],
                "new_WIND_$(ix)_$(bus.name)",
            )
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_renewable(
                base_device,
                bus,
                remainder_cap,
                "new_WIND_rem_$(bus.name)",
            )
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_pv(
    sys::PSY.System,
    capacity::Float64,
    base_device = "324_PV_3",
)
    devices = []
    base_device = PSY.get_components_by_name(PSY.RenewableGen, sys, base_device)[1]
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:PVe]
    remainder_cap = capacity_per_bus % unit_capacity[:PVe]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_renewable(
                base_device,
                bus,
                unit_capacity[:PVe],
                "new_PVe_$(ix)_$(bus.name)",
            )
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_renewable(
                base_device,
                bus,
                remainder_cap,
                "new_PVe_rem_$(bus.name)",
            )
            push!(devices, device)
        end
    end
    return devices
end

function add_device_bat(bus::PSY.Bus, capacity::Float64, name::String)
    return PSY.GenericBattery(
        name,
        true,
        bus,
        PSY.PrimeMovers.BA,
        0.0,
        (min = 0.0, max = capacity),
        capacity,
        0.0,
        (min = 0.0, max = capacity),
        (min = 0.0, max = capacity),
        (in = 0.9, out = 0.9),
        0.0,
        (min = 0.0, max = 0.0),
        0.0,
    )
end

function make_semi_discrete_bat(sys::PSY.System, capacity::Float64)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)
    no_complete_devices = capacity_per_bus ÷ unit_capacity[:BA]
    remainder_cap = capacity_per_bus % unit_capacity[:BA]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_bat(bus, unit_capacity[:BA], "new_BA_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_bat(bus, remainder_cap, "new_BA_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function add_device_hy(
    base_device::PSY.Device,
    bus::PSY.Bus,
    capacity::Float64,
    name::String,
)
    device = deepcopy(base_device)
    IS.clear_forecasts!(device)
    set_device_name!(device, name)
    set_uuid!(device)
    device.rating = capacity
    device.basepower = capacity
    device.activepower = capacity
    device.activepowerlimits = (min= 0., max=capacity)
    PSY.set_bus!(device, bus)
    IS.copy_forecasts!(base_device, device)
    IS.set_time_series_storage!(device, nothing)
    services = PSY.get_services(device)
    while !isempty(services)
        PSY._remove_service!(device, services[1])
    end
    return device
end

function make_semi_discrete_hy(sys::PSY.System, capacity::Float64, base_device = "222_HYDRO_3",)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    base_device = PSY.get_components_by_name(PSY.HydroGen, sys, base_device)[1]
    capacity == 0 ? (return devices) : nothing
    capacity_per_bus = capacity / length(buses)

    no_complete_devices = capacity_per_bus ÷ unit_capacity[:HY]
    remainder_cap = capacity_per_bus % unit_capacity[:HY]
    for bus in buses
        for ix in no_complete_devices
            device = add_device_hy(base_device, bus, unit_capacity[:HY], "new_HY_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_hy(base_device, bus, remainder_cap, "new_HY_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function _make_device_semi_discrete(
    sys::PSY.System,
    mover::PSY.PrimeMovers.PrimeMover,
    capacity::Float64,
)
    if mover == PSY.PrimeMovers.CT
        return make_semi_discrete_ct(sys, capacity)
    elseif mover == PSY.PrimeMovers.CC
        return make_semi_discrete_cc(sys, capacity)
    elseif mover == PSY.PrimeMovers.ST
        return make_semi_discrete_st(sys, capacity)
    elseif mover == PSY.PrimeMovers.WT
        return make_semi_discrete_wt(sys, capacity)
    elseif mover == PSY.PrimeMovers.PVe
        return make_semi_discrete_pv(sys, capacity)
    elseif mover == PSY.PrimeMovers.BA
        return make_semi_discrete_bat(sys, capacity)
    elseif mover == PSY.PrimeMovers.HY
        return make_semi_discrete_hy(sys, capacity)
    end
end

function add_copies!(
    sys::PSY.System,
    device_list::Dict{PSY.PrimeMovers.PrimeMover, Float64},
    semi_discrete::Bool,
)
    for (type, cap) in device_list
        if semi_discrete
            devices = _make_device_semi_discrete(sys, type, cap)
        else
            devices = _make_device(sys, type, cap)
        end
        isnothing(devices) ? continue : nothing
        services = PSY.get_components(PSY.Service, sys)
        for new_device in devices
            PSY.add_component!(sys, new_device)
            for service in services
                if check_service(service, new_device)
                    PSY.add_service!(new_device, service)
                end
            end
        end
    end
    return
end

############################### Regional semi-discrete device build functions ###########################

function make_semi_discrete_regional_ct(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:CT]
        remainder_cap = capacity_per_bus % unit_capacity[:CT]
        for ix in no_complete_devices
            device = add_device_ct(bus, unit_capacity[:CT], "new_CT_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_ct(bus, remainder_cap, "new_CT_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_cc(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:CC]
        remainder_cap = capacity_per_bus % unit_capacity[:CC]
        for ix in no_complete_devices
            device = add_device_cc(bus, unit_capacity[:CC], "new_CC_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_cc(bus, remainder_cap, "new_CC_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_st(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:ST]
        remainder_cap = capacity_per_bus % unit_capacity[:ST]
        for ix in no_complete_devices
            device = add_device_st(bus, unit_capacity[:ST], "new_ST_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_st(bus, remainder_cap, "new_ST_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_wt(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
    base_device = "309_WIND_1",
)
    devices = []
    base_device = PSY.get_components_by_name(PSY.RenewableGen, sys, base_device)[1]
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:WT]
        remainder_cap = capacity_per_bus % unit_capacity[:WT]
        for ix in no_complete_devices
            device = add_device_renewable(
                base_device,
                bus,
                unit_capacity[:WT],
                "new_WIND_$(ix)_$(bus.name)",
            )
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_renewable(
                base_device,
                bus,
                remainder_cap,
                "new_WIND_rem_$(bus.name)",
            )
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_pv(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
    base_device = "324_PV_3",
)
    devices = []
    base_device = PSY.get_components_by_name(PSY.RenewableGen, sys, base_device)[1]
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:PVe]
        remainder_cap = capacity_per_bus % unit_capacity[:PVe]
        for ix in no_complete_devices
            device = add_device_renewable(
                base_device,
                bus,
                unit_capacity[:PVe],
                "new_PVe_$(ix)_$(bus.name)",
            )
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_renewable(
                base_device,
                bus,
                remainder_cap,
                "new_PVe_rem_$(bus.name)",
            )
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_bat(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:BA]
        remainder_cap = capacity_per_bus % unit_capacity[:BA]
        for ix in no_complete_devices
            device = add_device_bat(bus, unit_capacity[:BA], "new_BA_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_bat(bus, remainder_cap, "new_BA_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function make_semi_discrete_regional_hy(
    sys::PSY.System,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
    base_device = "222_HYDRO_3",
)
    devices = []
    buses = PSY.get_components(PSY.Bus, sys)
    _device = PSY.get_components_by_name(PSY.HydroGen, sys, base_device)[1]
    capacity == 0 ? (return devices) : nothing
    for (ix, bus) in enumerate(buses)
        capacity_per_bus = capacity * split_ratio[ix]
        no_complete_devices = capacity_per_bus ÷ unit_capacity[:HY]
        remainder_cap = capacity_per_bus % unit_capacity[:HY]
        for ix in no_complete_devices
            device = add_device_hy(_device, bus, unit_capacity[:HY], "new_HY_$(ix)_$(bus.name)")
            push!(devices, device)
        end
        if remainder_cap != 0
            device = add_device_hy(_device, bus, remainder_cap, "new_HY_rem_$(bus.name)")
            push!(devices, device)
        end
    end
    return devices
end

function _make_device_semi_discrete_regional(
    sys::PSY.System,
    mover::PSY.PrimeMovers.PrimeMover,
    capacity::Float64,
    split_ratio::NTuple{3, Float64},
)
    if mover == PSY.PrimeMovers.CT
        return make_semi_discrete_regional_ct(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.CC
        return make_semi_discrete_regional_cc(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.ST
        return make_semi_discrete_regional_st(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.WT
        return make_semi_discrete_regional_wt(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.PVe
        return make_semi_discrete_regional_pv(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.BA
        return make_semi_discrete_regional_bat(sys, capacity, split_ratio)
    elseif mover == PSY.PrimeMovers.HY
        return make_semi_discrete_regional_hy(sys, capacity, split_ratio)
    end
end

function ContinuousRegionalBuildContainer()
    return Dict{PSY.PrimeMovers.PrimeMover, Tuple{Float64, NTuple{3, Float64}}}(
        PSY.PrimeMovers.CT => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.CC => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.ST => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.WT => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.PVe => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.BA => (0.0, (0.,0.,0.)),
        PSY.PrimeMovers.HY => (0.0, (0.,0.,0.)),
    )
end

function update_continuous_reg_samples(config, mapping, data)
    for pm in keys(mapping)
        ix, split_ratio = mapping[pm]
        config[pm] = (data[ix], split_ratio)
    end
    return config
end

function continuous_sampling_regional(
    distribution_dict::Dict{PSY.PrimeMovers.PrimeMover, Distributions.Distribution},
    count::Int,
)
    samples = Dict()
    distribustion_array = []
    distribution_idx = Dict()
    for (ix, (pm, dist)) in enumerate(distribution_dict)
        push!(distribustion_array, dist)
        r = rand(3)
        r = r / sum(r)
        r = Tuple(r)
        push!(distribution_idx, pm => (ix, r))
    end
    sample_set = Distributions.Product([distribustion_array...])
    samples_distribution = rand(sample_set, count)
    for ix in 1:count
        _temp = ContinuousRegionalBuildContainer()
        _temp =
            update_continuous_reg_samples(_temp, distribution_idx, samples_distribution[:, ix])
        samples[ix] = _temp
    end
    return samples
end

function add_copies!(
    sys::PSY.System,
    device_list::Dict{PSY.PrimeMovers.PrimeMover, Tuple{Float64, NTuple{3, Float64}}},
)
    for (type, (cap, split_ratio)) in device_list
        devices = _make_device_semi_discrete_regional(sys, type, cap, split_ratio)
        isnothing(devices) ? continue : nothing
        services = PSY.get_components(PSY.Service, sys)
        for new_device in devices
            PSY.add_component!(sys, new_device)
            for service in services
                if check_service(service, new_device)
                    PSY.add_service!(new_device, service)
                end
            end
        end
    end
    return
end


text:
# Autogenerated wrapper script for GSL_jll for x86_64-apple-darwin
export gsl_histogram, gsl_randist, libgsl, libgslcblas

JLLWrappers.@generate_wrapper_header("GSL")
JLLWrappers.@declare_executable_product(gsl_histogram)
JLLWrappers.@declare_executable_product(gsl_randist)
JLLWrappers.@declare_library_product(libgsl, "@rpath/libgsl.25.dylib")
JLLWrappers.@declare_library_product(libgslcblas, "@rpath/libgslcblas.0.dylib")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_executable_product(
        gsl_histogram,
        "bin/gsl-histogram",
    )

    JLLWrappers.@init_executable_product(
        gsl_randist,
        "bin/gsl-randist",
    )

    JLLWrappers.@init_library_product(
        libgsl,
        "lib/libgsl.25.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libgslcblas,
        "lib/libgslcblas.0.dylib",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()

ext: jl


text:
load("kernels.jl")

# code = quote
#     A = B.*C + D[j,i]
#     dest[2i, 2j] = A
#     dest2[...] = 2A
# end
code = :(let
    A = B.*C + D
    X = A + C
    dest1[...] = A
    dest2[...] = X
end)

rawdag = tangle(code.args[1])

kernelargs = collect_arguments(rawdag)
gendag = general_transform(rawdag)

max_stars_repo_name: toivoh/julia-kernels

max_issues_repo_name: toivoh/julia-kernels

max_forks_repo_name: toivoh/julia-kernels


text:
using FreqTables
using Test
using NamedArrays

x = repeat(["a", "b", "c", "d"], outer=[100]);
# Values not in order to test discrepancy between index and levels with CategoricalArray
y = repeat(["D", "C", "A", "B"], inner=[10], outer=[10]);

tab = @inferred freqtable(x)
@test tab == [100, 100, 100, 100]
@test names(tab) == [["a", "b", "c", "d"]]
@test @inferred prop(tab) == [0.25, 0.25, 0.25, 0.25]
tab = @inferred freqtable(y)
@test tab == [100, 100, 100, 100]
@test names(tab) == [["A", "B", "C", "D"]]
tab = @inferred freqtable(x, y)
@test tab == [30 20 20 30;
              30 20 20 30;
              20 30 30 20;
              20 30 30 20]
@test names(tab) == [["a", "b", "c", "d"], ["A", "B", "C", "D"]]

pt = @inferred prop(tab)
@test pt == [0.075  0.05  0.05 0.075;
             0.075  0.05  0.05 0.075;
              0.05 0.075 0.075  0.05;
              0.05 0.075 0.075  0.05]
pt = @inferred prop(tab, margins=2)
@test pt == [0.3 0.2 0.2 0.3;
             0.3 0.2 0.2 0.3;
             0.2 0.3 0.3 0.2;
             0.2 0.3 0.3 0.2]
pt = @inferred prop(tab, margins=1)
@test pt == [0.3 0.2 0.2 0.3;
             0.3 0.2 0.2 0.3;
             0.2 0.3 0.3 0.2;
             0.2 0.3 0.3 0.2]
pt = @inferred prop(tab, margins=(1, 2))
@test pt == [1.0 1.0 1.0 1.0;
             1.0 1.0 1.0 1.0;
             1.0 1.0 1.0 1.0;
             1.0 1.0 1.0 1.0]

tbl = @inferred prop(rand(5, 5, 5, 5), margins=(1, 2))
sumtbl = sum(tbl, dims=(3,4))
@test all(x -> x ≈ 1.0, sumtbl)

@test_throws MethodError prop()
@test_throws MethodError prop(("a","b"))
@test_throws MethodError prop((1, 2))
@test_throws MethodError prop([1,2,3], "a")
@test_throws MethodError prop([1,2,3], 1, 2)
@test_throws ArgumentError prop([1,2,3], margins=2)
@test_throws ArgumentError prop([1,2,3], margins=0)

tab = @inferred freqtable(x, y,
                          subset=1:20,
                          weights=repeat([1, .5], outer=[10]))
@test tab == [2.0 3.0
              1.0 1.5
              3.0 2.0
              1.5 1.0]
@test names(tab) == [["a", "b", "c", "d"], ["C", "D"]]
pt = @inferred prop(tab)
@test pt == [4 6; 2 3; 6 4; 3 2] / 30.0
pt = @inferred prop(tab, margins=2)
@test pt == [8  12; 4   6; 12  8; 6   4] / 30.0
pt = @inferred prop(tab, margins=1)
@test pt == [6 9; 6 9; 9 6; 9 6] / 15.0
pt = @inferred prop(tab, margins=(1, 2))
@test pt == [1.0 1.0; 1.0 1.0; 1.0 1.0; 1.0 1.0]

using CategoricalArrays
cx = CategoricalArray(x)
cy = CategoricalArray(y)

tab = @inferred freqtable(cx)
@test tab == [100, 100, 100, 100]
@test names(tab) == [["a", "b", "c", "d"]]
tab = @inferred freqtable(cy)
@test tab == [100, 100, 100, 100]
@test names(tab) == [["A", "B", "C", "D"]]
tab = @inferred freqtable(cx, cy)
@test tab == [30 20 20 30;
              30 20 20 30;
              20 30 30 20;
              20 30 30 20]
@test names(tab) == [["a", "b", "c", "d"], ["A", "B", "C", "D"]]

tab = @inferred freqtable(cx, cy,
                          subset=1:20,
                          weights=repeat([1, .5], outer=[10]))
@test tab == [0.0 0.0 2.0 3.0
              0.0 0.0 1.0 1.5
              0.0 0.0 3.0 2.0
              0.0 0.0 1.5 1.0]
@test names(tab) == [["a", "b", "c", "d"], ["A", "B", "C", "D"]]

const ≅ = isequal
mx = Array{Union{String, Missing}}(x)
my = Array{Union{String, Missing}}(y)
mx[1] = missing
my[[1, 10, 20, 400]] .= missing

mcx = categorical(mx)
mcy = categorical(my)

tab = @inferred freqtable(mx)
tabc = @inferred freqtable(mcx)
@test tab == tabc == [99, 100, 100, 100, 1]
@test names(tab) ≅ names(tabc) ≅ [["a", "b", "c", "d", missing]]
tab = @inferred freqtable(my)
tabc = @inferred freqtable(mcy)
@test tab == tabc == [100, 99, 99, 98, 4]
@test names(tab) ≅ names(tabc) ≅ [["A", "B", "C", "D", missing]]
tab = @inferred freqtable(mx, my)
tabc = @inferred freqtable(mcx, mcy)
@test tab == tabc == [30 20 20 29 0;
                      30 20 20 29 1;
                      20 30 30 20 0;
                      20 29 29 20 2;
                      0   0  0  0 1]
@test names(tab) ≅ names(tabc) ≅ [["a", "b", "c", "d", missing],
                                  ["A", "B", "C", "D", missing]]

tab = @inferred freqtable(mx, skipmissing=true)
tabc = @inferred freqtable(mcx, skipmissing=true)
@test tab == tabc == [99, 100, 100, 100]
@test names(tab) ≅ names(tabc) ≅ [["a", "b", "c", "d"]]
tab = @inferred freqtable(my, skipmissing=true)
tabc = @inferred freqtable(mcy, skipmissing=true)
@test names(tab) ≅ names(tabc) ≅ [["A", "B", "C", "D"]]
@test tab == tabc == [100, 99, 99, 98]
tab = @inferred freqtable(mx, my, skipmissing=true)
tabc = @inferred freqtable(mcx, mcy, skipmissing=true)
@test tab == tabc == [30 20 20 29;
                      30 20 20 29;
                      20 30 30 20;
                      20 29 29 20]

using DataFrames

for docat in [false, true]
    iris = DataFrame(SepalLength=[4.8, 4.3, 5.8, 5.7, 5.4, 5.7, 5.7, 6.2,
                                  5.1, 5.7, 6.3, 5.8, 7.1, 6.3, 6.5, 7.6, 4.9],
                     SepalWidth=[3, 3, 4, 4.4, 3.9, 3, 2.9, 2.9, 2.5, 2.8,
                                 3.3, 2.7, 3, 2.9, 3, 3, 2.5],
                     Species=["Iris-setosa", "Iris-setosa", "Iris-setosa",
                              "Iris-setosa", "Iris-setosa", "Iris-versicolor",
                              "Iris-versicolor", "Iris-versicolor", "Iris-versicolor",
                              "Iris-versicolor", "Iris-virginica", "Iris-virginica",
                              "Iris-virginica", "Iris-virginica", "Iris-virginica",
                              "Iris-virginica", "Iris-virginica"])
    if docat
        iris.LongSepal = categorical(iris.SepalLength .> 5.0)
    else
        iris.LongSepal = iris.SepalLength .> 5.0
    end
    for cols in ((:Species, :LongSepal), ("Species", "LongSepal"),
                 ("Species", :LongSepal), (:Species, "LongSepal"))
        tab = freqtable(iris, cols...)
        @test tab == [2 3
                    0 5
                    1 6]
        if all(x -> x isa AbstractString, cols)
            @test dimnames(tab) == ["Species", "LongSepal"]
        else
            @test dimnames(tab) == [:Species, :LongSepal]
        end
        @test names(tab) == [["Iris-setosa", "Iris-versicolor", "Iris-virginica"], [false, true]]
        @test (names(tab, 2) isa CategoricalArray) == docat
    end

    tab = freqtable(iris, :Species, :LongSepal, subset=iris.SepalWidth .< 3.8)
    @test tab == [2 0
                  0 5
                  1 6]
    @test names(tab[1:2, :]) == [["Iris-setosa", "Iris-versicolor"], [false, true]]
    @test (names(tab, 2) isa CategoricalArray) == docat
    iris_nt = (Species = iris.Species, LongSepal = iris.LongSepal)
    @test freqtable(iris, :Species, :LongSepal) == freqtable(iris_nt, :Species, :LongSepal)

    @test_throws ArgumentError freqtable(iris)
    @test_throws ArgumentError freqtable(nothing, :Species, :LongSepal)
end

# Issue #5
@test @inferred freqtable([Set(1), Set(2)]) == [1, 1]
@test @inferred freqtable([Set(1), Set(2)], [Set(1), Set(2)]) == [1 0; 0 1]

@test_throws ArgumentError freqtable()
@test_throws ArgumentError freqtable(DataFrame())

# Integer dimension
using NamedArrays

df = DataFrame(A = 101:103, B = ["x","y","y"]);
intft = freqtable(df, :A, :B)
@test names(intft) == [[101,102,103],["x","y"]]
@test intft == [1 0;
                0 1;
                0 1]

@test_throws BoundsError intft[101,"x"]
@test intft[Name(101),"x"] == 1

# proptable
df = DataFrame(x = [1, 2, 1, 2], y = [1, 1, 2, 2], z = ["a", "a", "c", "d"])

for cols in ((:x, :z), ("x", "z"), ("x", :z), (:x, "z"))
    tab = proptable(df, cols...)
    if all(x -> x isa AbstractString, cols)
        @test dimnames(tab) == ["x", "z"]
    else
        @test dimnames(tab) == [:x, :z]
    end
    @test tab == [0.25 0.25 0.0
                  0.25 0.0  0.25]
    @test names(tab) == [[1, 2], ["a", "c", "d"]]
end

tab = proptable(df, :x, :z, margins=1)
@test tab == [0.5 0.5 0.0
              0.5 0.0 0.5]

tab = proptable(df, :x, :y, margins=(1,2))
@test tab == [1.0 1.0
              1.0 1.0]
@test names(tab) == [[1, 2], [1, 2]]

@test_throws ArgumentError proptable(df)
@test_throws ArgumentError proptable(nothing, :x, :y)
@test_throws MethodError proptable(df, :x, :y, 1, 2)


max_stars_repo_path: test/4 Trig functions/4.7 Miscellaneous/4.7.4 x^m (a+b trig^n)^p.jl


text:
using Test
using QuantumLattices.Prerequisites.Factories

@testset "escape" begin
    @test escape(true,RawExpr())==true
    @test escape(true,Escaped())==true
    @test escape(true,UnEscaped())==true
    @test escape(:Int,Escaped(:Int))==:($(Expr(:escape, :Int)))
    @test escape(:Int,Escaped())==:Int
    @test escape(:(Vector{Int}),Escaped(:Vector))==:(($(Expr(:escape, :Vector))){Int})
    @test escape(:Int,UnEscaped(:Int))==:Int
    @test escape(:Int,UnEscaped())==:($(Expr(:escape, :Int)))
    @test escape(:(Vector{Int}),UnEscaped(:Vector))==:(Vector{$(Expr(:escape, :Int))})
end

@testset "names" begin
    @test names(:a)==[:a]
    @test names(:(Vector{Int}))==[:Vector,:Int]
end

@testset "Inference" begin
    @test Inference(name=:T)==Inference(nothing,:T,nothing)
    @test isequal(Inference(name=:T),Inference(nothing,:T,nothing))
    @test (@inference Vector{Tuple{Int,String}})(UnEscaped(:Vector,:Tuple,:Int,:String))==:(Vector{Tuple{Int,String}})
    @test (@inference Type{<:Real})(UnEscaped(:Type,:Real))==:(Type{<:Real})
    @test Inference(:(SVector{N,<:Real}))|>string=="Inference(\n  head:   curly\n  name:   SVector\n  params: Inference[N, <:Real]\n)"
    @test replace(@inference(Vector{<:Real}),name=:AbstractVector)==@inference(AbstractVector{<:Real})
end

@testset "Argument" begin
    argument=Argument(name=:name,default=nothing)
    @test argument|>string=="Argument(\n  name:    name\n  type:    Any\n  slurp:   false\n  default: nothing\n)"

    argument=Argument(:(phone::Vector{Int}=[9,1,1]))
    @test argument.name==:phone
    @test argument.type==Inference(:(Vector{Int}))
    @test argument.slurp==false
    @test argument.default==:([9,1,1])
    @test argument(MixEscaped(UnEscaped(:Vector),Escaped(:Int)))==Expr(:kw,:(phone::Vector{$(Expr(:escape,:Int))}),:[9,1,1])

    argument=Argument(:(properties::Int...))
    @test argument.name==:properties
    @test argument.type==Inference(:Int)
    @test argument.slurp==true
    @test argument.default==nothing
    @test argument(MixEscaped(UnEscaped(:Int)))==:(properties::Int...)

    argument1=@argument address::String
    argument2=Argument(:(address::String))
    @test argument1==argument2
end

@testset "Parameter" begin
    parameter=Parameter(head=:(<:),name=:name,type=Inference(:T))
    @test parameter|>string=="Parameter(\n  head: <:\n  name: name\n  type: T\n)"

    parameter=Parameter(:T)
    @test parameter.head==nothing
    @test parameter.name==:T
    @test parameter.type==nothing
    @test parameter(UnEscaped(:T))==:T

    parameter=Parameter(:(T<:Real))
    @test parameter.head==:(<:)
    @test parameter.name==:T
    @test parameter.type==Inference(:Real)
    @test parameter(UnEscaped(:Real))==:(T<:Real)

    parameter=Parameter(:(<:Real))
    @test parameter.head==:(<:)
    @test parameter.name==nothing
    @test parameter.type==Inference(:Real)
    @test parameter(UnEscaped(:Real))==:(<:Real)

    parameter=@parameter ::Int
    @test parameter.head==:(::)
    @test parameter.name==nothing
    @test parameter.type==Inference(:Int)
    @test parameter(UnEscaped(:Int))==:(Int)
end

@testset "Field" begin
    field=Field(name=:name)
    @test field|>string=="Field(\n  name: name\n  type: Any\n)"

    field=Field(:xs)
    @test field.name==:xs
    @test field.type==Inference(:Any)
    @test field(UnEscaped(:Any))==:(xs::Any)

    field=Field(:(xs::Vector{Int}))
    @test field.name==:xs
    @test field.type==Inference(:(Vector{Int}))
    @test field(UnEscaped(:Vector,:Int))==:(xs::Vector{Int})

    field1=@field xs::Vector{Int}
    field2=Field(:(xs::Vector{Int}))
    @test field1==field2
end

@testset "Block" begin
    block=Block(:(x=1;y=2))
    push!(block)
    rmlines!(block)
    @test block.body==Any[:(x=1),:(y=2)]
    @test block==@rmlines Block(:(x=1;y=2))
    @test block(MixEscaped())==Expr(:block,:(x=1),:(y=2))
    @test block(Escaped())==Expr(:block,:(x=1),:(y=2))

    block=@block a=1
    @push! block b=2 c=3 d=4
    @test block.body==[:(a=1),:(b=2),:(c=3),:(d=4)]
end

@testset "FunctionFactory" begin
    ff=FunctionFactory(name=:fx)
    addargs!(ff)
    addkwargs!(ff)
    extendbody!(ff)
    addwhereparams!(ff)
    addparams!(ff)
    @test ff==FunctionFactory(name=:fx)

    ff=FunctionFactory(:(fx(x::Int,y::Int;choice::Function=sum)=choice(x,y)))
    @test ff.name==:fx
    @test ff.args==Argument.([:(x::Int),:(y::Int)])
    @test ff.kwargs==Argument.([:(choice::Function=sum)])
    @test ff.rtype==Inference(:Any)
    @test ff.whereparams==Parameter[]
    @test ff.body|>rmlines==Block(:(begin choice(x,y) end))

    ff=FunctionFactory(:(
        function fx(x::T,y::T;choice::Function=sum) where T
            choice(x,y)
        end
    ))
    @test ff.name==:fx
    @test ff.args==Argument.([:(x::T),:(y::T)])
    @test ff.kwargs==Argument.([:(choice::Function=sum)])
    @test ff.rtype==Inference(:Any)
    @test ff.whereparams==Parameter.([:T])
    @test ff.body|>rmlines==Block(:(begin choice(x,y) end))

    ff=@functionfactory (fx()::T)=nothing
    @addargs! ff x::T y::T z::T
    @addkwargs! ff sign::Int=1 choice::Function=sum
    @addparams! ff T
    @addwhereparams! ff T<:Number
    @extendbody! ff result=choice(x,y,z) result*=sign
    @test ff.name==:fx
    @test ff.args==Argument.([:(x::T),:(y::T),:(z::T)])
    @test ff.kwargs==Argument.([:(sign::Int=1),:(choice::Function=sum)])
    @test ff.rtype==Inference(:T)
    @test ff.params==[Inference(:T)]
    @test ff.whereparams==Parameter.([:(T<:Number)])
    @test ff.body|>rmlines==Block(:nothing,:(result=choice(x,y,z)),:(result*=sign))
end

@testset "TypeFactory" begin
    tf=TypeFactory(name=:Child)
    addfields!(tf)
    addconstructors!(tf)
    addparams!(tf)
    @test tf==TypeFactory(name=:Child)

    tf=TypeFactory(:(
        struct Child{T<:Real} <: Parent{T}
            address::String
            phone::Vector{Int}
            properties::Vector{T}
        end
    ))
    @test tf.name==:Child
    @test tf.mutable==false
    @test tf.params==Parameter.([:(T<:Real)])
    @test tf.supertype==Inference(:(Parent{T}))
    @test tf.fields==Field.([:(address::String),:(phone::Vector{Int}),:(properties::Vector{T})])
    @test tf.constructors==FunctionFactory[]

    tf=@typefactory struct Child <: Parent{T} end
    @addparams! tf T<:Real
    @addfields! tf address::String phone::Vector{Int} properties::Vector{T}
    @addconstructors! tf Child(address::String,phone::Vector{Int},properties::Vector{T}) where T=new(address,phone,properties)
    @test tf.name==:Child
    @test tf.mutable==false
    @test tf.params==Parameter.([:(T<:Real)])
    @test tf.supertype==Inference(:(Parent{T}))
    @test tf.fields==Field.([:(address::String),:(phone::Vector{Int}),:(properties::Vector{T})])
end

eval((
    @typefactory struct Child
        name::String
        seniority::Int
        Child(name::String,seniority::Int=1)=new(name,seniority)
    end
)(MixEscaped(UnEscaped(:String,:Int,:Any))))

@testset "call" begin
    c=Child("Tuanzi")
    @test c.name=="Tuanzi"
    @test c.seniority==1
end


text:
using BrainFlow
using BrainFlowML
using JLD2
using DecisionTree # maybe MLJ in future
using Makie

# load a stored model
folder = pwd() # or BrainFlowML.testdata_path
test_model = joinpath(folder, "model_file.jld2")
@load test_model model
modeled_sample_size = 128 # ok, I should store this in the jld2...

board_id = BrainFlow.GFORCE_PRO_BOARD
BrainFlow.enable_dev_logger(BrainFlow.BOARD_CONTROLLER)
params = BrainFlowInputParams()
board_shim = BrainFlow.BoardShim(board_id, params)
BrainFlow.prepare_session(board_shim)
BrainFlow.start_stream(board_shim)

sleep(0.5) # wait a moment for brainflow buffer to fill, and other startup effects

# make a prediction with the model:
function predict_gesture_on_data(board_shim::BrainFlow.BoardShim, modeled_sample_size::Int = 128)
    data = BrainFlow.get_current_board_data(modeled_sample_size, board_shim)
    v = BrainFlowML.preprocess_brainflow_data(data', BrainFlow.get_emg_channels(board_shim.board_id))
    predicted_gesture = apply_forest(model, v')[1]
end

# update continuously
gesture_map = ["", "left", "right", "fist", "spread"]

# start by initializing the plot, it's the slowest part
text_holder = Makie.Node("  start  ")
text(text_holder, show_axis=false, align = (:center, :center))

while true
    sleep(0.02)
    text_holder[] = gesture_map[predict_gesture_on_data(board_shim, modeled_sample_size)+1]
end

# done?
# BrainFlow.stop_stream(board_shim)
# BrainFlow.release_session(board_shim)


text:
function likelihood!(
    likelihood::Matrix{Float64},
    N::Int64,
    K::Int64,
    i_index::Vector{Vector{Int64}},
    response_matrix::Matrix{Float64},
    phi::Matrix{Float64},
)
    ephizero = _sig_cplus.(phi)
    ephione = _sig_c.(phi)
    post_n = zeros(Float64, K)
    for n = 1:N
        for k = 1:K
            post_k = one(Float64)
            for i in i_index[n]
                if response_matrix[i, n] > 0
                    post_k *= ephione[k, i]
                else
                    post_k *= ephizero[k, i]
                end
            end
            likelihood[n, k] = copy(post_k)
        end
    end
    return nothing
end

function posterior_simplified!(
    post::Matrix{Float64},
    N::Int64,
    K::Int64,
    i_index::Vector{Vector{Int64}},
    r::Matrix{Float64},
    Wk::Vector{Float64},
    phi::Matrix{Float64},
)
    ephizero = _sig_cplus.(phi)
    ephione = 1 .- ephizero
    post_n = zeros(Float64, K)
    for n = 1:N
        for k = 1:K
            post_k = one(Float64)
            for i in i_index[n]
                if r[i, n] > 0
                    post_k *= ephione[k, i]
                else
                    post_k *= ephizero[k, i]
                end
            end
            post_n[k] = copy(post_k)
        end
        post_n = (post_n .* Wk) #modify with first_latent
        exp_cd = sum(post_n)
        if exp_cd > typemin(Float64)
            post_n = post_n ./ exp_cd
        end
        post[n, :] = copy(post_n)
    end
    return nothing
end

function max_i(
    X::Matrix{Float64},
    sumpk_i::Vector{Float64},
    r1_i::Vector{Float64},
    pars_i::Vector{Float64},
    bounds::Vector{Vector{Float64}},
    opt_settings::Vector{Float64}
)
    new_pars_i = copy(pars_i)
    opt = NLopt.Opt(:LD_SLSQP, 2)
    opt.maxtime = opt_settings[1]
    opt.xtol_rel = opt_settings[2]
    opt.ftol_rel = opt_settings[3]
    opt.lower_bounds = [bounds[1][1], bounds[2][1]]
    opt.upper_bounds = [bounds[1][2], bounds[2][2]]
    function myf(x::Vector, grad::Vector)
        n_par = size(x, 1)
        if n_par == 2
            y = X * x
        else
            y = x
        end
        if size(grad, 1) > 0
            p = r1_i - (sumpk_i .* _sig_c.(y))
            p = X' * p
            for i = 1:size(grad, 1)
                grad[i] = p[i]
            end
        end
        return sum(r1_i .* y - (sumpk_i .* _log_c.( 1 .+ _exp_c.(y))))
    end
    opt.max_objective = myf
    opt_f = Array{Cdouble}(undef, 1)
    ccall(
        (:nlopt_optimize, NLopt.libnlopt),
        NLopt.Result,
        (NLopt._Opt, Ptr{Cdouble}, Ptr{Cdouble}),
        opt,
        new_pars_i,
        opt_f,
    )
    return new_pars_i::Vector{Float64}
end

function max_LH_MMLE!(
    pars_start::Matrix{Float64},
    phi::Matrix{Float64},
    posterior::Matrix{Float64},
    i_index::Vector{Vector{Int64}},
    design::Matrix{Float64},
    X::Matrix{Float64},
    Wk::Vector{Float64},
    response_matrix::Matrix{Float64},
    opt_settings::Vector{Float64},
    bounds::Vector{Vector{Vector{Float64}}},
)
    n_items = size(pars_start, 2)
    N = size(i_index, 1)
    K = size(X, 1)
    sumpk = zeros(Float64, K, n_items)
    r1 = similar(sumpk)
    posterior_simplified!(posterior, N, K, i_index, response_matrix, Wk, phi)
    LinearAlgebra.BLAS.gemm!(
        'T',
        'T',
        one(Float64),
        posterior,
        design,
        zero(Float64),
        sumpk,
    )# sumpk KxI
    LinearAlgebra.BLAS.gemm!(
        'T',
        'T',
        one(Float64),
        posterior,
        response_matrix,
        zero(Float64),
        r1,
    )# r1 KxI

    #opt.maxeval=50
    pars_start = Distributed.@sync Distributed.@distributed (hcat) for i = 1:n_items
        max_i(X, sumpk[:, i], r1[:, i], pars_start[:, i], bounds[i], opt_settings)
    end
    LinearAlgebra.BLAS.gemm!('N', 'N', one(Float64), X, pars_start, zero(Float64), phi)# phi=New_pars*X1', if A'*B then 'T', 'N'
    return pars_start::Matrix{Float64}
end

function optimize_2pl_1d_super_fast(je_mmle_model::JointEstimationMMLEModel)
    local parameters = je_mmle_model.parameters
    local latents = je_mmle_model.latents
    local dist = je_mmle_model.dist
    local n_index = je_mmle_model.n_index
    local i_index = je_mmle_model.i_index
    local responses_per_item = je_mmle_model.responses_per_item
    local responses_per_examinee = je_mmle_model.responses_per_examinee

    I = size(parameters, 1)
    N = size(latents, 1)
    K = size(dist.support, 1)

    Xk = dist.support
    X = hcat(ones(K), Xk)
    Wk = dist.p

    iter = 1

    # starting values
    before_time = time()
    stop = false
    old_likelihood = -Inf
    old_pars = hcat(_get_parameters_vals.(parameters)...)
    #change parametrization form a(t-b) to b+at
    old_pars[2, :] = .-old_pars[2, :] .* old_pars[1, :]
    old_pars_2 = copy(old_pars)
    old_pars[1, :] = copy(old_pars_2[2, :])
    old_pars[2, :] = copy(old_pars_2[1, :])

    new_pars = copy(old_pars)

    items_bounds = map( p -> [[min(-p.bounds_b[1], -p.bounds_b[2]), max(-p.bounds_b[1], -p.bounds_b[2])], p.bounds_a], parameters)

    phi = X * new_pars

    design = zeros(Float64, I, N)
    for i in 1:I
        design[i, n_index[i]] .= 1.0
    end

    response_matrix = zeros(Float64, I, N)
    for i = 1:I
        response_matrix[i, n_index[i]] = responses_per_item[i]
    end

    posterior = zeros(Float64, N, K)
    likelihood_matrix = similar(posterior)
    oneoverN = fill(1 / N, N)

    posterior_simplified!(
                        posterior,
                        N,
                        K,
                        i_index,
                        response_matrix,
                        Wk,
                        phi,
                    )

    start_time = time()

    while !stop
        # calibrate items
        new_pars = max_LH_MMLE!(
            new_pars,
            phi,
            posterior,
            i_index,
            design,
            X,
            Wk,
            response_matrix,
            je_mmle_model.int_opt_settings,
            items_bounds,
        )
        likelihood!(likelihood_matrix, N, K, i_index, response_matrix, phi)
        new_likelihood = sum(
            _log_c.(
                LinearAlgebra.BLAS.gemv('N', one(Float64), likelihood_matrix, Wk),
            )
        )
        posterior_simplified!(
            posterior,
            N,
            K,
            i_index,
            response_matrix,
            Wk,
            phi,
        )
        if je_mmle_model.rescale_latent
            Wk = LinearAlgebra.BLAS.gemv('T', one(Float64), posterior, oneoverN) #if Wk depends only on the likelihoods
            observed = [LinearAlgebra.dot(Wk, Xk), sqrt(LinearAlgebra.dot(Wk, Xk .^ 2))]
            observed = [
                observed[1] - je_mmle_model.metric[1],
                observed[2] / je_mmle_model.metric[2],
            ]
            #check mean
            #if  (abs(observed[1]) > 1e-4 ) || (abs(observed[2] - 1.0) > 1e-4)
                Xk2, Wk2 = my_rescale(Xk, Wk, observed)
                Wk = cubic_spline_int(Xk, Xk2, Wk2)
                X = hcat(ones(K), Xk2[2:(K+1)])
            #end
        end
        if any([
            check_iter(iter; max_iter = Int64(je_mmle_model.ext_opt_settings[1]), verbosity = Int(je_mmle_model.ext_opt_settings[5])),
            check_time(start_time; max_time = Int64(je_mmle_model.ext_opt_settings[2]), verbosity = Int(je_mmle_model.ext_opt_settings[5])),
            check_f_tol_rel!(
                new_likelihood,
                old_likelihood;
                f_tol_rel = je_mmle_model.ext_opt_settings[3],
                verbosity = Int(je_mmle_model.ext_opt_settings[5])
                ),
            check_x_tol_rel!(
                new_pars,
                old_pars;
                x_tol_rel = je_mmle_model.ext_opt_settings[4],
                verbosity = Int(je_mmle_model.ext_opt_settings[5])
            )]
            )
            stop = true
        end
        iter += 1
    end
    #change parametrization form a(t-b) to b+at
    new_pars[1, :] = .-new_pars[1, :] ./ new_pars[2, :]
    map(i -> begin
            parameters[i].a = new_pars[2, i]
            parameters[i].b = new_pars[1, i]
        end
        ,1 : I)

    map(n -> begin
            latents[n].posterior = Distributions.DiscreteNonParametric(Xk, posterior[n, :])
        end
        ,1 : N)
    dist = Distributions.DiscreteNonParametric(Xk, Wk)
    return parameters::Vector{<:AbstractParameters}, latents::Vector{<:AbstractLatent}, dist::Distributions.DiscreteUnivariateDistribution
end


text:
abstract type Agent end
#TIME
@with_kw mutable struct Period @deftype Int32
    number_of_days = 1; @assert number_of_days > 0
    number_of_t_steps = 24
    step_size::Float64 = 24 / number_of_t_steps
end

@with_kw mutable struct Scenario
    id::Any = "anyscenario"
    counter::Int64 = 1
    prob::Float64 = 1.0
end

@with_kw mutable struct Result
    period::Period = Period()
    id::Any = 1
    scenario::Scenario = Scenario() #INIT WITH A SINGLE SCENARIO
    values::Array{Float64,2} = zeros((period.number_of_days, period.number_of_t_steps))
end

abstract type Forecast end
#EVERY FORECAST TYPE BELONGS TO A SINGLE SCENARIO

@with_kw mutable struct Demand <: Forecast
    period::Period = Period()
    root::Union{Nothing,Scenario} = nothing
    id::Any = 1
    scenario::Scenario = Scenario() #INIT WITH A SINGLE SCENARIO
    values::Array{Float64,2} = zeros((period.number_of_days, period.number_of_t_steps))
end

@with_kw mutable struct Price <: Forecast
    period::Period = Period()
    root::Union{Nothing,Scenario} = nothing
    id::Any = 1
    scenario::Scenario = Scenario() #INIT WITH A SINGLE SCENARIO
    values::Array{Float64,2} = zeros((period.number_of_days, period.number_of_t_steps))
end

@with_kw mutable struct Preferences
    ϵ::Float64 = 1.0 #For the CVAR based constraints
    βᴬ::Float64 = 0.1 #adjustment param for the risk-averseness
    γᴬ::Float64 = 1.0 #tradeoff between maximizing expacted return vs risk aversion, 1.0 -> risk neutral
    bigM::Float64 = 1000.0 #Big-M value if it is needed in the model
end


text:
# Automatically generated using Clang.jl

const CXVirtualFileOverlayImpl = Cvoid
const CXVirtualFileOverlay = Ptr{CXVirtualFileOverlayImpl}
const CXModuleMapDescriptorImpl = Cvoid
const CXModuleMapDescriptor = Ptr{CXModuleMapDescriptorImpl}
const CXCompilationDatabase = Ptr{Cvoid}
const CXCompileCommands = Ptr{Cvoid}
const CXCompileCommand = Ptr{Cvoid}

@cenum CXCompilationDatabase_Error::UInt32 begin
    CXCompilationDatabase_NoError = 0
    CXCompilationDatabase_CanNotLoadDatabase = 1
end

@cenum CXErrorCode::UInt32 begin
    CXError_Success = 0
    CXError_Failure = 1
    CXError_Crashed = 2
    CXError_InvalidArguments = 3
    CXError_ASTReadError = 4
end

struct CXString
    data::Ptr{Cvoid}
    private_flags::UInt32
end

struct CXStringSet
    Strings::Ptr{CXString}
    Count::UInt32
end

const CXTranslationUnitImpl = Cvoid
const CXTranslationUnit = Ptr{CXTranslationUnitImpl}

struct CXComment
    ASTNode::Ptr{Cvoid}
    TranslationUnit::CXTranslationUnit
end

@cenum CXCommentKind::UInt32 begin
    CXComment_Null = 0
    CXComment_Text = 1
    CXComment_InlineCommand = 2
    CXComment_HTMLStartTag = 3
    CXComment_HTMLEndTag = 4
    CXComment_Paragraph = 5
    CXComment_BlockCommand = 6
    CXComment_ParamCommand = 7
    CXComment_TParamCommand = 8
    CXComment_VerbatimBlockCommand = 9
    CXComment_VerbatimBlockLine = 10
    CXComment_VerbatimLine = 11
    CXComment_FullComment = 12
end

@cenum CXCommentInlineCommandRenderKind::UInt32 begin
    CXCommentInlineCommandRenderKind_Normal = 0
    CXCommentInlineCommandRenderKind_Bold = 1
    CXCommentInlineCommandRenderKind_Monospaced = 2
    CXCommentInlineCommandRenderKind_Emphasized = 3
end

@cenum CXCommentParamPassDirection::UInt32 begin
    CXCommentParamPassDirection_In = 0
    CXCommentParamPassDirection_Out = 1
    CXCommentParamPassDirection_InOut = 2
end

const CINDEX_VERSION_MAJOR = 0
const CINDEX_VERSION_MINOR = 59

# Skipping MacroDefinition: CINDEX_VERSION_ENCODE ( major , minor ) ( ( ( major ) * 10000 ) + ( ( minor ) * 1 ) )
# Skipping MacroDefinition: CINDEX_VERSION CINDEX_VERSION_ENCODE ( CINDEX_VERSION_MAJOR , CINDEX_VERSION_MINOR )
# Skipping MacroDefinition: CINDEX_VERSION_STRINGIZE_ ( major , minor ) # major "." # minor
# Skipping MacroDefinition: CINDEX_VERSION_STRINGIZE ( major , minor ) CINDEX_VERSION_STRINGIZE_ ( major , minor )
# Skipping MacroDefinition: CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE ( CINDEX_VERSION_MAJOR , CINDEX_VERSION_MINOR )

const CXIndex = Ptr{Cvoid}
const CXTargetInfoImpl = Cvoid
const CXTargetInfo = Ptr{CXTargetInfoImpl}
const CXClientData = Ptr{Cvoid}

struct CXUnsavedFile
    Filename::Cstring
    Contents::Cstring
    Length::Culong
end

@cenum CXAvailabilityKind::UInt32 begin
    CXAvailability_Available = 0
    CXAvailability_Deprecated = 1
    CXAvailability_NotAvailable = 2
    CXAvailability_NotAccessible = 3
end

struct CXVersion
    Major::Cint
    Minor::Cint
    Subminor::Cint
end

@cenum CXCursor_ExceptionSpecificationKind::UInt32 begin
    CXCursor_ExceptionSpecificationKind_None = 0
    CXCursor_ExceptionSpecificationKind_DynamicNone = 1
    CXCursor_ExceptionSpecificationKind_Dynamic = 2
    CXCursor_ExceptionSpecificationKind_MSAny = 3
    CXCursor_ExceptionSpecificationKind_BasicNoexcept = 4
    CXCursor_ExceptionSpecificationKind_ComputedNoexcept = 5
    CXCursor_ExceptionSpecificationKind_Unevaluated = 6
    CXCursor_ExceptionSpecificationKind_Uninstantiated = 7
    CXCursor_ExceptionSpecificationKind_Unparsed = 8
    CXCursor_ExceptionSpecificationKind_NoThrow = 9
end

@cenum CXGlobalOptFlags::UInt32 begin
    CXGlobalOpt_None = 0
    CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1
    CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2
    CXGlobalOpt_ThreadBackgroundPriorityForAll = 3
end

const CXFile = Ptr{Cvoid}

struct CXFileUniqueID
    data::NTuple{3, Culonglong}
end

struct CXSourceLocation
    ptr_data::NTuple{2, Ptr{Cvoid}}
    int_data::UInt32
end

struct CXSourceRange
    ptr_data::NTuple{2, Ptr{Cvoid}}
    begin_int_data::UInt32
    end_int_data::UInt32
end

struct CXSourceRangeList
    count::UInt32
    ranges::Ptr{CXSourceRange}
end

@cenum CXDiagnosticSeverity::UInt32 begin
    CXDiagnostic_Ignored = 0
    CXDiagnostic_Note = 1
    CXDiagnostic_Warning = 2
    CXDiagnostic_Error = 3
    CXDiagnostic_Fatal = 4
end

const CXDiagnostic = Ptr{Cvoid}
const CXDiagnosticSet = Ptr{Cvoid}

@cenum CXLoadDiag_Error::UInt32 begin
    CXLoadDiag_None = 0
    CXLoadDiag_Unknown = 1
    CXLoadDiag_CannotLoad = 2
    CXLoadDiag_InvalidFile = 3
end

@cenum CXDiagnosticDisplayOptions::UInt32 begin
    CXDiagnostic_DisplaySourceLocation = 1
    CXDiagnostic_DisplayColumn = 2
    CXDiagnostic_DisplaySourceRanges = 4
    CXDiagnostic_DisplayOption = 8
    CXDiagnostic_DisplayCategoryId = 16
    CXDiagnostic_DisplayCategoryName = 32
end

@cenum CXTranslationUnit_Flags::UInt32 begin
    CXTranslationUnit_None = 0
    CXTranslationUnit_DetailedPreprocessingRecord = 1
    CXTranslationUnit_Incomplete = 2
    CXTranslationUnit_PrecompiledPreamble = 4
    CXTranslationUnit_CacheCompletionResults = 8
    CXTranslationUnit_ForSerialization = 16
    CXTranslationUnit_CXXChainedPCH = 32
    CXTranslationUnit_SkipFunctionBodies = 64
    CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128
    CXTranslationUnit_CreatePreambleOnFirstParse = 256
    CXTranslationUnit_KeepGoing = 512
    CXTranslationUnit_SingleFileParse = 1024
    CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 2048
    CXTranslationUnit_IncludeAttributedTypes = 4096
    CXTranslationUnit_VisitImplicitAttributes = 8192
    CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 16384
end

@cenum CXSaveTranslationUnit_Flags::UInt32 begin
    CXSaveTranslationUnit_None = 0
end

@cenum CXSaveError::UInt32 begin
    CXSaveError_None = 0
    CXSaveError_Unknown = 1
    CXSaveError_TranslationErrors = 2
    CXSaveError_InvalidTU = 3
end

@cenum CXReparse_Flags::UInt32 begin
    CXReparse_None = 0
end

@cenum CXTUResourceUsageKind::UInt32 begin
    CXTUResourceUsage_AST = 1
    CXTUResourceUsage_Identifiers = 2
    CXTUResourceUsage_Selectors = 3
    CXTUResourceUsage_GlobalCompletionResults = 4
    CXTUResourceUsage_SourceManagerContentCache = 5
    CXTUResourceUsage_AST_SideTables = 6
    CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7
    CXTUResourceUsage_SourceManager_Membuffer_MMap = 8
    CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9
    CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10
    CXTUResourceUsage_Preprocessor = 11
    CXTUResourceUsage_PreprocessingRecord = 12
    CXTUResourceUsage_SourceManager_DataStructures = 13
    CXTUResourceUsage_Preprocessor_HeaderSearch = 14
    CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = 1
    CXTUResourceUsage_MEMORY_IN_BYTES_END = 14
    CXTUResourceUsage_First = 1
    CXTUResourceUsage_Last = 14
end

struct CXTUResourceUsageEntry
    kind::CXTUResourceUsageKind
    amount::Culong
end

struct CXTUResourceUsage
    data::Ptr{Cvoid}
    numEntries::UInt32
    entries::Ptr{CXTUResourceUsageEntry}
end

@cenum CXCursorKind::UInt32 begin
    CXCursor_UnexposedDecl = 1
    CXCursor_StructDecl = 2
    CXCursor_UnionDecl = 3
    CXCursor_ClassDecl = 4
    CXCursor_EnumDecl = 5
    CXCursor_FieldDecl = 6
    CXCursor_EnumConstantDecl = 7
    CXCursor_FunctionDecl = 8
    CXCursor_VarDecl = 9
    CXCursor_ParmDecl = 10
    CXCursor_ObjCInterfaceDecl = 11
    CXCursor_ObjCCategoryDecl = 12
    CXCursor_ObjCProtocolDecl = 13
    CXCursor_ObjCPropertyDecl = 14
    CXCursor_ObjCIvarDecl = 15
    CXCursor_ObjCInstanceMethodDecl = 16
    CXCursor_ObjCClassMethodDecl = 17
    CXCursor_ObjCImplementationDecl = 18
    CXCursor_ObjCCategoryImplDecl = 19
    CXCursor_TypedefDecl = 20
    CXCursor_CXXMethod = 21
    CXCursor_Namespace = 22
    CXCursor_LinkageSpec = 23
    CXCursor_Constructor = 24
    CXCursor_Destructor = 25
    CXCursor_ConversionFunction = 26
    CXCursor_TemplateTypeParameter = 27
    CXCursor_NonTypeTemplateParameter = 28
    CXCursor_TemplateTemplateParameter = 29
    CXCursor_FunctionTemplate = 30
    CXCursor_ClassTemplate = 31
    CXCursor_ClassTemplatePartialSpecialization = 32
    CXCursor_NamespaceAlias = 33
    CXCursor_UsingDirective = 34
    CXCursor_UsingDeclaration = 35
    CXCursor_TypeAliasDecl = 36
    CXCursor_ObjCSynthesizeDecl = 37
    CXCursor_ObjCDynamicDecl = 38
    CXCursor_CXXAccessSpecifier = 39
    CXCursor_FirstDecl = 1
    CXCursor_LastDecl = 39
    CXCursor_FirstRef = 40
    CXCursor_ObjCSuperClassRef = 40
    CXCursor_ObjCProtocolRef = 41
    CXCursor_ObjCClassRef = 42
    CXCursor_TypeRef = 43
    CXCursor_CXXBaseSpecifier = 44
    CXCursor_TemplateRef = 45
    CXCursor_NamespaceRef = 46
    CXCursor_MemberRef = 47
    CXCursor_LabelRef = 48
    CXCursor_OverloadedDeclRef = 49
    CXCursor_VariableRef = 50
    CXCursor_LastRef = 50
    CXCursor_FirstInvalid = 70
    CXCursor_InvalidFile = 70
    CXCursor_NoDeclFound = 71
    CXCursor_NotImplemented = 72
    CXCursor_InvalidCode = 73
    CXCursor_LastInvalid = 73
    CXCursor_FirstExpr = 100
    CXCursor_UnexposedExpr = 100
    CXCursor_DeclRefExpr = 101
    CXCursor_MemberRefExpr = 102
    CXCursor_CallExpr = 103
    CXCursor_ObjCMessageExpr = 104
    CXCursor_BlockExpr = 105
    CXCursor_IntegerLiteral = 106
    CXCursor_FloatingLiteral = 107
    CXCursor_ImaginaryLiteral = 108
    CXCursor_StringLiteral = 109
    CXCursor_CharacterLiteral = 110
    CXCursor_ParenExpr = 111
    CXCursor_UnaryOperator = 112
    CXCursor_ArraySubscriptExpr = 113
    CXCursor_BinaryOperator = 114
    CXCursor_CompoundAssignOperator = 115
    CXCursor_ConditionalOperator = 116
    CXCursor_CStyleCastExpr = 117
    CXCursor_CompoundLiteralExpr = 118
    CXCursor_InitListExpr = 119
    CXCursor_AddrLabelExpr = 120
    CXCursor_StmtExpr = 121
    CXCursor_GenericSelectionExpr = 122
    CXCursor_GNUNullExpr = 123
    CXCursor_CXXStaticCastExpr = 124
    CXCursor_CXXDynamicCastExpr = 125
    CXCursor_CXXReinterpretCastExpr = 126
    CXCursor_CXXConstCastExpr = 127
    CXCursor_CXXFunctionalCastExpr = 128
    CXCursor_CXXTypeidExpr = 129
    CXCursor_CXXBoolLiteralExpr = 130
    CXCursor_CXXNullPtrLiteralExpr = 131
    CXCursor_CXXThisExpr = 132
    CXCursor_CXXThrowExpr = 133
    CXCursor_CXXNewExpr = 134
    CXCursor_CXXDeleteExpr = 135
    CXCursor_UnaryExpr = 136
    CXCursor_ObjCStringLiteral = 137
    CXCursor_ObjCEncodeExpr = 138
    CXCursor_ObjCSelectorExpr = 139
    CXCursor_ObjCProtocolExpr = 140
    CXCursor_ObjCBridgedCastExpr = 141
    CXCursor_PackExpansionExpr = 142
    CXCursor_SizeOfPackExpr = 143
    CXCursor_LambdaExpr = 144
    CXCursor_ObjCBoolLiteralExpr = 145
    CXCursor_ObjCSelfExpr = 146
    CXCursor_OMPArraySectionExpr = 147
    CXCursor_ObjCAvailabilityCheckExpr = 148
    CXCursor_FixedPointLiteral = 149
    CXCursor_LastExpr = 149
    CXCursor_FirstStmt = 200
    CXCursor_UnexposedStmt = 200
    CXCursor_LabelStmt = 201
    CXCursor_CompoundStmt = 202
    CXCursor_CaseStmt = 203
    CXCursor_DefaultStmt = 204
    CXCursor_IfStmt = 205
    CXCursor_SwitchStmt = 206
    CXCursor_WhileStmt = 207
    CXCursor_DoStmt = 208
    CXCursor_ForStmt = 209
    CXCursor_GotoStmt = 210
    CXCursor_IndirectGotoStmt = 211
    CXCursor_ContinueStmt = 212
    CXCursor_BreakStmt = 213
    CXCursor_ReturnStmt = 214
    CXCursor_GCCAsmStmt = 215
    CXCursor_AsmStmt = 215
    CXCursor_ObjCAtTryStmt = 216
    CXCursor_ObjCAtCatchStmt = 217
    CXCursor_ObjCAtFinallyStmt = 218
    CXCursor_ObjCAtThrowStmt = 219
    CXCursor_ObjCAtSynchronizedStmt = 220
    CXCursor_ObjCAutoreleasePoolStmt = 221
    CXCursor_ObjCForCollectionStmt = 222
    CXCursor_CXXCatchStmt = 223
    CXCursor_CXXTryStmt = 224
    CXCursor_CXXForRangeStmt = 225
    CXCursor_SEHTryStmt = 226
    CXCursor_SEHExceptStmt = 227
    CXCursor_SEHFinallyStmt = 228
    CXCursor_MSAsmStmt = 229
    CXCursor_NullStmt = 230
    CXCursor_DeclStmt = 231
    CXCursor_OMPParallelDirective = 232
    CXCursor_OMPSimdDirective = 233
    CXCursor_OMPForDirective = 234
    CXCursor_OMPSectionsDirective = 235
    CXCursor_OMPSectionDirective = 236
    CXCursor_OMPSingleDirective = 237
    CXCursor_OMPParallelForDirective = 238
    CXCursor_OMPParallelSectionsDirective = 239
    CXCursor_OMPTaskDirective = 240
    CXCursor_OMPMasterDirective = 241
    CXCursor_OMPCriticalDirective = 242
    CXCursor_OMPTaskyieldDirective = 243
    CXCursor_OMPBarrierDirective = 244
    CXCursor_OMPTaskwaitDirective = 245
    CXCursor_OMPFlushDirective = 246
    CXCursor_SEHLeaveStmt = 247
    CXCursor_OMPOrderedDirective = 248
    CXCursor_OMPAtomicDirective = 249
    CXCursor_OMPForSimdDirective = 250
    CXCursor_OMPParallelForSimdDirective = 251
    CXCursor_OMPTargetDirective = 252
    CXCursor_OMPTeamsDirective = 253
    CXCursor_OMPTaskgroupDirective = 254
    CXCursor_OMPCancellationPointDirective = 255
    CXCursor_OMPCancelDirective = 256
    CXCursor_OMPTargetDataDirective = 257
    CXCursor_OMPTaskLoopDirective = 258
    CXCursor_OMPTaskLoopSimdDirective = 259
    CXCursor_OMPDistributeDirective = 260
    CXCursor_OMPTargetEnterDataDirective = 261
    CXCursor_OMPTargetExitDataDirective = 262
    CXCursor_OMPTargetParallelDirective = 263
    CXCursor_OMPTargetParallelForDirective = 264
    CXCursor_OMPTargetUpdateDirective = 265
    CXCursor_OMPDistributeParallelForDirective = 266
    CXCursor_OMPDistributeParallelForSimdDirective = 267
    CXCursor_OMPDistributeSimdDirective = 268
    CXCursor_OMPTargetParallelForSimdDirective = 269
    CXCursor_OMPTargetSimdDirective = 270
    CXCursor_OMPTeamsDistributeDirective = 271
    CXCursor_OMPTeamsDistributeSimdDirective = 272
    CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273
    CXCursor_OMPTeamsDistributeParallelForDirective = 274
    CXCursor_OMPTargetTeamsDirective = 275
    CXCursor_OMPTargetTeamsDistributeDirective = 276
    CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277
    CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective = 278
    CXCursor_OMPTargetTeamsDistributeSimdDirective = 279
    CXCursor_BuiltinBitCastExpr = 280
    CXCursor_LastStmt = 280
    CXCursor_TranslationUnit = 300
    CXCursor_FirstAttr = 400
    CXCursor_UnexposedAttr = 400
    CXCursor_IBActionAttr = 401
    CXCursor_IBOutletAttr = 402
    CXCursor_IBOutletCollectionAttr = 403
    CXCursor_CXXFinalAttr = 404
    CXCursor_CXXOverrideAttr = 405
    CXCursor_AnnotateAttr = 406
    CXCursor_AsmLabelAttr = 407
    CXCursor_PackedAttr = 408
    CXCursor_PureAttr = 409
    CXCursor_ConstAttr = 410
    CXCursor_NoDuplicateAttr = 411
    CXCursor_CUDAConstantAttr = 412
    CXCursor_CUDADeviceAttr = 413
    CXCursor_CUDAGlobalAttr = 414
    CXCursor_CUDAHostAttr = 415
    CXCursor_CUDASharedAttr = 416
    CXCursor_VisibilityAttr = 417
    CXCursor_DLLExport = 418
    CXCursor_DLLImport = 419
    CXCursor_NSReturnsRetained = 420
    CXCursor_NSReturnsNotRetained = 421
    CXCursor_NSReturnsAutoreleased = 422
    CXCursor_NSConsumesSelf = 423
    CXCursor_NSConsumed = 424
    CXCursor_ObjCException = 425
    CXCursor_ObjCNSObject = 426
    CXCursor_ObjCIndependentClass = 427
    CXCursor_ObjCPreciseLifetime = 428
    CXCursor_ObjCReturnsInnerPointer = 429
    CXCursor_ObjCRequiresSuper = 430
    CXCursor_ObjCRootClass = 431
    CXCursor_ObjCSubclassingRestricted = 432
    CXCursor_ObjCExplicitProtocolImpl = 433
    CXCursor_ObjCDesignatedInitializer = 434
    CXCursor_ObjCRuntimeVisible = 435
    CXCursor_ObjCBoxable = 436
    CXCursor_FlagEnum = 437
    CXCursor_ConvergentAttr = 438
    CXCursor_WarnUnusedAttr = 439
    CXCursor_WarnUnusedResultAttr = 440
    CXCursor_AlignedAttr = 441
    CXCursor_LastAttr = 441
    CXCursor_PreprocessingDirective = 500
    CXCursor_MacroDefinition = 501
    CXCursor_MacroExpansion = 502
    CXCursor_MacroInstantiation = 502
    CXCursor_InclusionDirective = 503
    CXCursor_FirstPreprocessing = 500
    CXCursor_LastPreprocessing = 503
    CXCursor_ModuleImportDecl = 600
    CXCursor_TypeAliasTemplateDecl = 601
    CXCursor_StaticAssert = 602
    CXCursor_FriendDecl = 603
    CXCursor_FirstExtraDecl = 600
    CXCursor_LastExtraDecl = 603
    CXCursor_OverloadCandidate = 700
end

struct CXCursor
    kind::CXCursorKind
    xdata::Cint
    data::NTuple{3, Ptr{Cvoid}}
end

@cenum CXLinkageKind::UInt32 begin
    CXLinkage_Invalid = 0
    CXLinkage_NoLinkage = 1
    CXLinkage_Internal = 2
    CXLinkage_UniqueExternal = 3
    CXLinkage_External = 4
end

@cenum CXVisibilityKind::UInt32 begin
    CXVisibility_Invalid = 0
    CXVisibility_Hidden = 1
    CXVisibility_Protected = 2
    CXVisibility_Default = 3
end

struct CXPlatformAvailability
    Platform::CXString
    Introduced::CXVersion
    Deprecated::CXVersion
    Obsoleted::CXVersion
    Unavailable::Cint
    Message::CXString
end

@cenum CXLanguageKind::UInt32 begin
    CXLanguage_Invalid = 0
    CXLanguage_C = 1
    CXLanguage_ObjC = 2
    CXLanguage_CPlusPlus = 3
end

@cenum CXTLSKind::UInt32 begin
    CXTLS_None = 0
    CXTLS_Dynamic = 1
    CXTLS_Static = 2
end

const CXCursorSetImpl = Cvoid
const CXCursorSet = Ptr{CXCursorSetImpl}

@cenum CXTypeKind::UInt32 begin
    CXType_Invalid = 0
    CXType_Unexposed = 1
    CXType_Void = 2
    CXType_Bool = 3
    CXType_Char_U = 4
    CXType_UChar = 5
    CXType_Char16 = 6
    CXType_Char32 = 7
    CXType_UShort = 8
    CXType_UInt = 9
    CXType_ULong = 10
    CXType_ULongLong = 11
    CXType_UInt128 = 12
    CXType_Char_S = 13
    CXType_SChar = 14
    CXType_WChar = 15
    CXType_Short = 16
    CXType_Int = 17
    CXType_Long = 18
    CXType_LongLong = 19
    CXType_Int128 = 20
    CXType_Float = 21
    CXType_Double = 22
    CXType_LongDouble = 23
    CXType_NullPtr = 24
    CXType_Overload = 25
    CXType_Dependent = 26
    CXType_ObjCId = 27
    CXType_ObjCClass = 28
    CXType_ObjCSel = 29
    CXType_Float128 = 30
    CXType_Half = 31
    CXType_Float16 = 32
    CXType_ShortAccum = 33
    CXType_Accum = 34
    CXType_LongAccum = 35
    CXType_UShortAccum = 36
    CXType_UAccum = 37
    CXType_ULongAccum = 38
    CXType_FirstBuiltin = 2
    CXType_LastBuiltin = 38
    CXType_Complex = 100
    CXType_Pointer = 101
    CXType_BlockPointer = 102
    CXType_LValueReference = 103
    CXType_RValueReference = 104
    CXType_Record = 105
    CXType_Enum = 106
    CXType_Typedef = 107
    CXType_ObjCInterface = 108
    CXType_ObjCObjectPointer = 109
    CXType_FunctionNoProto = 110
    CXType_FunctionProto = 111
    CXType_ConstantArray = 112
    CXType_Vector = 113
    CXType_IncompleteArray = 114
    CXType_VariableArray = 115
    CXType_DependentSizedArray = 116
    CXType_MemberPointer = 117
    CXType_Auto = 118
    CXType_Elaborated = 119
    CXType_Pipe = 120
    CXType_OCLImage1dRO = 121
    CXType_OCLImage1dArrayRO = 122
    CXType_OCLImage1dBufferRO = 123
    CXType_OCLImage2dRO = 124
    CXType_OCLImage2dArrayRO = 125
    CXType_OCLImage2dDepthRO = 126
    CXType_OCLImage2dArrayDepthRO = 127
    CXType_OCLImage2dMSAARO = 128
    CXType_OCLImage2dArrayMSAARO = 129
    CXType_OCLImage2dMSAADepthRO = 130
    CXType_OCLImage2dArrayMSAADepthRO = 131
    CXType_OCLImage3dRO = 132
    CXType_OCLImage1dWO = 133
    CXType_OCLImage1dArrayWO = 134
    CXType_OCLImage1dBufferWO = 135
    CXType_OCLImage2dWO = 136
    CXType_OCLImage2dArrayWO = 137
    CXType_OCLImage2dDepthWO = 138
    CXType_OCLImage2dArrayDepthWO = 139
    CXType_OCLImage2dMSAAWO = 140
    CXType_OCLImage2dArrayMSAAWO = 141
    CXType_OCLImage2dMSAADepthWO = 142
    CXType_OCLImage2dArrayMSAADepthWO = 143
    CXType_OCLImage3dWO = 144
    CXType_OCLImage1dRW = 145
    CXType_OCLImage1dArrayRW = 146
    CXType_OCLImage1dBufferRW = 147
    CXType_OCLImage2dRW = 148
    CXType_OCLImage2dArrayRW = 149
    CXType_OCLImage2dDepthRW = 150
    CXType_OCLImage2dArrayDepthRW = 151
    CXType_OCLImage2dMSAARW = 152
    CXType_OCLImage2dArrayMSAARW = 153
    CXType_OCLImage2dMSAADepthRW = 154
    CXType_OCLImage2dArrayMSAADepthRW = 155
    CXType_OCLImage3dRW = 156
    CXType_OCLSampler = 157
    CXType_OCLEvent = 158
    CXType_OCLQueue = 159
    CXType_OCLReserveID = 160
    CXType_ObjCObject = 161
    CXType_ObjCTypeParam = 162
    CXType_Attributed = 163
    CXType_OCLIntelSubgroupAVCMcePayload = 164
    CXType_OCLIntelSubgroupAVCImePayload = 165
    CXType_OCLIntelSubgroupAVCRefPayload = 166
    CXType_OCLIntelSubgroupAVCSicPayload = 167
    CXType_OCLIntelSubgroupAVCMceResult = 168
    CXType_OCLIntelSubgroupAVCImeResult = 169
    CXType_OCLIntelSubgroupAVCRefResult = 170
    CXType_OCLIntelSubgroupAVCSicResult = 171
    CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172
    CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173
    CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174
    CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175
    CXType_ExtVector = 176
end

@cenum CXCallingConv::UInt32 begin
    CXCallingConv_Default = 0
    CXCallingConv_C = 1
    CXCallingConv_X86StdCall = 2
    CXCallingConv_X86FastCall = 3
    CXCallingConv_X86ThisCall = 4
    CXCallingConv_X86Pascal = 5
    CXCallingConv_AAPCS = 6
    CXCallingConv_AAPCS_VFP = 7
    CXCallingConv_X86RegCall = 8
    CXCallingConv_IntelOclBicc = 9
    CXCallingConv_Win64 = 10
    CXCallingConv_X86_64Win64 = 10
    CXCallingConv_X86_64SysV = 11
    CXCallingConv_X86VectorCall = 12
    CXCallingConv_Swift = 13
    CXCallingConv_PreserveMost = 14
    CXCallingConv_PreserveAll = 15
    CXCallingConv_AArch64VectorCall = 16
    CXCallingConv_Invalid = 100
    CXCallingConv_Unexposed = 200
end

struct CXType
    kind::CXTypeKind
    data::NTuple{2, Ptr{Cvoid}}
end

@cenum CXTemplateArgumentKind::UInt32 begin
    CXTemplateArgumentKind_Null = 0
    CXTemplateArgumentKind_Type = 1
    CXTemplateArgumentKind_Declaration = 2
    CXTemplateArgumentKind_NullPtr = 3
    CXTemplateArgumentKind_Integral = 4
    CXTemplateArgumentKind_Template = 5
    CXTemplateArgumentKind_TemplateExpansion = 6
    CXTemplateArgumentKind_Expression = 7
    CXTemplateArgumentKind_Pack = 8
    CXTemplateArgumentKind_Invalid = 9
end

@cenum CXTypeNullabilityKind::UInt32 begin
    CXTypeNullability_NonNull = 0
    CXTypeNullability_Nullable = 1
    CXTypeNullability_Unspecified = 2
    CXTypeNullability_Invalid = 3
end

@cenum CXTypeLayoutError::Int32 begin
    CXTypeLayoutError_Invalid = -1
    CXTypeLayoutError_Incomplete = -2
    CXTypeLayoutError_Dependent = -3
    CXTypeLayoutError_NotConstantSize = -4
    CXTypeLayoutError_InvalidFieldName = -5
    CXTypeLayoutError_Undeduced = -6
end

@cenum CXRefQualifierKind::UInt32 begin
    CXRefQualifier_None = 0
    CXRefQualifier_LValue = 1
    CXRefQualifier_RValue = 2
end

@cenum CX_CXXAccessSpecifier::UInt32 begin
    CX_CXXInvalidAccessSpecifier = 0
    CX_CXXPublic = 1
    CX_CXXProtected = 2
    CX_CXXPrivate = 3
end

@cenum CX_StorageClass::UInt32 begin
    CX_SC_Invalid = 0
    CX_SC_None = 1
    CX_SC_Extern = 2
    CX_SC_Static = 3
    CX_SC_PrivateExtern = 4
    CX_SC_OpenCLWorkGroupLocal = 5
    CX_SC_Auto = 6
    CX_SC_Register = 7
end

@cenum CXChildVisitResult::UInt32 begin
    CXChildVisit_Break = 0
    CXChildVisit_Continue = 1
    CXChildVisit_Recurse = 2
end

const CXCursorVisitor = Ptr{Cvoid}
const CXCursorVisitorBlock = Cvoid
const CXPrintingPolicy = Ptr{Cvoid}

@cenum CXPrintingPolicyProperty::UInt32 begin
    CXPrintingPolicy_Indentation = 0
    CXPrintingPolicy_SuppressSpecifiers = 1
    CXPrintingPolicy_SuppressTagKeyword = 2
    CXPrintingPolicy_IncludeTagDefinition = 3
    CXPrintingPolicy_SuppressScope = 4
    CXPrintingPolicy_SuppressUnwrittenScope = 5
    CXPrintingPolicy_SuppressInitializers = 6
    CXPrintingPolicy_ConstantArraySizeAsWritten = 7
    CXPrintingPolicy_AnonymousTagLocations = 8
    CXPrintingPolicy_SuppressStrongLifetime = 9
    CXPrintingPolicy_SuppressLifetimeQualifiers = 10
    CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors = 11
    CXPrintingPolicy_Bool = 12
    CXPrintingPolicy_Restrict = 13
    CXPrintingPolicy_Alignof = 14
    CXPrintingPolicy_UnderscoreAlignof = 15
    CXPrintingPolicy_UseVoidForZeroParams = 16
    CXPrintingPolicy_TerseOutput = 17
    CXPrintingPolicy_PolishForDeclaration = 18
    CXPrintingPolicy_Half = 19
    CXPrintingPolicy_MSWChar = 20
    CXPrintingPolicy_IncludeNewlines = 21
    CXPrintingPolicy_MSVCFormatting = 22
    CXPrintingPolicy_ConstantsAsWritten = 23
    CXPrintingPolicy_SuppressImplicitBase = 24
    CXPrintingPolicy_FullyQualifiedName = 25
    CXPrintingPolicy_LastProperty = 25
end

@cenum CXObjCPropertyAttrKind::UInt32 begin
    CXObjCPropertyAttr_noattr = 0
    CXObjCPropertyAttr_readonly = 1
    CXObjCPropertyAttr_getter = 2
    CXObjCPropertyAttr_assign = 4
    CXObjCPropertyAttr_readwrite = 8
    CXObjCPropertyAttr_retain = 16
    CXObjCPropertyAttr_copy = 32
    CXObjCPropertyAttr_nonatomic = 64
    CXObjCPropertyAttr_setter = 128
    CXObjCPropertyAttr_atomic = 256
    CXObjCPropertyAttr_weak = 512
    CXObjCPropertyAttr_strong = 1024
    CXObjCPropertyAttr_unsafe_unretained = 2048
    CXObjCPropertyAttr_class = 4096
end

@cenum CXObjCDeclQualifierKind::UInt32 begin
    CXObjCDeclQualifier_None = 0
    CXObjCDeclQualifier_In = 1
    CXObjCDeclQualifier_Inout = 2
    CXObjCDeclQualifier_Out = 4
    CXObjCDeclQualifier_Bycopy = 8
    CXObjCDeclQualifier_Byref = 16
    CXObjCDeclQualifier_Oneway = 32
end

const CXModule = Ptr{Cvoid}

@cenum CXNameRefFlags::UInt32 begin
    CXNameRange_WantQualifier = 1
    CXNameRange_WantTemplateArgs = 2
    CXNameRange_WantSinglePiece = 4
end

@cenum CXTokenKind::UInt32 begin
    CXToken_Punctuation = 0
    CXToken_Keyword = 1
    CXToken_Identifier = 2
    CXToken_Literal = 3
    CXToken_Comment = 4
end

struct CXToken
    int_data::NTuple{4, UInt32}
    ptr_data::Ptr{Cvoid}
end

const CXCompletionString = Ptr{Cvoid}

struct CXCompletionResult
    CursorKind::CXCursorKind
    CompletionString::CXCompletionString
end

@cenum CXCompletionChunkKind::UInt32 begin
    CXCompletionChunk_Optional = 0
    CXCompletionChunk_TypedText = 1
    CXCompletionChunk_Text = 2
    CXCompletionChunk_Placeholder = 3
    CXCompletionChunk_Informative = 4
    CXCompletionChunk_CurrentParameter = 5
    CXCompletionChunk_LeftParen = 6
    CXCompletionChunk_RightParen = 7
    CXCompletionChunk_LeftBracket = 8
    CXCompletionChunk_RightBracket = 9
    CXCompletionChunk_LeftBrace = 10
    CXCompletionChunk_RightBrace = 11
    CXCompletionChunk_LeftAngle = 12
    CXCompletionChunk_RightAngle = 13
    CXCompletionChunk_Comma = 14
    CXCompletionChunk_ResultType = 15
    CXCompletionChunk_Colon = 16
    CXCompletionChunk_SemiColon = 17
    CXCompletionChunk_Equal = 18
    CXCompletionChunk_HorizontalSpace = 19
    CXCompletionChunk_VerticalSpace = 20
end

struct CXCodeCompleteResults
    Results::Ptr{CXCompletionResult}
    NumResults::UInt32
end

@cenum CXCodeComplete_Flags::UInt32 begin
    CXCodeComplete_IncludeMacros = 1
    CXCodeComplete_IncludeCodePatterns = 2
    CXCodeComplete_IncludeBriefComments = 4
    CXCodeComplete_SkipPreamble = 8
    CXCodeComplete_IncludeCompletionsWithFixIts = 16
end

@cenum CXCompletionContext::UInt32 begin
    CXCompletionContext_Unexposed = 0
    CXCompletionContext_AnyType = 1
    CXCompletionContext_AnyValue = 2
    CXCompletionContext_ObjCObjectValue = 4
    CXCompletionContext_ObjCSelectorValue = 8
    CXCompletionContext_CXXClassTypeValue = 16
    CXCompletionContext_DotMemberAccess = 32
    CXCompletionContext_ArrowMemberAccess = 64
    CXCompletionContext_ObjCPropertyAccess = 128
    CXCompletionContext_EnumTag = 256
    CXCompletionContext_UnionTag = 512
    CXCompletionContext_StructTag = 1024
    CXCompletionContext_ClassTag = 2048
    CXCompletionContext_Namespace = 4096
    CXCompletionContext_NestedNameSpecifier = 8192
    CXCompletionContext_ObjCInterface = 16384
    CXCompletionContext_ObjCProtocol = 32768
    CXCompletionContext_ObjCCategory = 65536
    CXCompletionContext_ObjCInstanceMessage = 131072
    CXCompletionContext_ObjCClassMessage = 262144
    CXCompletionContext_ObjCSelectorName = 524288
    CXCompletionContext_MacroName = 1048576
    CXCompletionContext_NaturalLanguage = 2097152
    CXCompletionContext_IncludedFile = 4194304
    CXCompletionContext_Unknown = 8388607
end

const CXInclusionVisitor = Ptr{Cvoid}

@cenum CXEvalResultKind::UInt32 begin
    CXEval_Int = 1
    CXEval_Float = 2
    CXEval_ObjCStrLiteral = 3
    CXEval_StrLiteral = 4
    CXEval_CFStr = 5
    CXEval_Other = 6
    CXEval_UnExposed = 0
end

const CXEvalResult = Ptr{Cvoid}
const CXRemapping = Ptr{Cvoid}

@cenum CXVisitorResult::UInt32 begin
    CXVisit_Break = 0
    CXVisit_Continue = 1
end

struct CXCursorAndRangeVisitor
    context::Ptr{Cvoid}
    visit::Ptr{Cvoid}
end

@cenum CXResult::UInt32 begin
    CXResult_Success = 0
    CXResult_Invalid = 1
    CXResult_VisitBreak = 2
end

const CXCursorAndRangeVisitorBlock = Cvoid
const CXIdxClientFile = Ptr{Cvoid}
const CXIdxClientEntity = Ptr{Cvoid}
const CXIdxClientContainer = Ptr{Cvoid}
const CXIdxClientASTFile = Ptr{Cvoid}

struct CXIdxLoc
    ptr_data::NTuple{2, Ptr{Cvoid}}
    int_data::UInt32
end

struct CXIdxIncludedFileInfo
    hashLoc::CXIdxLoc
    filename::Cstring
    file::CXFile
    isImport::Cint
    isAngled::Cint
    isModuleImport::Cint
end

struct CXIdxImportedASTFileInfo
    file::CXFile
    _module::CXModule
    loc::CXIdxLoc
    isImplicit::Cint
end

@cenum CXIdxEntityKind::UInt32 begin
    CXIdxEntity_Unexposed = 0
    CXIdxEntity_Typedef = 1
    CXIdxEntity_Function = 2
    CXIdxEntity_Variable = 3
    CXIdxEntity_Field = 4
    CXIdxEntity_EnumConstant = 5
    CXIdxEntity_ObjCClass = 6
    CXIdxEntity_ObjCProtocol = 7
    CXIdxEntity_ObjCCategory = 8
    CXIdxEntity_ObjCInstanceMethod = 9
    CXIdxEntity_ObjCClassMethod = 10
    CXIdxEntity_ObjCProperty = 11
    CXIdxEntity_ObjCIvar = 12
    CXIdxEntity_Enum = 13
    CXIdxEntity_Struct = 14
    CXIdxEntity_Union = 15
    CXIdxEntity_CXXClass = 16
    CXIdxEntity_CXXNamespace = 17
    CXIdxEntity_CXXNamespaceAlias = 18
    CXIdxEntity_CXXStaticVariable = 19
    CXIdxEntity_CXXStaticMethod = 20
    CXIdxEntity_CXXInstanceMethod = 21
    CXIdxEntity_CXXConstructor = 22
    CXIdxEntity_CXXDestructor = 23
    CXIdxEntity_CXXConversionFunction = 24
    CXIdxEntity_CXXTypeAlias = 25
    CXIdxEntity_CXXInterface = 26
end

@cenum CXIdxEntityLanguage::UInt32 begin
    CXIdxEntityLang_None = 0
    CXIdxEntityLang_C = 1
    CXIdxEntityLang_ObjC = 2
    CXIdxEntityLang_CXX = 3
    CXIdxEntityLang_Swift = 4
end

@cenum CXIdxEntityCXXTemplateKind::UInt32 begin
    CXIdxEntity_NonTemplate = 0
    CXIdxEntity_Template = 1
    CXIdxEntity_TemplatePartialSpecialization = 2
    CXIdxEntity_TemplateSpecialization = 3
end

@cenum CXIdxAttrKind::UInt32 begin
    CXIdxAttr_Unexposed = 0
    CXIdxAttr_IBAction = 1
    CXIdxAttr_IBOutlet = 2
    CXIdxAttr_IBOutletCollection = 3
end

struct CXIdxAttrInfo
    kind::CXIdxAttrKind
    cursor::CXCursor
    loc::CXIdxLoc
end

struct CXIdxEntityInfo
    kind::CXIdxEntityKind
    templateKind::CXIdxEntityCXXTemplateKind
    lang::CXIdxEntityLanguage
    name::Cstring
    USR::Cstring
    cursor::CXCursor
    attributes::Ptr{Ptr{CXIdxAttrInfo}}
    numAttributes::UInt32
end

struct CXIdxContainerInfo
    cursor::CXCursor
end

struct CXIdxIBOutletCollectionAttrInfo
    attrInfo::Ptr{CXIdxAttrInfo}
    objcClass::Ptr{CXIdxEntityInfo}
    classCursor::CXCursor
    classLoc::CXIdxLoc
end

@cenum CXIdxDeclInfoFlags::UInt32 begin
    CXIdxDeclFlag_Skipped = 1
end

struct CXIdxDeclInfo
    entityInfo::Ptr{CXIdxEntityInfo}
    cursor::CXCursor
    loc::CXIdxLoc
    semanticContainer::Ptr{CXIdxContainerInfo}
    lexicalContainer::Ptr{CXIdxContainerInfo}
    isRedeclaration::Cint
    isDefinition::Cint
    isContainer::Cint
    declAsContainer::Ptr{CXIdxContainerInfo}
    isImplicit::Cint
    attributes::Ptr{Ptr{CXIdxAttrInfo}}
    numAttributes::UInt32
    flags::UInt32
end

@cenum CXIdxObjCContainerKind::UInt32 begin
    CXIdxObjCContainer_ForwardRef = 0
    CXIdxObjCContainer_Interface = 1
    CXIdxObjCContainer_Implementation = 2
end

struct CXIdxObjCContainerDeclInfo
    declInfo::Ptr{CXIdxDeclInfo}
    kind::CXIdxObjCContainerKind
end

struct CXIdxBaseClassInfo
    base::Ptr{CXIdxEntityInfo}
    cursor::CXCursor
    loc::CXIdxLoc
end

struct CXIdxObjCProtocolRefInfo
    protocol::Ptr{CXIdxEntityInfo}
    cursor::CXCursor
    loc::CXIdxLoc
end

struct CXIdxObjCProtocolRefListInfo
    protocols::Ptr{Ptr{CXIdxObjCProtocolRefInfo}}
    numProtocols::UInt32
end

struct CXIdxObjCInterfaceDeclInfo
    containerInfo::Ptr{CXIdxObjCContainerDeclInfo}
    superInfo::Ptr{CXIdxBaseClassInfo}
    protocols::Ptr{CXIdxObjCProtocolRefListInfo}
end

struct CXIdxObjCCategoryDeclInfo
    containerInfo::Ptr{CXIdxObjCContainerDeclInfo}
    objcClass::Ptr{CXIdxEntityInfo}
    classCursor::CXCursor
    classLoc::CXIdxLoc
    protocols::Ptr{CXIdxObjCProtocolRefListInfo}
end

struct CXIdxObjCPropertyDeclInfo
    declInfo::Ptr{CXIdxDeclInfo}
    getter::Ptr{CXIdxEntityInfo}
    setter::Ptr{CXIdxEntityInfo}
end

struct CXIdxCXXClassDeclInfo
    declInfo::Ptr{CXIdxDeclInfo}
    bases::Ptr{Ptr{CXIdxBaseClassInfo}}
    numBases::UInt32
end

@cenum CXIdxEntityRefKind::UInt32 begin
    CXIdxEntityRef_Direct = 1
    CXIdxEntityRef_Implicit = 2
end

@cenum CXSymbolRole::UInt32 begin
    CXSymbolRole_None = 0
    CXSymbolRole_Declaration = 1
    CXSymbolRole_Definition = 2
    CXSymbolRole_Reference = 4
    CXSymbolRole_Read = 8
    CXSymbolRole_Write = 16
    CXSymbolRole_Call = 32
    CXSymbolRole_Dynamic = 64
    CXSymbolRole_AddressOf = 128
    CXSymbolRole_Implicit = 256
end

struct CXIdxEntityRefInfo
    kind::CXIdxEntityRefKind
    cursor::CXCursor
    loc::CXIdxLoc
    referencedEntity::Ptr{CXIdxEntityInfo}
    parentEntity::Ptr{CXIdxEntityInfo}
    container::Ptr{CXIdxContainerInfo}
    role::CXSymbolRole
end

struct IndexerCallbacks
    abortQuery::Ptr{Cvoid}
    diagnostic::Ptr{Cvoid}
    enteredMainFile::Ptr{Cvoid}
    ppIncludedFile::Ptr{Cvoid}
    importedASTFile::Ptr{Cvoid}
    startedTranslationUnit::Ptr{Cvoid}
    indexDeclaration::Ptr{Cvoid}
    indexEntityReference::Ptr{Cvoid}
end

const CXIndexAction = Ptr{Cvoid}

@cenum CXIndexOptFlags::UInt32 begin
    CXIndexOpt_None = 0
    CXIndexOpt_SuppressRedundantRefs = 1
    CXIndexOpt_IndexFunctionLocalSymbols = 2
    CXIndexOpt_IndexImplicitTemplateInstantiations = 4
    CXIndexOpt_SuppressWarnings = 8
    CXIndexOpt_SkipParsedBodiesInSession = 16
end

const CXFieldVisitor = Ptr{Cvoid}

# Skipping MacroDefinition: CINDEX_DEPRECATED __attribute__ ( ( deprecated ) )


text:
@testset "OU" begin
    θ₀ = [2.0,0.4]
    ω = 1.1
    τ = 2.0
    @testset "sdf" begin
        @testset "Gradient" begin
            @test approx_gradient_uni(θ -> sdf(OU(θ), ω), θ₀)      ≈ grad_sdf(OU(θ₀), ω)
        end
        @testset "Hessian" begin
            @test approx_hessian_uni( θ -> grad_sdf(OU(θ), ω), θ₀) ≈ hess_sdf(OU(θ₀), ω)
        end
    end
    @testset "acv" begin
        @testset "Gradient" begin
            @test approx_gradient_uni(θ -> acv(OU(θ), τ), θ₀)      ≈ grad_acv(OU(θ₀), τ)
        end
        @testset "Hessian" begin
            @test approx_hessian_uni( θ -> grad_acv(OU(θ), τ), θ₀) ≈ hess_acv(OU(θ₀), τ)
        end
    end
    @testset "Error handling" begin
        @test_throws ArgumentError OU(-1.0,1.0)
        @test_throws ArgumentError OU(1.0,-1.0)
        @test_throws ArgumentError OU(ones(1))
        @test_throws ArgumentError OU(ones(3))
    end
end


text:
# Triangular decompostion with Partial Pivoting

p = collect (1:m)                                       # initialization of the permutation vector

for k=1:m
    j = indmax(abs(A[k:m,k])); j = k-1+j                # pivot search
    p[[k,j]] = p[[j,k]]; A[[k,j],:] = A[[j,k],:]        # row swap
    A[k+1:m,k] /= A[k,k]
    A[k+1:m,k+1:m]  -= A[k+1:m,k]*A[k:k,k+1:m]
end

max_stars_repo_path: Code/Numerical Analysis & Machine Learning/Numerical Linear Algebra/TriangularDecomposition.jl

max_stars_repo_name: BambooFlower/Math-Scripts

max_issues_repo_name: BambooFlower/Math-Scripts

max_forks_repo_name: BambooFlower/Math-Scripts


text:
using HorizonSideRobots
include("../basics.jl")

md"""
            task_5 c перегородками
"""

 """Решение задачи 18"""
 function solve_18!(r)
    visited = Set()
    (M, N), (I, J) = get_field_size_and_position!(r)
    mark_some_cells_with_dfs!(r, visited, (I, J), false, [(M, N), (1, N), (M, 1), (1, 1)])

    show(r)
end


text:
module Transformations

export Transformation, ZScore, RescaledZScore, SpaceIndices, TimeIndices

using Statistics

using Oceananigans.Fields: interior
using Oceananigans.OutputReaders: FieldTimeSeries

#####
##### Identity normalization
#####

struct Transformation{T, X, N}
    time :: T
    space :: X
    normalization :: N
end

"""
    Transformation(; time=nothing, space=nothing, normalization=nothing)

Return a transformation that is applied on the observation. Examples include slicing
the data or multiplying with weight factors to make the loss function putting more
weight in particular regions of the domain or particular times. Also, we can denote
a normalization procedure applied to the data *after* the space- and time-
transformations.

Slicing is prescribed as `SpaceIndices` and `TimeIndices`. For example,

```julia
Transformation(time = TimeIndices(4:10))
```

only keeps time instances 4 to 10 from the observations. Similarly,

```julia
Transformation(space = SpaceIndices(x=:, y=1:10, z=2:2:20))
```

does not affect the `x` dimension of the data, but slices the observations
in `y` and `z` as prescribed.

Keyword Arguments
=================

- `time`: The time transformation either as a `TimeIndices` or as an `AbstractVector` of
  weights of same size as `observations.times`. If `nothing` is given, then, by default,
  the transformation ignores the first snapshot (initial state). (Default: `nothing`)

- `space`: The space trasformation either as a `SpaceIndices` or as an `AbstractArray` of
  weights of same size as a snapshot of the observations. (Default: `nothing`)

- `normalization`: The normalization that is applied to the data after space and time
  transformations have been applied first. (Default: `nothing`)
"""
Transformation(; time=nothing, space=nothing, normalization=nothing) =
    Transformation(time, space, normalization)

compute_normalization(::Nothing, transformation, fts) = nothing

function compute_transformation(transformation, field_time_series)
    time = compute_time_transformation(transformation.time, field_time_series)
    space = compute_space_transformation(transformation.space, field_time_series)
    normalization = compute_normalization(transformation.normalization, transformation, field_time_series)

    return Transformation(time, space, normalization)
end

#####
##### Time transformations
#####

# Convert Integers to UnitRange
int_to_range(t) = t
int_to_range(t::Int) = UnitRange(t, t)

time_transform(::Nothing, data) = data

struct TimeIndices{T}
    t :: T

    function TimeIndices(t)
        t = int_to_range(t)
        T = typeof(t)

        return new{T}(t)
    end
end

TimeIndices(; t) = TimeIndices(t)

"""
    compute_time_transformation(user_time_transformation, fts)

Compute a time transformation for the field time series `fts`
given `user_time_transformation`.

By default, if `user_time_transformation isa nothing`, then we include all time instances
except the initial condition.
"""
compute_time_transformation(::Nothing, fts) = TimeIndices(2:length(fts.times))
compute_time_transformation(indices::TimeIndices, fts) = indices

time_transform(indices::TimeIndices, data) = data[:, :, :, indices.t]

function time_transform(weights::AbstractVector, data)
    weights = reshape(weights, 1, 1, 1, length(weights))
    return data .* weights
end

compute_time_transformation(weights::AbstractVector, fts) = weights

#####
##### Space transformations
#####

compute_space_transformation(::Nothing, fts) = nothing
space_transform(::Nothing, data) = data

struct SpaceIndices{X, Y, Z}
    x :: X
    y :: Y
    z :: Z
end

function SpaceIndices(; x=:, y=:, z=:)
    x isa Colon || throw(ArgumentError("Cannot transform in x because x is reserved for the ensemble dimension."))
    x = int_to_range(x)
    y = int_to_range(y)
    z = int_to_range(z)
    return SpaceIndices(x, y, z)
end

compute_space_transformation(indices::SpaceIndices, fts) = indices
space_transform(indices::SpaceIndices, data) = data[indices.x, indices.y, indices.z, :]

function space_transform(weights::AbstractArray, data)
    Nx, Ny, Nz = size(weights)
    weights = reshape(weights, Nx, Ny, Nz, 1)
    return data .* weights
end

compute_space_transformation(weights::AbstractArray, fts) = weights

#####
##### Normalizations
#####

abstract type AbstractNormalization end

# Convenience is queen
function compute_transformation(normalization::Union{Nothing, AbstractNormalization}, field_time_series)
    transformation = Transformation(; normalization)
    return compute_transformation(transformation, field_time_series)
end

normalize!(data, ::Nothing) = data

#####
##### ZScore, kinda like Normal...
#####

struct ZScore{T} <: AbstractNormalization
    μ :: T
    σ :: T
end

ZScore() = ZScore(nothing, nothing) # stub for user-interface

"""
    ZScore(data)

Return the `ZScore` normalization of a `FieldTimeSeries` after computing
its mean and its variance.
"""
function ZScore(data)
    @assert size(data, 1) == 1 # we're going to assume this
    @assert ndims(data) == 2 # we're also going to assume this

    data = dropdims(data, dims=1)
    μ = mean(data)
    σ = sqrt(cov(data; corrected=false))

    if σ == 0
        @warn "Your data has zero variance --- just sayin'! I'm setting ZScore σ = 1."
        σ = one(μ)
    end

    return ZScore(μ, σ)
end

compute_normalization(zscore::ZScore, fts) = zscore

"""Compute ZScore on time- and space-transformed field time series data."""
function compute_normalization(::ZScore{Nothing}, transformation, field_time_series)
    time_space_transformation = Transformation(transformation.time,
                                               transformation.space,
                                               nothing)

    data = transform_field_time_series(time_space_transformation, field_time_series)

    return ZScore(data)
end

function normalize!(data, normalization::ZScore)
    μ, σ = normalization.μ, normalization.σ
    @. data = (data - μ) / σ
    return nothing
end

#####
##### Like ZScore, but maybe less important
#####

struct RescaledZScore{T, Z} <: AbstractNormalization
    scale :: T
    zscore :: Z
end

RescaledZScore(scale) = RescaledZScore(scale, nothing)

compute_normalization(r::RescaledZScore, transformation, fts) =
    RescaledZScore(r.scale, compute_normalization(r.zscore, transformation, fts))

function normalize!(data, normalization::RescaledZScore)
    normalize!(data, normalization.zscore)
    @. data *= normalization.scale
    return nothing
end

#####
##### Transform it!
#####

function transform_field_time_series(transformation::Transformation,
                                     field_time_series::FieldTimeSeries)

    copied_data = Array(interior(field_time_series))
    time_transformed_data = time_transform(transformation.time, copied_data)
    time_space_transformed_data = space_transform(transformation.space, time_transformed_data)
    normalize!(time_space_transformed_data, transformation.normalization)

    # Reshape data to 2D array with size (Nx, :)
    Nens = size(time_space_transformed_data, 1)
    Ndata = size(time_space_transformed_data)[2:4]
    reshaped_data = reshape(time_space_transformed_data, Nens, prod(Ndata))

    return reshaped_data
end

end # module


text:
type Node
  item  ::  Any
  next  ::  Any
  function Node(item)
    new(item, nothing)
  end
end

type LinkedList
  head  ::  Any
  function LinkedList()
    new(nothing)
  end
end

function append_to_tail!(ll :: LinkedList, item)
  if ll.head == nothing
    ll.head = Node(item)
  else
    curr :: Node = ll.head
    tail :: Node = Node(item)
    while curr.next != nothing curr = curr.next; end
    curr.next = tail
  end
end

function delete_node!(ll :: LinkedList, item)
  @assert ll.head != nothing "[delete_node] cannot delete node from an empty LinkedList"

  curr :: Node = ll.head

  if curr.item == item ll.head = curr.next; end

  while curr.next != nothing
    if curr.next.item == item curr.next = curr.next.next; break; end
    curr = curr.next
  end
end

using Base: Test

ll = LinkedList()
append_to_tail!(ll, 1)
append_to_tail!(ll, 2)
append_to_tail!(ll, 3)
delete_node!(ll, 2)
delete_node!(ll, 1)
delete_node!(ll, 3)
@test ll.head == nothing

max_stars_repo_name: Kiandr/crackingcodinginterview

max_issues_repo_name: Kiandr/crackingcodinginterview

max_forks_repo_name: Kiandr/crackingcodinginterview