text:
# CauchyWeight enriches a TensorSpace with a singular diagonal

export CauchyWeight

struct CauchyWeight{O,SV,DD,RR} <: AbstractProductSpace{SV,DD,RR}
    space::TensorSpace{SV,DD,RR}
end

CauchyWeight(space::TensorSpace{SV,DD,RR},O) where {SV,DD,RR} = CauchyWeight{O,SV,DD,RR}(space)

order(C::CauchyWeight{O}) where {O} = O
domain(C::CauchyWeight) = domain(C.space)
ncomponents(C::CauchyWeight) = ncomponents(C.space)
component(C::CauchyWeight, k::Integer) = CauchyWeight(component(C.space,k),order(C))
ApproxFun.columnspace(C::CauchyWeight, _) = C[1]
component(C::CauchyWeight{O,Tuple{PWS1,PWS2}},i,j) where {O,PWS1<:PiecewiseSpace,PWS2<:PiecewiseSpace} =
    CauchyWeight(component(C.space,i,j),O)

factor(s::CauchyWeight,k) = factor(s.space,k) # TODO: Why is this a meaningful definition?
Base.transpose(C::CauchyWeight{O}) where {O} = CauchyWeight(transpose(C.space),O)

cauchyweight(O,x,y) = O == 0 ? logabs(y-x)/π : (y-x)^(-O)/π
cauchyweight(C::CauchyWeight{O},x,y) where {O} = cauchyweight(O,tocanonical(C,x,y)...)

## BivariateFun constructors in a CauchyWeight space

## TODO: for different domains, there should not be (x,y)->f(x,y)*cauchyweight(O,x,y)
## This will change for v0.0.2 with the switch to ChebyshevDirichlet{1,1} bases

for Func in (:ProductFun,:convolutionProductFun)
    @eval begin
        function $Func(f::DFunction,cwsp::CauchyWeight{O};kwds...) where O
            F = domain(factor(cwsp.space,1)) == domain(factor(cwsp.space,2)) ?
                $Func(f,factor(cwsp.space,1),factor(cwsp.space,2);kwds...) :
                $Func((x,y)->f(x,y)*cauchyweight(O,x,y),factor(cwsp.space,1),factor(cwsp.space,2);kwds...)
            return ProductFun(F.coefficients,cwsp)
        end
    end
end

function LowRankFun(f::DFunction,cwsp::CauchyWeight{O};retmax::Bool=false,kwds...) where O
    if retmax
        F,maxabsf = domain(factor(cwsp.space,1)) == domain(factor(cwsp.space,2)) ?
            LowRankFun(f,factor(cwsp.space,1),factor(cwsp.space,2);retmax=retmax,kwds...) :
            LowRankFun((x,y)->f(x,y)*cauchyweight(O,x,y),factor(cwsp.space,1),factor(cwsp.space,2);retmax=retmax,kwds...)
        LowRankFun(F.A,F.B,cwsp),maxabsf
    else
        F = domain(factor(cwsp.space,1)) == domain(factor(cwsp.space,2)) ?
            LowRankFun(f,factor(cwsp.space,1),factor(cwsp.space,2);kwds...) :
            LowRankFun((x,y)->f(x,y)*cauchyweight(O,x,y),factor(cwsp.space,1),factor(cwsp.space,2);kwds...)
        LowRankFun(F.A,F.B,cwsp)
    end
end

## Definite (Line) Integration over BivariateFuns in a CauchyWeight space

## TODO: for different domains, should be OffOp instead of ⨍
## This will change for v0.0.2 with the switch to ChebyshevDirichlet{1,1} bases

for (Func,Op) in ((:(ApproxFun.DefiniteIntegral),:Hilbert),
                    (:(ApproxFun.DefiniteLineIntegral),:SingularIntegral))
    @eval begin
        function Base.getindex(⨍::$Func,f::ProductFun{S,V,CauchyWeight{O,Tuple{S,V},T2,DD},T}) where {S,V,O,T,T2,DD}
            if domain(factor(f.space.space,1)) == domain(factor(f.space.space,2))
                $Op(domainspace(⨍),O)[f]
            else
                ⨍[ProductFun(f.coefficients,f.space.space)]
            end
        end
        function Base.getindex(⨍::$Func,f::LowRankFun{S,M,CauchyWeight{O,Tuple{S,M},T2,DD},T}) where {S,M,O,T,T2,DD}
            if domain(factor(f.space.space,1)) == domain(factor(f.space.space,2))
                $Op(domainspace(⨍),O)[f]
            else
                ⨍[LowRankFun(f.A,f.B,f.space.space)]
            end
        end
    end
end

## Evaluation of bivariate functions in a CauchyWeight space

evaluate(f::ProductFun{S,V,CauchyWeight{O,Tuple{S,V},T1,DD},T2},x::AbstractRange,y::AbstractRange) where {S<:UnivariateSpace,V<:UnivariateSpace,O,T1,T2,DD} =
    evaluate(f,[x],[y])
evaluate(f::ProductFun{S,V,CauchyWeight{O,Tuple{S,V},T1,DD},T2},x,y) where {S<:UnivariateSpace,V<:UnivariateSpace,O,T1,T2,DD} =
    evaluate(ProductFun(f.coefficients,space(f).space),x,y).*cauchyweight(space(f),x,y)

+(F::ProductFun{S,V,CauchyWeight{O},T1},G::ProductFun{S,V,CauchyWeight{O},T2}) where {S<:UnivariateSpace,V<:UnivariateSpace,O,T1,T2} =
    ProductFun(ProductFun(F.coefficients,F.space.space)+ProductFun(G.coefficients,G.space.space),G.space)
-(F::ProductFun{S,V,CauchyWeight{O},T1},G::ProductFun{S,V,CauchyWeight{O},T2}) where {S<:UnivariateSpace,V<:UnivariateSpace,O,T1,T2} =
    ProductFun(ProductFun(F.coefficients,F.space.space)-ProductFun(G.coefficients,G.space.space),G.space)

evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},::Colon,::Colon) where {S<:Space,M<:Space,O,SV,TT,T<:Number,DD} =
    error("Not callable.")
evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},x::Number,::Colon) where {S<:Space,M<:Space,O,SV,TT,T<:Number,DD} =
    error("Not callable.")
evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},x::Vector{TTT},::Colon) where {S<:Space,M<:Space,O,SV,TT,T<:Number,TTT<:Number,DD} =
    error("Not callable.")
evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},::Colon,y::Number) where {S<:Space,M<:Space,O,SV,TT,T<:Number,DD} =
    error("Not callable.")
evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},::Colon,y::Vector{TTT}) where {S<:Space,M<:Space,O,SV,TT,T<:Number,TTT<:Number,DD} =
    error("Not callable.")
evaluate(f::LowRankFun{S,M,CauchyWeight{O,SV,TT,DD},T},x,y) where {S<:Space,M<:Space,O,SV,TT,T<:Number,DD} =
    evaluate(f.A,f.B,x,y).*cauchyweight(space(f),x,y)

+(F::LowRankFun{S,M,CauchyWeight{O},T1},G::LowRankFun{S,M,CauchyWeight{O},T2}) where {S<:Space,M<:Space,O,T1<:Number,T2<:Number} =
    LowRankFun([F.A,G.A],[F.B,G.B],F.space)
-(F::LowRankFun{S,M,CauchyWeight{O},T1},G::LowRankFun{S,M,CauchyWeight{O},T2}) where {S<:Space,M<:Space,O,T1<:Number,T2<:Number} =
    LowRankFun([F.A,-G.A],[F.B,G.B],F.space)


text:
function normAm(A,m)::Real
    #NORMAM   Estimate of 1-norm of power of matrix.
    #   NORMAM(A,m) estimates norm(A^m,1).
    #   If A has nonnegative elements the estimate is exact.
    #   [C,MV] = NORMAM(A,m) returns the estimate C and the number MV of
    #   matrix-vector products computed involving A or A^*.

    #   Reference: A. H. Al-Mohy and N. J. Higham, A New Scaling and Squaring
    #   Algorithm for the Matrix Exponential, SIAM J. Matrix Anal. Appl. 31(3):
    #   970-989, 2009.

    #   Awad H. Al-Mohy and Nicholas J. Higham, September 7, 2010.

    t = 2; # Number of columns used by NORMEST1.

    n = size(A, 1);
    if hasmethod(opnorm, Tuple{typeof(A), typeof(1)})
        if eltype(A) <: Real
            if sum(A .< 0) == 0 # for positive matrices only
                e = ones(n,1)
                f = similar(e)
                for j=1:m
                    mul!(f, A, e)
                    copyto!(e, f)
                end
                return norm(e, Inf)
            end
        end
    end
    return norm1est(A, m, t)
end

ext: jl


text:
####### Scalogram estimator #######

"""
Variance function of the empirical scalogram of B-Spline wavelet
"""
function bspline_scalogram_variance(H::Real, vm::Integer, sclrng::AbstractVector{<:Integer}, N::Integer)
    V = zeros(Float64, length(sclrng))

    for (j, s) in enumerate(sclrng)
        # B-Spline filter: extra 1/sqrt(s) factor is due to the implementation of DCWT
        filter = intscale_bspline_filter(s, vm)/sqrt(s)
        proc = FractionalWaveletNoise(H, filter)
        V[j] = autocov(proc, 0)^2 + sum((1-i/N) * autocov(proc, i)^2 for i=0:N-1)
    end
    return 4/N * V
end

"""

B-Spline scalogram estimator for Hurst exponent and volatility.

# Args
- X: matrix of wavelet coefficients. Each row corresponds to a scale.
- sclrng: scale of wavelet transform. Each number in `sclrng` corresponds to one row in the matrix X.
- v: vanishing moments of the wavelet
- p: power of the scalogram
"""
function bspline_scalogram_estim(X::AbstractMatrix{<:Real}, sclrng::AbstractVector{<:Integer}, vm::Integer; pow::Real=2., method::Symbol=:optim, cmode::Symbol=:causal, reweight::Bool=true)
    # remove columns containing NaN
    idx = findall(vec(.!any(isnan.(X), dims=1)))
    X = X[:,idx] # view(X,:,idx)

    if length(X) == 0
        return (hurst=NaN, σ=NaN, η=NaN, residual=NaN, vars=nothing, optimizer=nothing)
    else
        @assert length(sclrng) == size(X,1) > 1  "Dimension mismatch."
        @assert any(sclrng .% 2 .== 0) && any(sclrng .> 0)  "All scales must be positive even number."
        @assert pow>0  "Moment must be positive."

        xp = pow * log.(sclrng)
        μX = mean(X, dims=2)
        yp = vec(log.(mean(abs.(X.-μX).^pow, dims=2)))
        # hurst, η, res = NaN, NaN, NaN

        # compute the weighting vector:
        # Run first an estimation of Hurst by linear regression, then use this estimate to compute the weighting vector.
        # Note that the reweighting scheme is exact only for pow=2.
        dg = DataFrames.DataFrame(xvar=xp, yvar=yp)
        opm = GLM.lm(@GLM.formula(yvar~xvar), dg)
        coef = GLM.coef(opm)
        η, hurst = coef[1], coef[2] - 1/2  # intercept and slope
        res = GLM.deviance(opm)  # residual

        ws =  if reweight
            bspline_scalogram_variance(0 < hurst < 1 ? hurst : 0.5, vm, sclrng, size(X,2)) .^ (-1)
        else
            ones(length(sclrng))  # uniform weight
        end
        ws ./= sum(ws)

        # estimation of H and η
        if method == :optim
            yc = yp .- mean(yp)
            xc = xp .- mean(xp)

            # original implentation
            # func = h -> sum(ws .* abs.(yc - h*xc).^1)
            func = h -> sum(ws .* (yc - h*xc).^2)
            # Gradient-free constrained optimization
            ɛ = 1e-2  # search hurst in the interval 0.5+[ɛ, 1-ɛ]
            opm = Optim.optimize(func, 0.5+ɛ, 1.5-ɛ, Optim.Brent())
            hurst = Optim.minimizer(opm)[1] - 1/2
            η = mean(yp - (hurst+1/2)*xp)

            # # implementation of Knut with weight
            # ɛ = 1e-2  # search hurst in the interval 0.5+[ɛ, 1-ɛ]
            # wv1 = 1 ./ (sclrng)
            # func = h -> sum(wv1 .* abs.(yc - h*xc).^2)
            # # func = h -> sum(wv1 .* (yc - h*xc).^2)
            # opm = Optim.optimize(func, 0.5+ε, 1.5-ε, Optim.Brent())
            # hurst1 = Optim.minimizer(opm)[1] - 1/2
            # wv2 = 1 ./ (sclrng .^ 3)
            # func = h -> sum(wv2 .* abs.(yc - h*xc).^2)
            # # func = h -> sum(wv2 .* (yc - h*xc).^2)
            # opm = Optim.optimize(func, 0.5+ε, 1.5-ε, Optim.Brent())
            # hurst2 = Optim.minimizer(opm)[1] - 1/2
            # hurst = max(hurst1, hurst2)
            # # println("Hurst1=$(hurst1), Hurst2=$(hurst2)")
            # η = mean(yp - (hurst+1/2)*xp)

            res = sqrt(opm.minimum / length(xp) / var(yp))
        elseif method == :lm  # using GLM package
            dg = DataFrames.DataFrame(xvar=xp, yvar=yp)
            opm = GLM.glm(@GLM.formula(yvar~xvar), dg, GLM.Normal(), GLM.IdentityLink(), wts=sqrt.(ws))
            # opm = GLM.lm(@GLM.formula(yvar~xvar), dg)
            coef = GLM.coef(opm)
            η, hurst = coef[1], coef[2] - 1/2
            res = sqrt(GLM.deviance(opm) / var(yp)) # / length(xp)

        # elseif method == :irls
        #     coef = IRLS(yp, xp, p; maxiter=10^4, tol=10^-4)
        #     hurst = coef[1][1]-1/2
        #     η = coef[2][1]  # returned value is a scalar in a vector form
        #     opm = nothing
        else
            error("Unknown method $(method).")
        end

        cp = normal_moment_factor(pow)  # constant factor depending on p
        σ = try
            A = Aψρ_bspline(0, 1, hurst, vm, cmode)  # kwargs: mode=:center
            exp((η - log(cp) - log(A)*pow/2)/pow)
        catch
            NaN
        end

        return (hurst=hurst, σ=σ, η=η, residual=res, vars=(xp,yp), optimizer=opm)
    end
end

"""
# Args
- X: sample path of fBm, e.g. the log-price
- v: vanishing moments
"""
function bspline_scalogram_estim(X::AbstractVector{<:Real}, sclrng::AbstractVector{<:Integer}, vm::Integer; kwargs...)

    # B-Spline wavelet transform
    W, M = cwt_bspline(X, sclrng, vm, :causal)
    # Wt = [view(W, findall(M[:,n]),n) for n=1:size(W,2)]
    # truncation of boundary points
    t1 = findall(prod(M, dims=2))[1][1]
    t2 = findall(prod(M, dims=2))[end][1]
    Wt = W[t1:t2, :]

    # # Covariance matrix
    # lag = 0
    # Σ = cov(Wt[1:end-lag, :], Wt[lag+1:end,:], dims=1);

    return bspline_scalogram_estim(Wt', sclrng, v; kwargs...)
end

const scalogram_estim = bspline_scalogram_estim

max_stars_repo_name: yanncalec/FracFin

max_issues_repo_name: yanncalec/FracFin

max_forks_repo_name: yanncalec/FracFin


text:
export bond_dimension, is_left_normalized, is_right_normalized
export verify_bonds, verify_physical_dims, tensor, rank, physical_dim
export State, dropindices

const State = Union{Vector, NTuple}

abstract type AbstractTensorNetwork{T} end

for (T, N) ∈ ((:PEPSRow, 5), (:MPO, 4), (:MPS, 3))
    AT = Symbol(:Abstract, T)
    @eval begin
        export $AT
        export $T

        abstract type $AT{T} <: AbstractTensorNetwork{T} end

        struct $T{T <: Number} <: $AT{T}
            tensors::Vector{Array{T, $N}}
        end

        # consturctors
        $T(::Type{T}, L::Int) where {T} = $T(Vector{Array{T, $N}}(undef, L))
        $T(L::Int) = $T(Float64, L)

        @inline Base.setindex!(a::$AT, A::AbstractArray{<:Number, $N}, i::Int) = a.tensors[i] = A
        @inline bond_dimension(a::$AT) = maximum(size.(a.tensors, $N))
        Base.hash(a::$T, h::UInt) = hash(a.tensors, h)
        @inline Base.:(==)(a::$T, b::$T) = a.tensors == b.tensors
        @inline Base.:(≈)(a::$T, b::$T)  = a.tensors ≈ b.tensors
        Base.copy(a::$T) = $T(copy(a.tensors))

        @inline Base.eltype(::$AT{T}) where {T} = T
    end
end

@inline Base.getindex(a::AbstractTensorNetwork, i) = getindex(a.tensors, i)
@inline Base.iterate(a::AbstractTensorNetwork) = iterate(a.tensors)
@inline Base.iterate(a::AbstractTensorNetwork, state) = iterate(a.tensors, state)
@inline Base.lastindex(a::AbstractTensorNetwork) = lastindex(a.tensors)
@inline Base.length(a::AbstractTensorNetwork) = length(a.tensors)
@inline Base.size(a::AbstractTensorNetwork) = (length(a.tensors), )
@inline Base.eachindex(a::AbstractTensorNetwork) = eachindex(a.tensors)

@inline LinearAlgebra.rank(ψ::AbstractMPS) = Tuple(size(A, 2) for A ∈ ψ)
@inline physical_dim(ψ::AbstractMPS, i::Int) = size(ψ[i], 2)

@inline MPS(A::AbstractArray) = MPS(A, :right)

@inline function MPS(A::AbstractArray, s::Symbol, Dcut::Int=typemax(Int))
    @assert s ∈ (:left, :right)
    if s == :right
        ψ = _right_sweep(A)
        _left_sweep!(ψ, Dcut)
    else
        ψ = _left_sweep(A)
        _right_sweep!(ψ, Dcut)
    end
    ψ
end

@inline dropindices(ψ::AbstractMPS, i::Int=2) = (dropdims(A, dims=i) for A ∈ ψ)

function MPS(states::Vector{Vector{T}}) where {T <: Number}
    state_arrays = [reshape(copy(v), (1, length(v), 1)) for v ∈ states]
    MPS(state_arrays)
end

function (::Type{T})(ψ::AbstractMPS) where {T <:AbstractMPO}
    _verify_square(ψ)
    T([
        @cast W[x, σ, y, η] |= A[x, (σ, η), y] (σ ∈ 1:isqrt(size(A, 2)))
        for A in ψ
    ])
end

function (::Type{T})(O::AbstractMPO) where {T <:AbstractMPS}
    T([@cast A[x, (σ, η), y] := W[x, σ, y, η] for W in O])
end

function Base.randn(::Type{MPS{T}}, D::Int, rank::Union{Vector, NTuple}) where {T}
    MPS([
        randn(T, 1, first(rank), D),
        randn.(T, D, rank[begin+1:end-1], D)...,
        rand(T, D, last(rank), 1)
    ])
end

function Base.randn(::Type{MPS{T}}, L::Int, D::Int, d::Int) where {T}
    MPS([
        randn(T, 1, d, D), (randn(T, D, d, D) for _ in 2:L-1)..., randn(T, D, d, 1)
    ])
end

Base.randn(::Type{MPS}, args...) = randn(MPS{Float64}, args...)

function Base.randn(::Type{MPO{T}}, L::Int, D::Int, d::Int) where {T}
    MPO(randn(MPS{T}, L, D, d^2))
end

function Base.randn(::Type{MPO{T}}, D::Int, rank::Union{Vector, NTuple}) where {T}
    MPO(randn(MPS{T}, D, rank .^ 2))
end

Base.randn(::Type{MPO}, args...) = randn(MPO{Float64}, args...)

is_left_normalized(ψ::MPS) = all(
    I(size(A, 3)) ≈ @tensor Id[x, y] := conj(A[α, σ, x]) * A[α, σ, y] order = (α, σ) for A ∈ ψ
)

is_right_normalized(ϕ::MPS) = all(
    I(size(B, 1)) ≈ @tensor Id[x, y] := B[x, σ, α] * conj(B[y, σ, α]) order = (α, σ) for B in ϕ
)

function _verify_square(ψ::AbstractMPS)
    dims = physical_dim.(Ref(ψ), eachindex(ψ))
    @assert isqrt.(dims) .^ 2 == dims "Incorrect MPS dimensions"
end

function verify_physical_dims(ψ::AbstractMPS, dims::NTuple)
    for i ∈ eachindex(ψ)
        @assert physical_dim(ψ, i) == dims[i] "Incorrect physical dim at site $(i)."
    end
end

function verify_bonds(ψ::AbstractMPS)
    L = length(ψ)

    @assert size(ψ[1], 1) == 1 "Incorrect size on the left boundary."
    @assert size(ψ[end], 3) == 1 "Incorrect size on the right boundary."

    for i ∈ 1:L-1
        @assert size(ψ[i], 3) == size(ψ[i+1], 1) "Incorrect link between $i and $(i+1)."
    end
end

function Base.show(io::IO, ψ::AbstractTensorNetwork)
    L = length(ψ)
    dims = [size(A) for A ∈ ψ]

    println(io, "Matrix product state on $L sites:")
    _show_sizes(io, dims)
    println(io, "   ")
end

function _show_sizes(io::IO, dims::Vector, sep::String=" x ", Lcut::Int=8)
    L = length(dims)
    if L > Lcut
        for i ∈ 1:Lcut
            print(io, " ", dims[i], sep)
        end
        print(io, " ... × ", dims[end])
    else
        for i ∈ 1:(L-1)
            print(io, dims[i], sep)
        end
        println(io, dims[end])
    end
end


text:
using BioMASS
using Documenter

makedocs(;
    modules=[BioMASS],
    authors="Hiroaki Imoto <himoto@protein.osaka-u.ac.jp>",
    repo="https://github.com/biomass-dev/BioMASS.jl/blob/{commit}{path}#L{line}",
    sitename="BioMASS.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://biomass-dev.github.io/BioMASS.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
        "Getting started with BioMASS.jl" => [
            "Parameter Estimation" => "usage/parameter_estimation.md",
            "Bifurcation Analysis" => "usage/bifurcation_analysis.md",
        ],
        "References" => "references.md"
    ],
)

deploydocs(;
    repo="github.com/biomass-dev/BioMASS.jl",
)


text:
using SpaceTimeFields
using Test

const GROUP = get(ENV, "GROUP", "All")

if GROUP == "All" || GROUP == "SpatialFields"
  include("spatialfields.jl")
end


text:
function solve(a,op,b)
    if op=="+"
        a+b
    elseif op=="-"
        a-b
    elseif op=="/"
        b!=0 ? a÷b : "error"
    elseif op=="*"
        a*b
    else
        "error"
    end
end

a,op,b=split(readline())
a=parse(Int64,a)
b=parse(Int64,b)
println(solve(a,op,b))

max_stars_repo_name: sugitanishi/competitive-programming

max_issues_repo_name: sugitanishi/competitive-programming

max_forks_repo_name: sugitanishi/competitive-programming


text:
insts = OrderedDict()
insts["minimal"] = [
    ((2, 2),),
    ((2, 2), :ExpPSD),
    ((2, 2), :SOCExpPSD),
    ]
insts["fast"] = [
    ((3, 4),),
    ((3, 4), :ExpPSD),
    ((3, 4), :SOCExpPSD),
    ((10, 3),),
    ((5, 3), :ExpPSD),
    ((5, 3), :SOCExpPSD),
    ]
insts["various"] = [
    ((10, 20),),
    ((10, 15), :ExpPSD),
    ((10, 15), :SOCExpPSD),
    ((10, 25),),
    ((10, 20), :ExpPSD),
    ((10, 20), :SOCExpPSD),
    ((10, 30),),
    ]
return (MatrixCompletionJuMP, insts)


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    ClusteringMethod

A method for clustering geospatial data.

Unlike a generic [`PartitionMethod`](@ref), a
clustering method also uses variables in the
data besides the underlying geospatial domain.
"""
abstract type ClusteringMethod <: Meshes.PartitionMethod end

"""
    cluster(data, method; vars=[all])

Cluster geospatial `data` with clustering `method`
using variables `vars` and return geospatial data
with cluster labels. Use all variables by default.

    cluster(data, model; vars=[all])

Alternatively, cluster geospatial `data` with
[`MLJ`](https://github.com/alan-turing-institute/MLJ.jl)
model.
"""
function cluster(data::Data, method; vars=nothing)
  # retrieve data
  tab = values(data)
  dom = domain(data)

  # variables used for clustering
  dvars = Tables.schema(tab).names
  vars  = isnothing(vars) ? dvars : vars
  @assert vars ⊆ dvars "variables not found in geospatial data"

  # view subset of variables
  sel = TableOperations.select(tab, vars...)

  # perform clustering on selection
  _cluster(georef(sel, dom), method)
end

function _cluster(data::Data, method::ClusteringMethod)
  d = domain(data)
  p = partition(data, method)

  # assign cluster labels to samples
  labels = Vector{Int}(undef, nelements(d))
  for (l, inds) in enumerate(indices(p))
    labels[inds] .= l
  end

  # table with cluster labels
  t = (cluster=categorical(labels),)

  georef(t, d)
end

function _cluster(data::Data, model::MI.Model)
  # perform clustering
  table = values(data)
  θ, _, __ = MI.fit(model, 0, table)
  labels = MI.predict(model, θ, table)

  cluster = isprobabilistic(model) ? mode.(labels) : labels

  georef((cluster=cluster,), domain(data))
end

# ----------------
# IMPLEMENTATIONS
# ----------------

include("clustering/slic.jl")
include("clustering/ghc.jl")


text:
# This file is part of Kpax3. License is MIT.

function writeresults(x::KData,
                      state::State,
                      file::String;
                      what::Int=1,
                      verbose::Bool=false)
  dirpath = dirname(file)
  if !isdir(dirpath)
    mkpath(dirpath)
  end

  fp = open("$(file)_partition.csv", "w")
  for i in 1:size(x.data, 2)
    write(fp, "\"$(x.id[i])\",$(state.R[i])\n")
  end
  close(fp)

  write("$(file)_logposterior_value.txt",
        string(state.logpR + state.logpC[1] + state.loglik, "\n"))

  if verbose
    println("Partition has been written to file: $(file)_partition.csv")
    println("Log posterior probability (minus a constant) has been written ",
            "to file: $(file)_logposterior.txt")
  end

  if what >= 2
    writeattributes(x, state, file, verbose)

    if what >= 3
      V = writecvalues(x, state, file, verbose)

      if what >= 4
        writedataset(x, state, file, verbose, V)
      end
    end
  end

  nothing
end

function writeattributes(x::KData,
                         state::State,
                         file::String,
                         verbose::Bool)
  (m, n) = size(x.data)
  M = length(x.ref)

  isuint8 = eltype(x.ref) == UInt8

  polval = if isuint8
              UInt8('.')
            else
              "."
            end

  # attributes
  C = ones(UInt8, state.k, M)

  # column index in x.key
  s = 0

  # column indices in state.C
  t = 1
  b = 1

  # temporary value
  v = 0x01

  for j in 1:M
    if x.ref[j] == polval
      s += 1
      b = t
      v = 0x01

      while (b <= m) && (x.key[b] == s)
        if state.C[state.cl[1], b] > v
          v = state.C[state.cl[1], b]
        end
        b += 1
      end

      if v > 0x02
        for u in t:(b - 1), l in 1:state.k
          if state.C[state.cl[l], u] > C[l, j]
            C[l, j] = state.C[state.cl[l], u]
          end
        end
      elseif v == 0x02
        for l in 1:state.k
          C[l, j] = 0x02
        end
      end

      t = b
    end
  end

  fp = open("$(file)_attributes.csv", "w")
  for l in 1:(state.k - 1)
    write(fp, string("\"Cluster ", l, "\","))
  end
  write(fp, string("\"Cluster ", state.k, "\"\n"))

  for j in 1:M
    for l in 1:(state.k - 1)
      write(fp, string(Int(C[l, j]), ","))
    end
    write(fp, string(Int(C[state.k, j]), "\n"))
  end
  close(fp)

  if verbose
    println("Attributes have been written to file: $(file)_attributes.csv")
  end

  nothing
end

function writecvalues(x::KData,
                      state::State,
                      file::String,
                      verbose::Bool)
  (m, n) = size(x.data)
  M = length(x.ref)

  isuint8 = eltype(x.ref) == UInt8

  polval = if isuint8
              UInt8('.')
            else
              "."
            end

  # characteristic values
  V = fill(" ", (state.k, M))

  # column index in x.key
  s = 0

  # column indices in state.C
  t = 1
  b = 1

  # temporary values
  v = 0x01
  z = 0
  flag = false

  fp = open("$(file)_characteristic.csv", "w")
  write(fp, "\"Site\",")
  for l in 1:(state.k - 1)
    write(fp, string("\"Cluster ", l, "\","))
  end
  write(fp, string("\"Cluster ", state.k, "\"\n"))

  for j in 1:M
    if x.ref[j] == polval
      s += 1
      b = t
      v = 0x01

      while (b <= m) && (x.key[b] == s)
        if state.C[state.cl[1], b] > v
          v = state.C[state.cl[1], b]
        end
        b += 1
      end

      if v > 0x02
        write(fp, string(j, ","))

        for l in 1:(state.k - 1)
          z = t
          flag = false

          while !flag && z < b
            flag = state.C[state.cl[l], z] == 0x04
            z += 1
          end

          if flag
            V[l, j] = uppercase(isuint8 ?
                                string(Char(x.val[z - 1])) :
                                x.val[z - 1])
            write(fp, string("\"", V[l, j], "\","))
          else
            write(fp, ",")
          end
        end

        z = t
        flag = false

        while !flag && z < b
          flag = state.C[state.cl[state.k], z] == 0x04
          z += 1
        end

        if flag
          V[state.k, j] = uppercase(isuint8 ?
                                    string(Char(x.val[z - 1])) :
                                    x.val[z - 1])
          write(fp, string("\"", V[state.k, j], "\"\n"))
        else
          write(fp, "\n")
        end
      end

      t = b
    end
  end
  close(fp)

  if verbose
    println("Characteristic values have been written to file: ",
            "$(file)_characteristic.csv")
  end

  V
end

function writedataset(x::KData,
                      state::State,
                      file::String,
                      verbose::Bool,
                      V::Matrix{String})
  (m, n) = size(x.data)
  M = length(x.ref)

  isuint8 = eltype(x.ref) == UInt8

  polval = if isuint8
              UInt8('.')
            else
              "."
            end

  # reconstruct original dataset
  D = fill(" ", (M, n))

  # column index in x.key
  s = 0

  # column indices in state.C
  t = 1
  b = 1

  # temporary values
  g = 0

  for a in 1:n
    s = 0
    t = 1
    g = state.R[a]

    for j in 1:M
      if x.ref[j] == polval
        s += 1
        b = t

        while (b <= m) && (x.key[b] == s)
          if x.data[b, a] == 0x01
            D[j, a] = (state.C[g, b] == 0x04) ?
                      uppercase(isuint8 ? string(Char(x.val[b])) : x.val[b]) :
                      lowercase(isuint8 ? string(Char(x.val[b])) : x.val[b])
          end
          b += 1
        end

        t = b
      end
    end
  end

  fp = open("$(file)_dataset.txt", "w")
  for l in 1:(state.k - 1)
    for j in 1:M
      write(fp, V[l, j])
    end
    write(fp, "\n")

    for i in 1:state.v[state.cl[l]]
      a = state.unit[state.cl[l]][i]
      for j in 1:M
        write(fp, D[j, a])
      end
      write(fp, string(" ; ", x.id[a], "\n"))
    end

    write(fp, "\n")
  end

  for j in 1:M
    write(fp, V[state.k, j])
  end
  write(fp, "\n")

  for i in 1:state.v[state.cl[state.k]]
    a = state.unit[state.cl[state.k]][i]
    for j in 1:M
      write(fp, D[j, a])
    end
    write(fp, string(" ; ", x.id[a], "\n"))
  end
  close(fp)

  nothing
end


text:
# using HTTP,JSON,Firebase
# # Firebase Auth  backend a REST API

# Firebase.init("test/fir-jl-457eb-firebase-adminsdk-40928-0efd6a89e7.json");
# header = Dict(
#     "Authorization" =>
#         "Bearer ya29.c.Kp8BAwh19dsnHN7yPkhlb3toQleIQuAQ94YlV-aXs6ijDEvEKtvKmoNiXw9Fg7u-EjpHjusuu_k9nIaW7tFohhW97fPTx7G0KowT-R0nwI52XdvHrG-TrRAZOjC38eiu_eaPgXTh2wxHUDH-sVPpvA5Yzv8DgCoCRTUboxa3ajDVhRiyvM7uOiFcR27k6eoMrOmk_EBTabpODRLhtIeKG10O",
# );
# body = """
# {
#     email: "ab669522@gmail.com",
#     password: "helloworld!!",
#     returnSecureToken: true
# }
# """
# HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyAEeSloxz3EtXTm73EdSIWY_WRVPF51hhI",header,body)
using HTTP,JSON

WEB_API_KEY = nothing

"""
set_webapikey(key ="")

sets WEB_API_KEY

# Example
```julia
set_webapikey("asjdlajsj1j32lj312")
```
"""
function set_webapikey(key="AIzaSyAEeSloxz3EtXTm73EdSIWY_WRVPF51hhI")
    global WEB_API_KEY = key
    println("WEB_API_KEY set: ", WEB_API_KEY)
end

"""
firebase_signup(email::String="", password::String="", returnSecureToken::Bool= true)

Sign up with email / password
You can create a new email and password user by issuing an HTTP POST request to the Auth
signupNewUser endpoint.

# Example

```julia
set_webapikey("WEB_API_KEY")
firebase_signup("ashwani@gmail.com","hello!!")
#=
Dict{String, Any} with 6 entries:
  "refreshToken" => "AGEhc0AjgXJevwy_rkJ3r4VUHc4EEORngVF-rwEtOuO007AymRqbAzVnn1iAMCZNHqzwnCI1X8fkJ0OPE2fTuGN7ameU6P7SmibwIFs8sOZxUI8C_uklOkk1IG5DFdWXAC45mK_0Hy4tuJXJUvI8Kuy6LS-GERZ5Bc…
  "kind"         => "identitytoolkit#SignupNewUserResponse"
  "localId"      => "GRCBj28Pkhat0mYsJS0BVrlVmJd2"
  "expiresIn"    => "3600"
  "idToken"      => "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRjNGQwMGJjM2NiZWE4YjU0NTMzMWQxZjFjOTZmZDRlNjdjNTFlODkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZmlyLWp…
  "email"        => "ashwani@gmail.com"
=#
```
"""
function firebase_signup(email::String="", password::String="", returnSecureToken::Bool=true)
    http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$WEB_API_KEY",
    header="""{Content-Type: application/json}""",
    body="""{"email": "$email","password":"$password","returnSecureToken":"$returnSecureToken"}""")
    response_string = String(http_response.body)
    JSON.parse(response_string)
end

"""
firebase_signin(email::String="data", password::String="data", returnSecureToken::Bool= true)

Sign in with email / password
You can sign in a user with an email and password by issuing an HTTP POST request
to the Auth verifyPassword endpoint.

# Example

```julia
firebase_signin("ashwani1@gmail.com" , "hello1231!!")
#=
Dict{String, Any} with 8 entries:
  "refreshToken" => "AGEhc0C1F9smilhBPdT5TYClumCwdzGI9q43s5r-MsqW-bJTeiIw1doG7zRF_VMX2a0WELR3zRB…
  "kind"         => "identitytoolkit#VerifyPasswordResponse"
  "localId"      => "zgrI4g3ualVJW7IEiRlPFg5jItA2"
  "displayName"  => ""
  "idToken"      => "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRjNGQwMGJjM2NiZWE4YjU0NTMzMWQxZjFjOTZmZDRlNjd…
  "registered"   => true
  "expiresIn"    => "3600"
  "email"        => "ashwani1@gmail.com"
=#
```
"""
function firebase_signin(email::String="", password::String="", returnSecureToken::Bool=true)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"email": "$email","password":"$password","returnSecureToken":"$returnSecureToken"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_signinanon(returnSecureToken::Bool= true)

Sign in anonymously
You can sign in a user anonymously by issuing an
HTTP POST request to the Auth signupNewUser endpoint.

# Exampleemail::String="", password::String="",

```julia
julia> firebase_signinanon()
#=
Dict{String, Any} with 5 entries:
  "refreshToken" => "AGEhc0DiE1zelLdCW2KG9wMRwZKcZI6EuSef4hsIc6uOZp0I3SYUTf0Hib_XgvtgY1yeqgFNqJ0…
  "kind"         => "identitytoolkit#SignupNewUserResponse"
  "localId"      => "3T8r7DD99zO9qKL1k56boC2iiXF2"
  "expiresIn"    => "3600"
  "idToken"      => "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRjNGQwMGJjM2NiZWE4YjU0NTMzMWQxZjFjOTZmZDRlNjd…
=#
```

"""
function firebase_signinanon(returnSecureToken::Bool=true)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"returnSecureToken":"$returnSecureToken"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

GOOGLE_ID_TOKEN = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRjNGQwMGJjM2NiZWE4YjU0NTMzMWQxZjFjOTZmZDRlNjdjNTFlODkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZmlyLWpsLTQ1N2ViIiwiYXVkIjoiZmlyLWpsLTQ1N2ViIiwiYXV0aF90aW1lIjoxNjIzOTQwMzIwLCJ1c2VyX2lkIjoiemdySTRnM3VhbFZKVzdJRWlSbFBGZzVqSXRBMiIsInN1YiI6Inpnckk0ZzN1YWxWSlc3SUVpUmxQRmc1akl0QTIiLCJpYXQiOjE2MjM5NDAzMjAsImV4cCI6MTYyMzk0MzkyMCwiZW1haWwiOiJhc2h3YW5pMUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiZW1haWwiOlsiYXNod2FuaTFAZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.uDT2BFPXlJWXzartwx8t8iBwriZc3PTpwJ3_5biOTI8H9sHU4w46E-XwUvW45Qip0_2Cmf6JZjbfkAZhGHnzIl6b9C3j2iJ0nXY_tvr0cC8otGPp01J8vBSZCu24tI0BdPaymXrFek4ouGmnbFCdxO2D3eeB59ZVsJCm9JWzGjSlrO5m0KMIOhYAV5aq6BaT32AzkPZJDXWTjc3nEXrxF-5n8Nehek_QbxROh7pwJHqDul5xswlDYGqHAx3d2jrcrSehGhfetHfPx9IYOPttAT0mSeROz3Lgy9cLmfO5HvAZMNoJs0gif7ffr773TJMkbELEc-gyBFETnoY87LPvuA"
"""
firebase_signinoauth()

Sign in with OAuth credential
You can sign in a user with an OAuth credential by issuing
 an HTTP POST request to the Auth verifyAssertion endpoint.

This doesn't work today

# Example

```julia"oobCode":"[VERIFICATION_CODE]"
firebase_signinoauth()
```

"""
function firebase_signinoauth()
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"postBody":"{id_token=$GOOGLE_ID_TOKEN&providerId=[google.com]","requestUri":"http://localhost","returnIdpCredential":true,"returnSecureToken":true}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_fetchproviders(email="")

Fetch providers for email
You can look all providers associated with a specified email by
issuing an HTTP POST request to the Auth createAuthUri endpoint.

# Example

```julia
julia> firebase_fetchproviders("ashwani1@gmail.com")
#=
Dict{String, Any} with 5 entries:
  "allProviders"  => Any["password"]
  "kind"          => "identitytoolkit#CreateAuthUriResponse"
  "sessionId"     => "k8iBdCSLEeAbhhgKz6E4PC-ltCs"
  "signinMethods" => Any["password"]
  "registered"    => true
=#
```
"""
function firebase_fetchproviders(email="ab669522@gmail.com")
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:createAuthUri?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"identifier":"$email","continueUri":"http://localhost:8080/app"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_passwordreset(email="ab669522@gmail.com")

Send password reset email
You can send a password reset email by
issuing an HTTP POST request to the Auth getOobConfirmationCode endpoint.

# Example

```julia
firebase_passwordreset(email="ab669522@gmail.com")
# email will recieve the reset password email
```
"""
function firebase_passwordreset(email="ab669522@gmail.com")
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"requestType":"PASSWORD_RESET","email":"$email"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
verify_passwordresetcode()

Verify password reset code
You can verify a password reset code by issuing an
HTTP POST request to the Auth resetPassword endpoint.

# Example

```julia

```
"""
function verify_passwordresetcode()
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"oobCode":"[PASSWORD_RESET_CODE]"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""

"""
function confirm_passwordreset()
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"oobCode":"[PASSWORD_RESET_CODE]","newPassword":"[NEW_PASSWORD]"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

FIREBASE_ID_TOKEN = nothing

"""
firebase_changeemail(newemail="",firebase_id_token=  FIREBASE_ID_TOKEN)

Change email
You can change a user's email by issuing an
HTTP POST request to the Auth setAccountInfo endpoint.

# Example
```julia
data = firebase_signin("ab669522@gmail.com,"helloworld!!")
firebase_changeemail("ab6695221@gmail.com",data["idToken"])
data = firebase_signin("ab6695221@gmail.com,"helloworld!!")
firebase_changeemail("ab669522@gmail.com",data["idToken"])
````

"""
function firebase_changeemail(newemail="", firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token","email":"$newemail","returnSecureToken":true}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_changepassword(newpassword="", firebase_id_token=FIREBASE_ID_TOKEN)

Change password
You can change a user's password by issuing an
HTTP POST request to the Auth setAccountInfo endpoint.

# Example
```julia
data = firebase_signin("ab669522@gmail.com","helloworld!!")
firebase_changepassword("hellopaaji!!",data["idToken"])
data = firebase_signin("ab6695221@gmail.com","hellopaaji!!")
firebase_changepassword("helloworld!!",data["idToken"])
````

"""
function firebase_changepassword(newpassword="", firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token","password":"$newpassword","returnSecureToken":true}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""

Update profile
You can update a user's profile (display name / photo URL) by issuing an
HTTP POST request to the Auth setAccountInfo endpoint.

# TODO: delete attribute
# Example
```julia
data = firebase_signin("ab669522@gmail.com","helloworld!!")
firebase_updateprofile("ash","https://i.imgur.com/zgDkgSR.jpeg",data["idToken"])
#=
Dict{String, Any} with 8 entries:
  "kind"             => "identitytoolkit#SetAccountInfoResponse"
  "photoUrl"         => "https://i.imgur.com/zgDkgSR.jpeg"
  "localId"          => "GovyExPqFWS70uynnuBzVnYgLAi2"
  "displayName"      => "ash"
  "passwordHash"     => "UkVEQUNURUQ="
  "emailVerified"    => false
  "providerUserInfo" => Any[Dict{String, Any}("rawId"=>"ab669522@gmail.com", "photoUrl"=>"https:…
  "email"            => "ab669522@gmail.com"
=#
  ```
"""
function firebase_updateprofile(displayname="",photourl="",firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token","displayName":"$displayname","photoUrl":"$photourl","returnSecureToken":true}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_getuserinfo(firebase_id_token=FIREBASE_ID_TOKEN)

Get user data
You can get a user's data by issuing an HTTP POST request to the Auth getAccountInfo endpoint.
# Example
```julia
data = firebase_signin("ab669522@gmail.com","helloworld!!")
firebase_getuserinfo(data["idToken"])
```
"""
function firebase_getuserinfo(firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""

Link with email/password
You can link an email/password to a current user by issuing an
HTTP POST request to the Auth setAccountInfo endpoint.

# Example
```julia
data = firebase_signin("ab669522@gmail.com","helloworld!!")
firebase_linkuserinfo("ash@gmail.com", "hello!!123as",data["idToken"])
data = firebase_signin("ash@gmail.com", "hello!!123as")
firebase_linkuserinfo("ab669522@gmail.com","helloworld!!",data["idToken"])
```
"""
function firebase_linkuserinfo(email::String="", password::String="",firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token","email":"$email","password":"$password","returnSecureToken":true}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

# implmene the linking a account with OAuth here
"""
Link with OAuth credential
You can link an OAuth credential to a user by
issuing an HTTP POST request to the Auth verifyAssertion endpoint.
"""
function firebase_linkoauth()

end

"""

Unlink provider
You can unlink a provider from a current user by issuing an
HTTP POST request to the Auth setAccountInfo endpoint.

# Example
```julia
set_webapikey()

data = firebase_signup("ashwani12123@gmail.com","hello!!123")
#=
Dict{String, Any} with 6 entries:
  "refreshToken" => "AGEhc0A4Y-wFC0S2Cub-7TY2XNfZMYQf-YKzTdQWl9_SjrRpUW4d3QymQy5P1EN4Me8-SE695sPE_MBXoMoqTzKLy76nBvDGmybGmP4wnWLyrJql-HfoVPRtG1emeJ3E61DnDbUIZOvV-Y3GuzpJ57XZojHBM1aoMp…
  "kind"         => "identitytoolkit#SignupNewUserResponse"
  "localId"      => "neXn8Mg562VFgENRtA2SEC0NEBk1"
  "expiresIn"    => "3600"
  "idToken"      => "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRjNGQwMGJjM2NiZWE4YjU0NTMzMWQxZjFjOTZmZDRlNjdjNTFlODkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZmlyLWp…
  "email"        => "ashwani12123@gmail.com"
=#
firebase_unlinkprovide(data["idToken"], "google.com")
#=
Dict{String, Any} with 6 entries:
  "kind"             => "identitytoolkit#SetAccountInfoResponse"
  "localId"          => "neXn8Mg562VFgENRtA2SEC0NEBk1"
  "passwordHash"     => "UkVEQUNURUQ="
  "emailVerified"    => false
  "providerUserInfo" => Any[Dict{String, Any}("rawId"=>"ashwani12123@gmail.com", "providerId"=>"password", "federatedId"=>"ashwani12123@gmail.com", "email"=>"ashwani12123@gmail.com")]
  "email"            => "ashwani12123@gmail.com"
=#
```
"""
function firebase_unlinkprovide(firebase_id_token=FIREBASE_ID_TOKEN, providerdelete="google.com")
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token","deleteProvider":["[$providerdelete]"]}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_verifyemail(firebase_id_token=FIREBASE_ID_TOKEN)

Send email verification
You can send an email verification for the current user by issuing an HTTP POST request to the Auth getOobConfirmationCode endpoint.

# Example
```julia
data = firebase_signin("ab669522@gmail.com","helloworld!!")
firebase_verifyemail((data["idToken"])
```
"""
function firebase_verifyemail(firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"requestType":"VERIFY_EMAIL","idToken":"$firebase_id_token"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

test = "1dArHTOb-Xpb6QWO7f-SVjb4yRRXMmxGB87iMy_oAtMAAAF6GtCHig"
"""
TODO: This does work yet
"""
function firebase_confirmemailverify(verification_code="")
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:update?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"oobCode":"$verification_code"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end

"""
firebase_deleteuser(firebase_id_token=FIREBASE_ID_TOKEN)

Delete account
You can delete a current user by issuing an HTTP POST
request to the Auth deleteAccount endpoint.
# Example

```julia
data = firebase_signup("ashwani121231@gmail.com","hello!!123")
firebase_deleteuser(data["idToken"])
```
"""
function firebase_deleteuser(firebase_id_token=FIREBASE_ID_TOKEN)
  http_response = HTTP.post("https://identitytoolkit.googleapis.com/v1/accounts:delete?key=$WEB_API_KEY",
  header="""{Content-Type: application/json}""",
  body="""{"idToken":"$firebase_id_token"}""")
  response_string = String(http_response.body)
  JSON.parse(response_string)
end


text:
using Test
using MMWavenet
using Flux
using Statistics

@doc """
    numgrad(model, data::Array{Float32, 3})

Returns gradient obtained by finite differentiation.
""" ->
function numgrad(model, data::Array{Float32, 3})
    gradient = Array{Float32, 3}(zeros(size(data)))
    for i=1:size(data)[1]
        for j=1:size(data)[2]
            Δ::Array{Float32, 3} = Array{Float32, 3}(zeros(size(data)))
            Δ[i, j, 1] = mean(data)/1000
            gradient[i, j, 1] = cda(model, data, Δ)[1]
        end
    end
    return gradient
end

@doc """
    cda(model, x::Array{Float32, 3})

Gradient: eighth order Central Difference Approximation.
""" ->
function cda(m, x::Array{Float32, 3}, Δ::Array{Float32, 3})
    return ((1/280)*m(x-4*Δ) - (4/105)*m(x-3*Δ) + (1/5)*m(x-2*Δ) - (4/5)*m(x-Δ)
    - (1/280)*m(x+4*Δ) + (4/105)*m(x+3*Δ) - (1/5)*m(x+2*Δ) + (4/5)*m(x+Δ) )/maximum(Δ)
end

function gradcheck()
    m, _ = build_wavenet(2, 3);

    # Finite differentiation vs Automatic differentiation.
    @testset "finiteDiff" begin
        for _=1:10
            x::Array{Float32, 3} = Array{Float32, 3}(rand(0:0.0001:0.001, (3, 2, 1)))
            @test mean(abs.((numgrad(m, x) .-
                gradient(Chain(m, t->t[1]), x)[1]))) < 10e-2
        end
    end

    # Gradients are not same for different inputs
    @testset "differentGrads" begin
        for _=1:2
            x1 = Array{Float32, 3}(rand(0:0.0001:0.001, (3, 2, 1)))
            x2 = Array{Float32, 3}(rand(0:0.0001:0.001, (3, 2, 1)))
            @test gradient(Chain(m, t->t[1]), x1)[1] != gradient(Chain(m, t->t[1]), x2)[1];
        end
    end
end

gradcheck()

max_stars_repo_name: kozvojtex/MMWavenet

max_issues_repo_name: kozvojtex/MMWavenet

max_forks_repo_name: kozvojtex/MMWavenet


text:
module IntegralsCubature

using Integrals, Cubature

import Integrals: transformation_if_inf, scale_x, scale_x!

abstract type AbstractCubatureJLAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
struct CubatureJLh <: AbstractCubatureJLAlgorithm end
struct CubatureJLp <: AbstractCubatureJLAlgorithm end

function Integrals.__solvebp_call(prob::IntegralProblem,
    alg::AbstractCubatureJLAlgorithm,
    sensealg, lb, ub, p, args...;
    reltol=1e-8, abstol=1e-8,
    maxiters=typemax(Int),
    kwargs...)
    prob = transformation_if_inf(prob) #intercept for infinite transformation
    nout = prob.nout
    if nout == 1
        if prob.batch == 0
            if isinplace(prob)
                dx = zeros(prob.nout)
                f = (x) -> (prob.f(dx, x, p); dx[1])
            else
                f = (x) -> prob.f(x, p)[1]
            end
            if lb isa Number
                if alg isa CubatureJLh
                    _val, err = Cubature.hquadrature(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    _val, err = Cubature.pquadrature(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
                val = prob.f(lb, p) isa Number ? _val : [_val]
            else
                if alg isa CubatureJLh
                    _val, err = Cubature.hcubature(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    _val, err = Cubature.pcubature(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end

                if isinplace(prob) || !isa(prob.f(lb, p), Number)
                    val = [_val]
                else
                    val = _val
                end
            end
        else
            if isinplace(prob)
                f = (x, dx) -> prob.f(dx', x, p)
            elseif lb isa Number
                if prob.f([lb ub], p) isa Vector
                    f = (x, dx) -> (dx .= prob.f(x', p))
                else
                    f = function (x, dx)
                        dx[:] = prob.f(x', p)
                    end
                end
            else
                if prob.f([lb ub], p) isa Vector
                    f = (x, dx) -> (dx .= prob.f(x, p))
                else
                    f = function (x, dx)
                        dx .= prob.f(x, p)[:]
                    end
                end
            end
            if lb isa Number
                if alg isa CubatureJLh
                    _val, err = Cubature.hquadrature_v(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    _val, err = Cubature.pquadrature_v(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            else
                if alg isa CubatureJLh
                    _val, err = Cubature.hcubature_v(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    _val, err = Cubature.pcubature_v(f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            end
            val = _val isa Number ? [_val] : _val
        end
    else
        if prob.batch == 0
            if isinplace(prob)
                f = (x, dx) -> (prob.f(dx, x, p); dx)
            else
                f = (x, dx) -> (dx .= prob.f(x, p))
            end
            if lb isa Number
                if alg isa CubatureJLh
                    val, err = Cubature.hquadrature(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    val, err = Cubature.pquadrature(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            else
                if alg isa CubatureJLh
                    val, err = Cubature.hcubature(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    val, err = Cubature.pcubature(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            end
        else
            if isinplace(prob)
                f = (x, dx) -> prob.f(dx, x, p)
            else
                if lb isa Number
                    f = (x, dx) -> (dx .= prob.f(x', p))
                else
                    f = (x, dx) -> (dx .= prob.f(x, p))
                end
            end

            if lb isa Number
                if alg isa CubatureJLh
                    val, err = Cubature.hquadrature_v(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    val, err = Cubature.pquadrature_v(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            else
                if alg isa CubatureJLh
                    val, err = Cubature.hcubature_v(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                else
                    val, err = Cubature.pcubature_v(nout, f, lb, ub;
                        reltol=reltol, abstol=abstol,
                        maxevals=maxiters)
                end
            end
        end
    end
    SciMLBase.build_solution(prob, alg, val, err, retcode=:Success)
end

export CubatureJLh, CubatureJLp

end


text:
# functions related to negative binomial distribution

# R implementations
using .RFunctions:
    nbinompdf,
    nbinomlogpdf,
    nbinomcdf,
    nbinomccdf,
    nbinomlogcdf,
    nbinomlogccdf,
    nbinominvcdf,
    nbinominvccdf,
    nbinominvlogcdf,
    nbinominvlogccdf


text:
"""
    AbstractLinearSolver{Tv}

Abstract container for solving an augmented system
```
    [-(Θ⁻¹ + Rp)   Aᵀ] [dx] = [ξd]
    [   A          Rd] [dy]   [ξp]
```
where `ξd` and `ξp` are given right-hand side.
"""
abstract type AbstractLinearSolver{Tv<:Real} end

"""
    LinearSystem

Indicates which linear system is solved.
"""
abstract type LinearSystem end

"""
    DefaultSystem

Choose linear system to be solved using default option.
"""
struct DefaultSystem <: LinearSystem end

"""
    AugmentedSystem

Solve the augmented system, i.e., without reducing to normal equations.
"""
struct AugmentedSystem <: LinearSystem end

"""
    NormalEquations

Solve the normal equations system.
"""
struct NormalEquations <: LinearSystem end

"""
    LSBackend

Backend used for solving linear systems.
"""
abstract type LSBackend end

"""
    DefaultBackend

Chose linear solver backend automatically.

* For `A::Matrix{Tv}`, defaults to [`Lapack`](@ref) (i.e., dense solver).
* For `A::AbstractMatrix{Float64}`, defaults to [`Cholmod`](@ref)
* Otherwise, defaults to [`LDLFact`](@ref)
"""
struct DefaultBackend <: LSBackend end

#
# Specialized implementations should extend the functions below
#

"""
    update_linear_solver!(ls, θ, regP, regD)

Update internal data, and re-compute factorization/pre-conditioner.

After this call, `ls` can be used to solve the augmented system
```
    [-(Θ⁻¹ + Rp)   Aᵀ] [dx] = [ξd]
    [   A          Rd] [dy]   [ξp]
```
for given right-hand sides `ξd` and `ξp`.
"""
function update_linear_solver! end

"""
    solve_augmented_system!(dx, dy, ls, ξp, ξd)

Solve the symmetric quasi-definite augmented system
```
    [-(Θ⁻¹ + Rp)   Aᵀ] [dx] = [ξd]
    [   A          Rd] [dy]   [ξp]
```
and over-write `dx`, `dy` with the result.

# Arguments
- `dx, dy`: Vectors of unknowns, modified in-place
- `ls`: Linear solver for the augmented system
- `ξp, ξd`: Right-hand-side vectors
"""
function solve_augmented_system! end

include("cholmod.jl")
include("ldlfact.jl")

AbstractLinearSolver(
    ::DefaultBackend,
    ::DefaultSystem,
    A::AbstractMatrix{Float64}
) = AbstractLinearSolver(Cholmod(), AugmentedSystem(), A)

AbstractLinearSolver(
    ::DefaultBackend,
    ::DefaultSystem,
    A::AbstractMatrix{Tv}
) where{Tv<:Real} = AbstractLinearSolver(LDLFact(), AugmentedSystem(), A)


text:
#==============================================================================#
# runtests.jl
#
# Tests for SymDict.jl
#
# Copyright Sam O'Connor 2015 - All rights reserved
#==============================================================================#

using SymDict
using Test

d = Dict(:a=>1,:b=>2)

@test stringdict(d) == Dict("a"=>1,"b"=>2)
@test symboldict(stringdict(d)) == d

function f()
    a = 1
    b = 2
    @SymDict(a,b,c=3,d=4)
end
@test f() == Dict(:a=>1,:b=>2,:c=>3,:d=>4)

function f2(a; args...)
    b = 2
    @SymDict(a, b, c=3, d=4, args...)
end
@test f2(1) == Dict(:a=>1,:b=>2,:c=>3,:d=>4)
@test f2(1,d="!") == Dict(:a=>1,:b=>2,:c=>3,:d=>"!")
@test f2(1,x=24,y=25,z=26) == Dict(:a=>1,:b=>2,:c=>3,:d=>4,:x=>24,:y=>25,:z=>26)

@test @SymDict(a=1, "b"=2, c=3) == @SymDict(a=1, b=2, c=3)

function f3(;args...)
    stringdict(args)
end

@test f3(a=1, b=2, c=3) == stringdict(@SymDict(a=1, b=2, c=3))

#==============================================================================#
# End of file.
#==============================================================================#


text:
using IHT, PLINK, RegressionTools
(xbed, ybed) = read_plink_data("gwas 1 data_kevin", delim=',', header=false); output = L0_reg(xbed, ybed, 10)

function run()
    (xbed, ybed) = read_plink_data("gwas 1 data_kevin", delim=',', header=false)
    output = L0_reg(xbed, ybed, 10)
end


text:
include("getdigit_n.jl")
include("myprintf.jl")
using Printf
using .GetDigit_n
using .MyPrintf

const DIGIT = 5
const MAXN = 1500000

function madhava_leibniz(n)
    result = BigFloat(0)
    for i = 1:n
        if i % 2 == 1
            result += BigFloat(1) / BigFloat(2 * i - 1)
        else
            result -= BigFloat(1) / BigFloat(2 * i - 1)
        end
    end

    return BigFloat(4) * result
end

function main()
    n = GetDigit_n.getn(madhava_leibniz, MAXN, DIGIT, true)
    precision = GetDigit_n.getdigit(madhava_leibniz, n, DIGIT, true)
    precision = GetDigit_n.getdigit_2(madhava_leibniz, n, DIGIT, precision)

    setprecision(precision)
    MyPrintf.myprintf("π（計算値） = ", DIGIT, madhava_leibniz(n))
    MyPrintf.myprintf("π（厳密値） = ", DIGIT, BigFloat(π))
    @printf("n = %d, 計算%d桁で、%d桁求まりました\n", n, precision, DIGIT)
end

main()


text:
import Base.iterate
abstract type  AbstractDataSampler end

"""
  SamplerWithData{Tsampler}

Associate an instance of an AbstractDataSampler with the actual data to sample.

"""
mutable struct SamplerWithData{Ts <: AbstractDataSampler, Td <: AbstractArray}
    sampler::Ts
    data::Td
    dims::Int64
end

# To implement a new sampler:
# - create a new structure child of AbstractDataSampler
# - override iterate(iter::SamplerWithData{yoursampler} and iterate(iter::SamplerWithData{yoursampler},state) considering that
#=
for i in iter   # or  "for i = iter"
    # body
end

# --> is rewritten to :

next = iterate(iter)
while next !== nothing
    (i, state) = next
    # body
    next = iterate(iter, state)
end
=#
"""
   KFold(nSplits=5,nRepeats=1,shuffle=true,rng=Random.GLOBAL_RNG)

Iterator for k-fold crossValidation strategy.

"""
mutable struct KFold <: AbstractDataSampler
    nSplits::Int64
    nRepeats::Int64
    shuffle::Bool
    rng::AbstractRNG
    function KFold(;nSplits=5,nRepeats=1,shuffle=true,rng=Random.GLOBAL_RNG)
        return new(nSplits,nRepeats,shuffle,rng)
    end
end

# Implementation of the Julia iteration  API for SamplerWithData{KFold}
function iterate(iter::SamplerWithData{KFold})
     # First iteration, I need to create the subsamples
     K    = iter.sampler.nSplits
     D    = iter.dims
     if eltype(iter.data) <: AbstractArray # data has multiple arrays, like X,Y
       subs = collect(zip(partition(iter.data,fill(1/K,K),shuffle=iter.sampler.shuffle,dims=D,rng=iter.sampler.rng,copy=false)...))
     else # data is a single matrix/tensor
       subs = collect(zip(partition(iter.data,fill(1/K,K),shuffle=iter.sampler.shuffle,dims=D,rng=iter.sampler.rng,copy=false)))
     end
     i    = (cat.(subs[2:K]...,dims=D),subs[1])
     next = (subs,2)
     return (i,next)
end

function iterate(iter::SamplerWithData{KFold},state)
     # Further iteration, I need to create the subsamples only if it is a new interaction
     K    = iter.sampler.nSplits
     D    = iter.dims
     nRep = iter.sampler.nRepeats
     subs    = state[1]
     counter = state[2]
     counter <= (K * nRep) || return nothing  # If we are done all the splits by the repetitions we are done
     kpart = counter % K
     if kpart == 1 # new round, we repartition in k parts
         if eltype(iter.data) <: AbstractArray # data has multiple arrays, like X,Y
             subs = collect(zip(partition(iter.data,fill(1/K,K),shuffle=iter.sampler.shuffle,dims=D,rng=iter.sampler.rng,copy=false)...))
         else # data is a single matrix
             subs = collect(zip(partition(iter.data,fill(1/K,K),shuffle=iter.sampler.shuffle,dims=D,rng=iter.sampler.rng,copy=false)))
         end
         i    = (cat.(subs[2:end]...,dims=D),subs[1])
         next = (subs,counter+1)
         return (i,next)
     else
        if kpart == 0 # the modulo returns the last element as zero instead as K
            i   = (cat.(subs[1:K-1]...,dims=D),subs[end])
        else
            i   = (cat.(subs[1:kpart-1]...,subs[kpart+1:end]...,dims=D),subs[kpart])
        end
        next  = (subs,counter+1)
        return (i,next)
    end
end

# ------------------------------------------------------------------------------
# Used for NN
"""
  batch(n,bSize;sequential=false,rng)

Return a vector of `bSize` vectors of indeces from `1` to `n`.
Randomly unless the optional parameter `sequential` is used.

# Example:
```julia
julia> Utils.batch(6,2,sequential=true)
3-element Array{Array{Int64,1},1}:
 [1, 2]
 [3, 4]
 [5, 6]
 ```
"""
function batch(n::Integer,bSize::Integer;sequential=false,rng = Random.GLOBAL_RNG)
    ridx = sequential ? collect(1:n) : shuffle(rng,1:n)
    if bSize > n
        return [ridx]
    end
    nBatches = Int64(floor(n/bSize))
    batches = Array{Int64,1}[]
    for b in 1:nBatches
        push!(batches,ridx[b*bSize-bSize+1:b*bSize])
    end
    return batches
end


text:
@testset "@when" begin
    @testset "Only @when" begin
        @test 2 == @when let (a, 1) = (2, 1)
            a
        end

        @test 2 === @when let 1 = 1
            2
        end
        @test 2 === @when 1 = 1 2

        @test 1 === @when let a = 1
            a
        end
        @test 1 === @when a = 1 a

        @test nothing === @when let (a, b) = 1
            a + b
        end
        @test nothing === @when (a, b) = 1 a + b

        ab = (2, 3)
        @test 5 === @when let (a, b) = ab
            a + b
        end
        @test 5 === @when (a, b) = ab a + b
    end

    @testset "@when + @data" begin
        @data WhenTest begin
            WhenTest_1(Int)
            WhenTest_2(Int)
        end

        var1 = WhenTest_1(2)
        var2 = WhenTest_2(2)
        @test 200 === @when let WhenTest_1(x) = var1,
                                @inline WhenAction(x) = 100x
            WhenAction(x)
        end

        @test 200 === @when WhenTest_1(x) = var1 begin
            100x
        end

        @test nothing === @when let WhenTest_1(x) = var2,
                                   @inline WhenAction(x) = 100x
            WhenAction(x)
        end

    end

    @testset "when with predicates" begin
        @test 2 === @when let if 1 > 0 end
            2
        end
        @test 3 === @when let (a, b) = (1, 2),
                              (1 > 0).?
                a + b
        end
    end
    @testset "@when in @when" begin
        function f1(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (2, b)
            end
        end
        # case: a
        @test f1(111, 1) == 111
        @test f1(222, 1) == 222
        # case: (2, b)
        @test f1(111, 2) == (2, 111)
        @test f1(222, 2) == (2, 222)

        function f2(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (:b, b)
            @when (c, 3) = x
                (:c, c)
            end
        end
        @test f2(10, 1) == 10       # case: a
        @test f2(20, 2) == (:b, 20) # case: (:b, b)
        @test f2(30, 3) == (:c, 30) # case: (:c, c)

    end

    @testset "@when + @otherwise" begin
        function f1(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @otherwise
                x
            end
        end
        @test f1(1) == (1, )    # case: x
        @test f1(1, 2) == (1, 2)# case: x
        @test f1(2, 1) == 2     # case: a

        function f2(args...)
            x = Tuple(args)
            @when (a, 1) = x begin
                a
            @when (b, 2) = x
                (:b, b)
            @when (c, 3) = x
                (:c, c)
            @otherwise
                x
            end
        end
        @test f2(1) == (1, )        # case: x
        @test f2(1, 0) == (1, 0)    # case: x
        @test f2(10, 1) == 10       # case: a
        @test f2(20, 2) == (:b, 20) # case: (:b, b)
        @test f2(30, 3) == (:c, 30) # case: (:c, c)

        xy = (1, 3)
        res = @when let (a, 1) = xy
            a
        @otherwise
            0
        end
        @test res == 0

        res = @when let (a, 3) = xy
            a
        @otherwise
            0
        end
        @test res == 1

        # @when let bindings...
        z = 5
        res = @when let (a, 3) = xy,
                        5 = z
            a
        @otherwise
            0
        end
        @test res == 1

        res = @when let (a, 1) = xy,
                        5 = z
            a
        @otherwise
            0
        end
        @test res == 0

        res = @when let (a, 3) = xy,
                        6 = z
            a
        @otherwise
            0
        end
        @test res == 0

    end

    @testset "@when + @otherwise with many bidings" begin
        function f1(xy, z)
            @when let (a, 1) = xy,
                      5      = z
                a
            @otherwise
                0   # default value
            end
        end
        @test f1((123, 1), 5) == 123    # case: a
        @test f1((123, 3), 5) == 0      # not match `(a, 1) = xy`
        @test f1((123, 1), 1) == 0      # not match `5 = z`

    end

    @testset "error handles" begin
        # no method matching
        @test_macro_throws MethodError @when

        # macro when(assignment, ret)
        #   case: _
        @test_macro_throws SyntaxError @when x 1
        @test_macro_throws SyntaxError("Not match the form of `@when a = b expr`") @when 1 1

        # gen_when
        #   case: Expr(a, _...)
        # @test_broken SyntaxError("Expect a let-binding, but found a `block` expression.") @when begin end
        # @test_broken SyntaxError("Expect a let-binding, but found a `macrocall` expression.") @when @when
        #
        # #   case: _
        # @test_broken SyntaxError("Expect a let-binding.") @when 1
        # @test_broken SyntaxError("Expect a let-binding.") @when x
    end

end


text:
function backprop(graph::AD, setGradToOne::Bool)
  # set the derivative to 1
  if setGradToOne
    graph.grad += 1
  end
  bfs = [graph]
  while length(bfs) != 0
    current = pop!(bfs)
    current.gradOp(current)
    numParents = length(current.parents)
    for i=1:numParents
      push!(bfs, current.parents[i])
    end
  end
  return graph
end
backprop(graph::AD) = backprop(graph, true)

function resetGrad(graph::AD)
  bfs = [graph]
  while length(bfs) != 0
    current = pop!(bfs)
    current.grad = current.grad .* 0
    numParents = length(current.parents)
    for i=1:numParents
      push!(bfs, current.parents[i])
    end
  end
  return graph
end


text:
module ChemistryFeaturization

using SimpleWeightedGraphs
using Reexport

# define all the abstract types
export AbstractAtoms, AbstractFeatureDescriptor, AbstractFeaturization
export AbstractPairFeatureDescriptor,
    AbstractAtomFeatureDescriptor, AbstractEnvironmentFeatureDescriptor

abstract type AbstractAtoms end
abstract type AbstractFeatureDescriptor end
abstract type AbstractFeaturization end

abstract type AbstractAtomFeatureDescriptor <: AbstractFeatureDescriptor end
abstract type AbstractPairFeatureDescriptor <: AbstractFeatureDescriptor end
abstract type AbstractEnvironmentFeatureDescriptor <: AbstractFeatureDescriptor end

include("utils/Utils.jl")
@reexport using .Utils.ElementFeatureUtils
@reexport using .Utils.GraphBuilding

#= ATOMS OBJECTS

Should have a field called `elements` that is a list of strings of elemental symbols, as well as fields to store features and an associated featurization object.

AtomGraph shouldn't have to change too much from its current incarnation. WeaveMol is
not currently a thing that can be directly fed into a model, so that will have to get
updated. Both will need some way to specify which types of features can be attached
to them, maybe this is a place for the holy trait design pattern?

=#

# link to guidance in docs about how to implement new feature types

# export...
export AtomGraph, visualize
#export WeaveMol#, ...

# include...
include("atoms/atomgraph.jl")
#include("weavemol.jl")

#= FEATURE OBJECTS

I decided on an abstract type to allow the dispatch shown below in the "magical encoding"
and "magical decoding" bits.

Representative examples – feature: feature object type, input to encoder, output of encoder:

block (s,p,d,f):            ElementFeatureDescriptor, String, Flux.OneHotMatrix
electronegativity (binned): ElementFeatureDescriptor, Float32, Flux.OneHotMatrix
electronegativity (direct): ElementFeatureDescriptor, Float32, Vector{Float32}
oxidation state:            SpeciesFeatureDescriptor, Int, Vector{Float32}
distance between atoms:     PairFeat, Float32, Matrix{Float32}
bond type:                  PairFeat, String, Array{Float32,3}

(bond type is categorical and gets one-hot encoded, so the first two indices of the Matrix
should be atom indices and the third should be indexing into the one-hot vector, which should just contain all zeros if the two atoms are not bonded (or we add a bin to the one-hot encoding to indicate that)

All subtypes should have `encode_f` and `decode_f` fields
=#

# link to guidance in docs about how to implement new feature types

# export...
export ElementFeatureDescriptor, SpeciesFeatureDescriptor, PairFeatureDescriptor
export encodable_elements, decode

"""
    encodable_elements(f::AbstractFeatureDescriptor)
    encodable_elements(feature_name::String)
    encodable_elements(fzn::AbstractFeaturization)

Return a list of elements encodable by a given feature or featurization.
"""
encodable_elements(f::AbstractFeatureDescriptor) = println("Implement me please!")
encodable_elements(fzn::AbstractFeaturization) = println("Implement me please!")

# include...
include("features/elementfeature.jl")
include("features/speciesfeature.jl")
include("features/pairfeature.jl")

# generic encode
function (f::AbstractFeatureDescriptor)(a::AbstractAtoms)
    println("Implement me, please!")
end

"""
    decode(f::AbstractFeatureDescriptor, encoded_feature)

Decode a feature that was encoded using the provided feature object.

## Examples

```jldoctest
julia> decode(AtomFeatureDescriptor("Block"), [0, 1, 0, 0])
"p"
```
"""
function decode(f::AbstractFeatureDescriptor, encoded_feature)
    #f.decode_f(encoded_feature)
    println("Implement me, please!")
end

#= FEATURIZATION OBJECTS
All such objects should define at least one list of <: AbstractFeatureDescriptor objects and either work according to the generic featurize! defined herein or dispatch featurize! if customized behavior is needed. You should also dispatch the decode function, for which a generic implementation does not currently exist.
=#

# export...
export GraphNodeFeaturization, decode
export encodable_elements, featurize!
export WeaveFeaturization

# include...
include("featurizations/graphnodefeaturization.jl")
include("featurizations/weavefeaturization.jl")

"""
    featurize!(a::AbstractAtoms, fzn::AbstractFeaturization)

Featurize a structure with a given featurization.
"""
function featurize!(a::AbstractAtoms, fzn::AbstractFeaturization)
    println("Implement me please!")
end

# dispatch some things so that featurize!.(::Vector{AbstractAtoms}, ::AbstractFeaturization) will work...
Base.iterate(fzn::AbstractFeaturization) = (fzn, nothing)
Base.iterate(fzn::AbstractFeaturization, state) = nothing
Base.length(fzn::AbstractFeaturization) = 1

"""
    decode(fzn::AbstractFeaturization, encoded)

Decode a set of features that were encoded using the provided featurization.
"""
function decode(fzn::AbstractFeaturization, encoded)
    println("Implement me please!")
end

# pretty printing for featurizations, short version
Base.show(io::IO, fzn::AbstractFeaturization) = print(io, "$(typeof(fzn))")

# pretty printing, long version
function Base.show(io::IO, ::MIME"text/plain", fzn::AbstractFeaturization)
    st = "$(typeof(fzn)):"
    for feature_list in fieldnames(typeof(fzn))
        st = string(st, "\n    $(feature_list):")
        for feature in getproperty(fzn, feature_list)
            st = string(st, "\n        $(feature)")
        end
    end
    print(io, st)
end

end


text:
# calculate the normalised mutual information measure
function voi(ca::Vector{Int}, cb::Vector{Int})
    length(ca) == length(cb) || error("membership length must be equal")
    n_ca = maximum(ca)
    n_cb = maximum(cb)
    ca_set = Set{Int}[]
    cb_set = Set{Int}[]
    for i=1:n_ca
        push!(ca_set, Set{Int}())
    end
    for (u, i) in enumerate(ca)
        push!(ca_set[i], u)
    end
    for j=1:n_cb
        push!(cb_set, Set{Int}())
    end
    for (v, j) in enumerate(cb)
        push!(cb_set[j], v)
    end
    N = zeros(Int, n_ca, n_cb) # confusion matrix
    for i=1:n_ca, j=1:n_cb
        N[i,j] = length(intersect(ca_set[i], cb_set[j]))
    end
    N1 = collect(sum(N, 1))
    N2 = collect(sum(N, 2))
    Nsum = length(ca)
    VI = 0.0
    for i=1:n_ca, j=1:n_cb
        if N[i,j]>0
            VI += N[i,j]*(log(N2[i]/N[i,j]) + log(N1[j]/N[i,j]))/Nsum
        end
    end
    VI/log(Nsum)
end

max_stars_repo_name: afternone/LPA

max_issues_repo_name: afternone/LPA

max_forks_repo_name: afternone/LPA


text:
#! /usr/bin/env julia

using Documenter
using GoogleCloud

makedocs(
    modules=[GoogleCloud], doctest=true,
    sitename="Google Cloud JSON APIs"
)

deploydocs(
    deps=Deps.pip("pygments", "mkdocs", "python-markdown-math"),
    repo="github.com/joshbode/GoogleCloud.jl.git",
    julia="0.5"
)


text:
# g + g^2 + ... + g^(T-1)
pvfactor(g, T) = (g ^ T - 1.0) / (g - 1.0);

# Present value. First entry not discounted.
present_value(xV, R) = sum(xV ./ (R .^ (0 : (length(xV)-1))));

# -----------


text:
include("./Functions.jl")
using Functions

val = BigInt(2) ^ BigInt(1000)
println(digitSum(val))

max_stars_repo_name: vmchale/julia-problem-solving

max_issues_repo_name: vmchale/julia-problem-solving

max_forks_repo_name: vmchale/julia-problem-solving


text:
"""
prime_factors(number)

Returns prime factors of `number` as a vector

# Example

```julia
prime_factors(50)          # returns [2,5,5]
prime_factors(0)           # returns []
prime_factors(100)         # returns [2, 2, 5, 5]
prime_factors(2560)        # returns [2, 2, 2, 2, 2, 2, 2, 2, 2, 5]
```

Contributed By:- [Ashwani Rathee](https://github.com/ashwani-rathee)
"""
function prime_factors(number::N) where {N<:Integer}
    i = 2
    factors = Vector{Int}()
    while i * i <= number
        if number % i == 1
            i += 1
        else
            number ÷= i
            push!(factors, i)
        end
    end
    if number > 1 == 1
        push!(factors, number)
    end
    return factors
end

max_issues_repo_name: AugustoCL/Julia

max_forks_repo_name: AugustoCL/Julia