text:
# CEP
"""
    setup_cep_opt_sets(ts_data::ClustData,opt_data::CEPData,opt_config::Dict{String,Any})
fetching sets from the time series (ts_data) and capacity expansion model data (opt_data) and returning Dictionary with Sets as Symbols
"""
function setup_opt_cep_set(ts_data::ClustData,
                            opt_data::OptDataCEP,
                            opt_config::Dict{String,Any})
  #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
  costs = opt_data.costs
  #`techs::OptVariable`: techs[tech] - OptDataCEPTech
  techs = opt_data.techs
  #`nodes::OptVariable`: nodes[tech,node] - OptDataCEPNode
  nodes = opt_data.nodes
  #`lines::OptVarible`: lines[tech,line] - OptDataCEPLine
  lines = opt_data.lines

  set=Dict{String,Array}()
  set["nodes"]=axes(nodes,"node")
  #Seperate sets for fossil and renewable technology
  set["tech"]=Array{String,1}()
  for categ in unique(getfield.(techs[:],:categ))
    if opt_config[categ]
      set["tech_"*categ]=axes(techs,"tech")[getfield.(techs[:], :categ).==categ]
      set["tech"]=[set["tech"];set["tech_"*categ]]
    end
  end
  #Compose a set of technologies without transmission
  set["tech_cap"]=deepcopy(set["tech"])
  set["tech_trans"]=Array{String,1}()
  set["tech_power"]=deepcopy(set["tech"])
  set["tech_energy"]=Array{String,1}()
  for (k,v) in set
    if occursin("tech",k) && occursin("_transmission",k)
      setdiff!(set["tech_cap"],v)
      set["tech_trans"]=[set["tech_trans"];v]
    end
    if occursin("tech",k) && String(k[end-1:end])=="_e"
      setdiff!(set["tech_power"],v)
      set["tech_energy"]=[set["tech_energy"];v]
    end
  end
  set["impact"]=axes(costs,"impact")
  set["impact_mon"]=[set["impact"][1]]
  set["impact_env"]=set["impact"][2:end]
  set["year"]=axes(costs,"year")
  set["account"]=axes(costs,"account")
  if opt_config["transmission"]
    set["lines"]=axes(opt_data.lines,"line")
    set["dir_transmission"]=["uniform","opposite"]
  end
  if opt_config["existing_infrastructure"]
    set["infrastruct"]=["new","ex"]
  else
    set["infrastruct"]=["new"]
  end
  set["sector"]=unique(getfield.(techs[:],:sector))
  set["time_K"]=1:ts_data.K
  set["time_T"]=1:ts_data.T
  set["time_T_e"]=0:ts_data.T
  if opt_config["seasonalstorage"]
    set["time_I_e"]=0:length(ts_data.k_ids)
    set["time_I"]=1:length(ts_data.k_ids)
  end
  return set
end

"""
    setup_cep_opt_basic(ts_data::ClustData,opt_data::CEPData,opt_config::Dict{String,Any},optimizer::DataType,optimizer_config::Dict{Symbol,Any})
setting up the basic core elements for a CEP-model
- a JuMP Model is setup and the optimizer is configured. The optimizer itself is passed on as a `optimizer`. It's configuration with `optimizer_config` - Each Symbol and the corresponding value in the Dictionary is passed on to the `with_optimizer` function in addition to the optimizer. For Gurobi an example Dictionary could look like `Dict{Symbol,Any}(:Method => 2, :OutputFlag => 0, :Threads => 2)`
- the sets are setup
"""
function setup_opt_cep_basic(ts_data::ClustData,
                            opt_data::OptDataCEP,
                            opt_config::Dict{String,Any},
                            optimizer::DataType,
                            optimizer_config::Dict{Symbol,Any})
   ## MODEL CEP ##
   # Initialize model
   model =  JuMP.Model(with_optimizer(optimizer;optimizer_config...))
   # Initialize info
   info=[opt_config["descriptor"]]
   # Setup set
   set=setup_opt_cep_set(ts_data, opt_data, opt_config)
   # Setup Model CEP
   return OptModelCEP(model,info,set)
 end

"""
    setup_opt_cep_basic_variables!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
Adding basic variables COST, CAP and GEN based on set
"""
function setup_opt_cep_basic_variables!(cep::OptModelCEP,
                                  ts_data::ClustData,
                                  opt_data::OptDataCEP)
  ## DATA ##
  set=cep.set

  ## VARIABLES ##
  # Cost
  push!(cep.info,"Variable COST[account, impact, tech] in $(set["impact"].*" "...)")
  @variable(cep.model, COST[account=set["account"],impact=set["impact"],tech=set["tech"]])
  # Capacity
  push!(cep.info,"Variable CAP[tech_cap, infrastruct, nodes] ≥ 0 in MW]")
  @variable(cep.model, CAP[tech=set["tech_cap"],infrastruct=set["infrastruct"] ,node=set["nodes"]]>=0)
  # Generation #
  push!(cep.info,"Variable GEN[sector, tech_power, t, k, node] in MW")
  @variable(cep.model, GEN[sector=set["sector"], tech=set["tech_power"], t=set["time_T"], k=set["time_K"], node=set["nodes"]])
  #end
  return cep
end

"""
     setup_opt_cep_lost_load!(cep::OptModelCEP, ts_data::ClustData, opt_data::OptDataCEP) set::Dict)
Adding variable SLACK, LL (LostLoad - if demand cannot be met with installed capacity -> Lost Load can be "purchased" to meet demand)
"""
function setup_opt_cep_lost_load!(cep::OptModelCEP,
                                  ts_data::ClustData,
                                  opt_data::OptDataCEP)
  ## DATA ##
  set=cep.set
  #ts_weights: k - weight of each period:
  ts_weights=ts_data.weights
  #ts_deltas:  t x k - Δt of each segment x period
  ts_deltas=ts_data.delta_t

  ## LOST LOAD ##
  # Slack variable #
  push!(cep.info,"Variable SLACK[sector, t, k, node] ≥ 0 in MW")
  @variable(cep.model, SLACK[sector=set["sector"], t=set["time_T"], k=set["time_K"], node=set["nodes"]] >=0)
  # Lost Load variable #
  push!(cep.info,"Variable LL[sector, node] ≥ 0 in MWh")
  @variable(cep.model, LL[sector=set["sector"], node=set["nodes"]] >=0)
  # Calculation of Lost Load
  push!(cep.info,"LL[sector, node] = Σ SLACK[sector, t, k, node] ⋅ ts_weights[k] ⋅ Δt[t,k] ∀ sector, node")
  @constraint(cep.model, [sector=set["sector"], node=set["nodes"]], cep.model[:LL][sector, node]==sum(cep.model[:SLACK][sector, t, k, node]*ts_weights[k]*ts_deltas[t,k] for t=set["time_T"], k=set["time_K"]))
  return cep
end

"""
     setup_opt_cep_lost_emission!(cep::OptModelCEP, ts_data::ClustData, opt_data::OptDataCEP)
Adding variable LE (LostEmission - if demand cannot be met without breaking Emission-constraint -> Lost Emission can be "purchased" to meet demand with "dirty" production)
"""
function setup_opt_cep_lost_emission!(cep::OptModelCEP,
                              ts_data::ClustData,
                              opt_data::OptDataCEP)
  ## DATA ##
  set=cep.set

  ## LOST EMISSION ##
  # Lost Emission variable #
  push!(cep.info,"Variable LE[impact_{environment}] ≥ 0 in kg")
  @variable(cep.model, LE[impact=set["impact"][2:end]] >=0)
  return cep
end

"""
     setup_opt_cep_fix_design_variables!(cep::OptModelCEP,ts_data::ClustData, opt_data::OptDataCEP,fixed_design_variables::Dict{String,Any})
Fixing variables CAP based on first stage vars
"""
function setup_opt_cep_fix_design_variables!(cep::OptModelCEP,
                                  ts_data::ClustData,
                                  opt_data::OptDataCEP,
                                  fixed_design_variables::Dict{String,Any})
  ## DATA ##
  set=cep.set
  cap=fixed_design_variables["CAP"]
  ## VARIABLES ##
  # Transmission
  if "tech_transmission" in keys(set)
    trans=fixed_design_variables["TRANS"]
    push!(cep.info,"TRANS[tech, 'new', line] = existing infrastructure ∀ tech_trans, line")
    @constraint(cep.model, [line=set["lines"], tech=set["tech_trans"]], cep.model[:TRANS][tech,"new",line]==trans[tech, "new", line])
  end
  # Capacity
  push!(cep.info,"CAP[tech, 'new', node] = existing infrastructure ∀ tech_cap, node")
  @constraint(cep.model, [node=set["nodes"], tech=set["tech_cap"]], cep.model[:CAP][tech,"new",node]==cap[tech, "new", node])
  return cep
end

"""
     setup_opt_cep_generation_el!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
add variable and fixed Costs and limit generation to installed capacity (and limiting time_series, if dependency in techs defined) for fossil and renewable power plants
"""
function setup_opt_cep_generation_el!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
    ## DATA ##
    set=cep.set
    #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
    costs = opt_data.costs
    #`techs::OptVariable`: techs[tech] - OptDataCEPTech
    techs = opt_data.techs
    #`nodes::OptVariable`: nodes[tech,node] - OptDataCEPNode
    nodes = opt_data.nodes
    #ts          Dict( tech-node ): t x k
    ts=ts_data.data
    #ts_weights: k - weight of each period:
    ts_weights=ts_data.weights
    #ts_deltas:  t x k - Δt of each segment x period
    ts_deltas=ts_data.delta_t

    ## GENERATION ELECTRICITY ##
    # Calculate Variable Costs
    push!(cep.info,"COST['var',impact,tech] = Σ_{t,k,node}GEN['el',t,k,node]⋅ ts_weights[k] ⋅ ts_deltas[t,k]⋅ var_costs[tech,impact] ∀ impact, tech_generation")
    @constraint(cep.model, [impact=set["impact"], tech=set["tech_generation"]], cep.model[:COST]["var",impact,tech]==sum(cep.model[:GEN]["el",tech,t,k,node]*ts_weights[k]*ts_deltas[t,k]*costs[tech,node,set["year"][1],"var",impact] for node=set["nodes"], t=set["time_T"], k=set["time_K"]))
    # Calculate Fixed Costs
    push!(cep.info,"COST['cap_fix',impact,tech] = Σ_{t,k}(ts_weights ⋅ ts_deltas[t,k])/8760h ⋅ Σ_{node}CAP[tech,'new',node] ⋅ cap_costs[tech,impact] ∀ impact, tech_generation")
    @constraint(cep.model, [impact=set["impact"], tech=set["tech_generation"]], cep.model[:COST]["cap_fix",impact,tech]==sum(ts_weights[k]*ts_deltas[t,k] for t=set["time_T"], k=set["time_K"])/8760* sum(cep.model[:CAP][tech,"new",node] *costs[tech,node,set["year"][1],"cap_fix",impact] for node=set["nodes"]))

    # Limit the generation of dispathables to the infrastructing capacity of dispachable power plants
    push!(cep.info,"0 ≤ GEN['el',tech, t, k, node] ≤ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_generation{dispatchable}, t, k")
    # Limit the generation of dispathables to the infrastructing capacity of non-dispachable power plants
    push!(cep.info,"0 ≤ GEN['el',tech, t, k, node] ≤ Σ_{infrastruct}CAP[tech,infrastruct,node]*ts[tech-node,t,k] ∀ node, tech_generation{non_dispatchable}, t, k")
    for tech in set["tech_generation"]
      # Limit the generation of dispathables to the infrastructing capacity of dispachable power plants
      if techs[tech].time_series=="none"
        @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]], 0 <=cep.model[:GEN]["el",tech, t, k, node])
        @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]],     cep.model[:GEN]["el",tech, t, k, node] <=sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]))
      else
        # Limit the generation of dispathables to the infrastructing capacity of non-dispachable power plants
        @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]], 0 <=cep.model[:GEN]["el",tech, t, k, node])
        @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]],     cep.model[:GEN]["el",tech,t,k,node] <= sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"])*ts[techs[tech].time_series*"-"*node][t,k])
      end
    end

    return cep
end

"""
     setup_opt_cep_storage!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
add variables INTRASTORGEN and INTRASTOR, variable and fixed Costs, limit generation to installed power-capacity, connect simple-storage levels (within period) with generation
basis for either simplestorage or seasonalstorage
"""
function setup_opt_cep_storage!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
    ## DATA ##
    set=cep.set
    #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
    costs = opt_data.costs
    #`techs::OptVariable`: techs[tech] - OptDataCEPTech
    techs = opt_data.techs
    #ts_weights: k - weight of each period:
    ts_weights=ts_data.weights
    #ts_deltas:  t x k - Δt of each segment x period
    ts_deltas=ts_data.delta_t

    ## VARIABLE ##existing_infrastructure
    # Storage has additional element 0 for storage at hour 0 of day
    push!(cep.info,"Variable INTRASTOR[sector, tech_storage_e, t, k, node] ≥ 0 in MWh")
    @variable(cep.model, INTRASTOR[sector=set["sector"], tech=set["tech_storage_e"], t=set["time_T_e"], k=set["time_K"], node=set["nodes"]] >=0)
    # Storage generation is necessary for the efficiency
    #push!(cep.info,"Variable INTRASTORGEN[sector, dir, tech, t, k, node] ≥ 0 in MW")
    #@variable(cep.model, INTRASTORGEN[sector=set["sector"], dir=set["dir_storage"], tech=set["tech_storage_p"], t=set["time_T"], k=set["time_K"], node=set["nodes"]] >=0)
    ## STORAGE ##
    # Calculate Variable Costs
    push!(cep.info,"COST['var',impact,tech] = 0 ∀ impact, tech_storage")
    @constraint(cep.model, [impact=set["impact"], tech=[set["tech_storage_in"];set["tech_storage_out"];set["tech_storage_e"]]], cep.model[:COST]["var",impact,tech]==0)
    # Fix Costs storage
    push!(cep.info,"COST['fix',impact,tech] = Σ_{t,k}(ts_weights ⋅ ts_deltas[t,k])/8760h ⋅ Σ_{node}CAP[tech,'new',node] ⋅ costs[tech,node,year,'cap_fix',impact] ∀ impact, tech_storage")
    @constraint(cep.model, [tech=[set["tech_storage_in"];set["tech_storage_out"];set["tech_storage_e"]], impact=set["impact"]], cep.model[:COST]["cap_fix",impact,tech]==sum(ts_weights[k]*ts_deltas[t,k] for t=set["time_T"], k=set["time_K"])/8760* sum(cep.model[:CAP][tech,"new",node]*costs[tech,node,set["year"][1],"cap_fix",impact] for node=set["nodes"]))
    # Limit the Generation of the theoretical power part of the battery to its installed power
    push!(cep.info,"0 ≤ GEN['el',tech, t, k, node] ≤ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_storage_out, t, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_out"], t=set["time_T"], k=set["time_K"]], 0 <= cep.model[:GEN]["el",tech,t,k,node])
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_out"], t=set["time_T"], k=set["time_K"]], cep.model[:GEN]["el",tech,t,k,node]<=sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]))
    push!(cep.info,"0 ≥ GEN['el',tech, t, k, node] ≥ (-1) ⋅ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_storage_in, t, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_in"], t=set["time_T"], k=set["time_K"]], 0 >= cep.model[:GEN]["el",tech,t,k,node])
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_in"], t=set["time_T"], k=set["time_K"]], cep.model[:GEN]["el",tech,t,k,node]>=(-1)*sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]))
    # Connect the previous storage level and the integral of the flows with the new storage level
    push!(cep.info,"INTRASTOR['el',tech, t, k, node] = INTRASTOR['el',tech, t-1, k, node] η[tech]^(ts_deltas[t,k]/732h) + ts_deltas[t,k] ⋅ (-1) ⋅ (GEN['el',tech_{in}, t, k, node] ⋅ η[tech_{in}] + GEN['el',tech_{out}, t, k, node] / η[tech_{out}]) ∀ node, tech_storage_e, t, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], t in set["time_T"], k=set["time_K"]], cep.model[:INTRASTOR]["el",tech,t,k,node]==cep.model[:INTRASTOR]["el",tech,t-1,k,node]*(techs[tech].eff)^(ts_deltas[t,k]/732) - ts_deltas[t,k] * (cep.model[:GEN]["el",split(tech,"_")[1]*"_in",t,k,node] * techs[split(tech,"_")[1]*"_in"].eff + cep.model[:GEN]["el",split(tech,"_")[1]*"_out",t,k,node] / techs[split(tech,"_")[1]*"_out"].eff))

    push!(cep.info,"CAP[tech_{out}, 'new', node] = CAP[tech_{in}, 'new', node] ∀ node, tech_{EUR-Cap-Cost out/in==0}")
    for tech in set["tech_storage_out"]
      for node in set["nodes"]
        if costs[tech,node,set["year"][1],"cap_fix",set["impact"][1]]==0 || costs[split(tech,"_")[1]*"_in",node,set["year"][1],"cap_fix",set["impact"][1]]==0
          @constraint(cep.model, cep.model[:CAP][tech,"new",node]==cep.model[:CAP][split(tech,"_")[1]*"_in","new",node])
        end
      end
    end

    return cep
end

"""
     setup_opt_cep_simplestorage!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
Adding only intra-day storage:
Looping constraint for each period (same start and end level for all periods) and limit storage to installed energy-capacity
"""
function setup_opt_cep_simplestorage!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
    ## DATA ##
    set=cep.set
    ## INTRASTORAGE ##
    # Limit the storage of the theoretical energy part of the battery to its installed power
    push!(cep.info,"INTRASTOR['el',tech, t, k, node] ≤ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_storage, t, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], t=set["time_T"], k=set["time_K"]], cep.model[:INTRASTOR]["el",tech,t,k,node]<=sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]))
    # Set storage level at beginning and end of day equal
    push!(cep.info,"INTRASTOR['el',tech, '0', k, node] = INTRASTOR['el',tech, 't[end]', k, node] ∀ node, tech_storage_e, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], k=set["time_K"]], cep.model[:INTRASTOR]["el",tech,0,k,node]== cep.model[:INTRASTOR]["el",tech,set["time_T_e"][end],k,node])
    # Set the storage level at the beginning of each representative day to the same
    push!(cep.info,"INTRASTOR['el',tech, '0', k, node] = INTRASTOR['el',tech, '0', k, node] ∀ node, tech_storage_e, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], k=set["time_K"]], cep.model[:INTRASTOR]["el",tech,0,k,node]== cep.model[:INTRASTOR]["el",tech,0,1,node])
    return cep
end

"""
     setup_opt_cep_seasonalstorage!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
Adding inter-day storage:
add variable INTERSTOR, calculate seasonal-storage-level and limit total storage to installed energy-capacity
"""
function setup_opt_cep_seasonalstorage!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
    ## DATA ##
    set=cep.set
    #K identification numbers
    k_ids=ts_data.k_ids

    ## VARIABLE ##
    # Storage
    push!(cep.info,"Variable INTERSTOR[sector, tech, i, node] ≥ 0 in MWh")
    @variable(cep.model, INTERSTOR[sector=set["sector"], tech=set["tech_storage_e"], i=set["time_I_e"], node=set["nodes"]]>=0)

    ## INTERSTORAGE ##
    # Set storage level at the beginning of the year equal to the end of the year
    push!(cep.info,"INTERSTOR['el',tech, '0', node] = INTERSTOR['el',tech, 'end', node] ∀ node, tech_storage, t, k")
    @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"]], cep.model[:INTERSTOR]["el",tech,0,node]== cep.model[:INTERSTOR]["el",tech,set["time_I_e"][end],node])
    # Connect the previous seasonal-storage level and the daily difference of the corresponding simple-storage with the new seasonal-storage level
    push!(cep.info,"INTERSTOR['el',tech, i+1, node] = INTERSTOR['el',tech, i, node] + INTRASTOR['el',tech, 'k[i]', 't[end]', node] - INTRASTOR['el',tech, 'k[i]', '0', node] ∀ node, tech_storage_e, i")
    # Limit the total storage (seasonal and simple) to be greater than zero and less than total storage cap
    push!(cep.info,"0 ≤ INTERSTOR['el',tech, i, node] + INTRASTOR['el',tech, t, k[i], node] ≤ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_storage_e, i, t")
    push!(cep.info,"0 ≤ INTERSTOR['el',tech, i, node] + INTRASTOR['el',tech, t, k[i], node] ≤ Σ_{infrastruct} CAP[tech,infrastruct,node] ∀ node, tech_storage_e, i, t")
    for i in set["time_I"]
        @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"]], cep.model[:INTERSTOR]["el",tech,i,node] == cep.model[:INTERSTOR]["el",tech,i-1,node] + cep.model[:INTRASTOR]["el",tech,set["time_T"][end],k_ids[i],node] - cep.model[:INTRASTOR]["el",tech,0,k_ids[i],node])
        @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], t=set["time_T_e"]], 0 <= cep.model[:INTERSTOR]["el",tech,i,node]+cep.model[:INTRASTOR]["el",tech,t,k_ids[i],node])
        @constraint(cep.model, [node=set["nodes"], tech=set["tech_storage_e"], t=set["time_T_e"]], cep.model[:INTERSTOR]["el",tech,i,node]+cep.model[:INTRASTOR]["el",tech,t,k_ids[i],node] <= sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]))
    end
    return cep
end

"""
     setup_opt_cep_transmission!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
Setup variable FLOW and TRANS, calculate fixed and variable COSTs, set CAP-trans to zero, limit FLOW with TRANS, calculate GEN-trans for each node
"""
function setup_opt_cep_transmission!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
    ## DATA ##
    set=cep.set
    #`costs::OptVariable`: costs[tech,node,year,account,impact] - annulized costs [USD in USD/MW_el, CO2 in kg-CO₂-eq./MW_el]`
    costs = opt_data.costs
    #`lines::OptVarible`: lines[tech,line] - OptDataCEPLine
    lines = opt_data.lines
    #ts_weights: k - weight of each period:
    ts_weights=ts_data.weights
    #ts_deltas:  t x k - Δt of each segment x period
    ts_deltas=ts_data.delta_t
    ## VARIABLE ##
    # Add varibale FLOW
    push!(cep.info,"Variable FLOW[sector, dir, tech_transmission, t, k, line] ≥ 0 in MW")
    @variable(cep.model, FLOW[sector=set["sector"], dir=set["dir_transmission"], tech=set["tech_transmission"], t=set["time_T"], k=set["time_K"], line=set["lines"]] >= 0)
    # Add variable TRANS
    push!(cep.info,"Variable TRANS[tech_transmission,  infrastruct, lines] ≥ 0 in MW")
    @variable(cep.model, TRANS[tech=set["tech_transmission"], infrastruct=set["infrastruct"], line=set["lines"]] >= 0)

    ## TRANSMISSION ##
    # Calculate Variable Costs
    push!(cep.info,"COST['var',impact,tech] = 0 ∀ impact, tech_transmission")
    @constraint(cep.model, [impact=set["impact"], tech=set["tech_transmission"]], cep.model[:COST]["var",impact,tech] == 0)
    # Calculate Fixed Costs
    push!(cep.info,"COST['cap-fix',impact,tech] = Σ_{t,k}(ts_weights ⋅ ts_deltas[t,k])/8760h ⋅ Σ_{node}(TRANS[tech,'new',line] ⋅ length[line]) ⋅ (cap_costs[tech,impact]+fix_costs[tech,impact]) ∀ impact, tech_transmission")
    @constraint(cep.model, [impact=set["impact"], tech=set["tech_transmission"]], cep.model[:COST]["cap_fix",impact,tech] == sum(ts_weights[k]*ts_deltas[t,k] for t=set["time_T"], k=set["time_K"])/8760* sum(cep.model[:TRANS][tech,"new",line]*lines[tech,line].length *(costs[tech,lines[tech,line].node_start,set["year"][1],"cap_fix",impact]) for line=set["lines"]))
    # Limit the flow per line to the existing infrastructure
    push!(cep.info,"| FLOW['el', dir, tech, t, k, line] | ≤ Σ_{infrastruct}TRANS[tech,infrastruct,line] ∀ line, tech_transmission, t, k")
    @constraint(cep.model, [line=set["lines"], dir=set["dir_transmission"], tech=set["tech_transmission"], t=set["time_T"], k=set["time_K"]], cep.model[:FLOW]["el",dir, tech, t, k, line] <= sum(cep.model[:TRANS][tech,infrastruct,line] for infrastruct=set["infrastruct"]))
    # Calculate the sum of the flows for each node
    push!(cep.info,"GEN['el',tech, t, k, node] = Σ_{line-end(node)} FLOW['el','uniform',tech, t, k, line] - Σ_{line_pos} FLOW['el','opposite',tech, t, k, line] / (η[tech]⋅length[line]) + Σ_{line-start(node)} Σ_{line_pos} FLOW['el','opposite',tech, t, k, line] - FLOW['el','uniform',tech, t, k, line] / (η[tech]⋅length[line])∀ tech_transmission, t, k")
    for node in set["nodes"]
      @constraint(cep.model, [tech=set["tech_transmission"], t=set["time_T"], k=set["time_K"]], cep.model[:GEN]["el",tech, t, k, node] == sum(cep.model[:FLOW]["el","uniform",tech, t, k, line_end] - cep.model[:FLOW]["el","opposite",tech, t, k, line_end]/lines[tech,line_end].eff for line_end=set["lines"][getfield.(lines[tech,:], :node_end).==node]) + sum(cep.model[:FLOW]["el","opposite",tech, t, k, line_start] - cep.model[:FLOW]["el","uniform",tech, t, k, line_start]/lines[tech,line_start].eff for line_start=set["lines"][getfield.(lines[tech,:], :node_start).==node]))
    end
    return cep
end

"""
    setup_opt_cep_demand!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP,lost_load_cost::Dict{String,Number}=Dict{String,Number}("el"=>Inf))
Add demand which shall be matched by the generation (GEN)
"""
function setup_opt_cep_demand!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP;
                            lost_load_cost::Dict{String,Number}=Dict{String,Number}("el"=>Inf))
  ## DATA ##
  set=cep.set
  #ts          Dict( tech-node ): t x k
  ts=ts_data.data

  ## DEMAND ##
  if "tech_transmission" in keys(set) && lost_load_cost["el"]!=Inf
    # Force the demand and slack to match the generation either with transmission
    push!(cep.info,"Σ_{tech}GEN['el',tech,t,k,node] = ts[el_demand-node,t,k]-SLACK['el',t,k,node] ∀ node,t,k")
    @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]], sum(cep.model[:GEN]["el",tech,t,k,node] for tech=set["tech_power"]) == ts["el_demand-"*node][t,k]-cep.model[:SLACK]["el",t,k,node])
  elseif !("tech_transmission" in keys(set)) && lost_load_cost["el"]!=Inf
    # or on copperplate
    push!(cep.info,"Σ_{tech,node}GEN['el',tech,t,k,node]= Σ_{node}ts[el_demand-node,t,k]-SLACK['el',t,k,node] ∀ t,k")
    @constraint(cep.model, [t=set["time_T"], k=set["time_K"]], sum(cep.model[:GEN]["el",tech,t,k,node] for node=set["nodes"], tech=set["tech_power"]) == sum(ts["el_demand-"*node][t,k]-cep.model[:SLACK]["el",t,k,node] for node=set["nodes"]))
  elseif "tech_transmission" in keys(set) && lost_load_cost["el"]==Inf
    # Force the demand without slack to match the generation either with transmission
    push!(cep.info,"Σ_{tech}GEN['el',tech,t,k,node] = ts[el_demand-node,t,k] ∀ node,t,k")
    @constraint(cep.model, [node=set["nodes"], t=set["time_T"], k=set["time_K"]], sum(cep.model[:GEN]["el",tech,t,k,node] for tech=set["tech_power"]) == ts["el_demand-"*node][t,k])
  else
    # or on copperplate
    push!(cep.info,"Σ_{tech,node}GEN['el',tech,t,k,node]= Σ_{node}ts[el_demand-node,t,k]∀ t,k")
    @constraint(cep.model, [t=set["time_T"], k=set["time_K"]], sum(cep.model[:GEN]["el",tech,t,k,node] for node=set["nodes"], tech=set["tech_power"]) == sum(ts["el_demand-"*node][t,k] for node=set["nodes"]))
  end
  return cep
end

"""
     setup_opt_cep_co2_limit!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP;co2_limit::Number=Inf,lost_emission_cost::Dict{String,Number}=Dict{String,Number}("CO2"=>Inf))
Add co2 emission constraint
"""
function setup_opt_cep_co2_limit!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP;
                            co2_limit::Number=Inf,
                            lost_emission_cost::Dict{String,Number}=Dict{String,Number}("CO2"=>Inf))
  ## DATA ##
  set=cep.set
  #ts          Dict( tech-node ): t x k
  ts=ts_data.data
  #ts_weights: k - weight of each period:
  ts_weights=ts_data.weights
  #ts_deltas:  t x k - Δt of each segment x period
  ts_deltas=ts_data.delta_t

  ## EMISSIONS ##
  if lost_emission_cost["CO2"]!=Inf
    # Limit the Emissions with co2_limit if it exists
    push!(cep.info,"ΣCOST_{account,tech}[account,'$(set["impact"][1])',tech] ≤ LE['CO2'] + co2_limit Σ_{node,t,k} ts[el_demand-node,t,k] ⋅ ts_weights[k] ⋅ ts_deltas[t,k]")
    @constraint(cep.model, sum(cep.model[:COST][account,"CO2",tech] for account=set["account"], tech=set["tech"])<= cep.model[:LE]["CO2"] +  co2_limit*sum(ts["el_demand-"*node][t,k]*ts_deltas[t,k]*ts_weights[k] for t=set["time_T"], k=set["time_K"], node=set["nodes"]))
  else
    # Limit the Emissions with co2_limit if it exists
    # Total demand can also be determined with the function get_total_demand() edit both in case of changes of e.g. ts_deltas
    push!(cep.info,"ΣCOST_{account,tech}[account,'$(set["impact"][1])',tech] ≤ co2_limit ⋅ Σ_{node,t,k} ts[el_demand-node,t,k] ⋅ ts_weights[k] ⋅ ts_deltas[t,k]")
    @constraint(cep.model, sum(cep.model[:COST][account,"CO2",tech] for account=set["account"], tech=set["tech"])<= co2_limit*sum(ts["el_demand-$node"][t,k]*ts_weights[k]*ts_deltas[t,k] for node=set["nodes"], t=set["time_T"], k=set["time_K"]))
  end
  return cep
end

"""
     setup_opt_cep_existing_infrastructure!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
fixing existing infrastructure to CAP[tech, 'ex', node]
"""
function setup_opt_cep_existing_infrastructure!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
  ## DATA ##
  set=cep.set
  #`nodes::OptVariable`: nodes[tech,node] - OptDataCEPNode
  nodes = opt_data.nodes
  #`lines::OptVarible`: lines[tech,line] - OptDataCEPLine
  lines = opt_data.lines

  ## ASSIGN VALUES ##
  # Assign the existing capacity from the nodes table
  push!(cep.info,"CAP[tech, 'ex', node] = existing infrastructure ∀ node, tech")
  @constraint(cep.model, [node=set["nodes"], tech=set["tech_cap"]], cep.model[:CAP][tech,"ex",node]==nodes[tech,node].power_ex)
  if "transmission" in keys(set)
    push!(cep.info,"TRANS[tech, 'ex', line] = existing infrastructure ∀ tech, line")
    @constraint(cep.model, [line=set["lines"], tech=set["tech_trans"]], cep.model[:TRANS][tech,"ex",line]==lines[tech,line].power_ex)
  end
  return cep
end

"""
     setup_opt_cep_limit_infrastructure!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
limit infrastructure setup of CAP[tech, sum(infrastuct), node]
NOTE just for CAP not for TRANS implemented
"""
function setup_opt_cep_limit_infrastructure!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP)
  ## DATA ##
  set=cep.set
  #`nodes::OptVariable`: nodes[tech,node] - OptDataCEPNode
  nodes = opt_data.nodes
  #`lines::OptVarible`: lines[tech,line] - OptDataCEPLine
  lines = opt_data.lines

  ## ASSIGN VALUES ##
  # Limit the capacity for each tech at each node with the limit provided in nodes table in column infrastruct
  push!(cep.info,"∑_{infrastuct} CAP[tech, infrastruct, node] <= limit infrastructure ∀ tech_cap, node")
  @constraint(cep.model, [node=set["nodes"], tech=set["tech_cap"]], sum(cep.model[:CAP][tech,infrastruct,node] for infrastruct=set["infrastruct"]) <= nodes[tech,node].power_lim)
  if "transmission" in keys(set)
    push!(cep.info,"∑_{infrastuct} TRANS[tech, infrastruct, line] <= limit infrastructure ∀ tech_trans, line")
    @constraint(cep.model, [line=set["lines"], tech=set["tech_trans"]], sum(cep.model[:TRANS][tech,infrastruct,line] for infrastruct=set["infrastruct"]) <= lines[tech,line].power_lim)
  end
  return cep
end

"""
     setup_opt_cep_objective!(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP)
Calculate total system costs and set as objective
"""
function setup_opt_cep_objective!(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP;
                            lost_load_cost::Dict{String,Number}=Dict{String,Number}("el"=>Inf),
                            lost_emission_cost::Dict{String,Number}=Dict{String,Number}("CO2"=>Inf))
  ## DATA ##
  set=cep.set

  ## OBJECTIVE ##
  # Minimize the total €-Costs s.t. the Constraints introduced above
  if lost_load_cost["el"]==Inf && lost_emission_cost["CO2"]==Inf
    push!(cep.info,"min Σ_{account,tech}COST[account,'$(set["impact"][1])',tech] st. above")
    @objective(cep.model, Min,  sum(cep.model[:COST][account,set["impact"][1],tech] for account=set["account"], tech=set["tech"]))
  elseif lost_load_cost["el"]!=Inf && lost_emission_cost["CO2"]==Inf
    push!(cep.info,"min Σ_{account,tech}COST[account,'$(set["impact"][1])',tech] + Σ_{node} LL['el'] ⋅ $(lost_load_cost["el"]) st. above")
    @objective(cep.model, Min,  sum(cep.model[:COST][account,set["impact"][1],tech] for account=set["account"], tech=set["tech"]) + sum(cep.model[:LL]["el",node] for node=set["nodes"])*lost_load_cost["el"])
  elseif lost_load_cost["el"]==Inf && lost_emission_cost["CO2"]!=Inf
    push!(cep.info,"min Σ_{account,tech}COST[account,'$(set["impact"][1])',tech] +  LE['CO2'] ⋅ $(lost_emission_cost["CO2"]) st. above")
    @objective(cep.model, Min,  sum(cep.model[:COST][account,set["impact"][1],tech] for account=set["account"], tech=set["tech"]) +  cep.model[:LE]["CO2"]*lost_emission_cost["CO2"])
  else
    push!(cep.info,"min Σ_{account,tech}COST[account,'$(set["impact"][1])',tech] + Σ_{node} LL['el'] ⋅ $(lost_load_cost["el"]) +  LE['CO2'] ⋅ $(lost_emission_cost["CO2"]) st. above")
    @objective(cep.model, Min,  sum(cep.model[:COST][account,set["impact"][1],tech] for account=set["account"], tech=set["tech"]) + sum(cep.model[:LL]["el",node] for node=set["nodes"])*lost_load_cost["el"] + cep.model[:LE]["CO2"]*lost_emission_cost["CO2"])
  end
  return cep
end

"""
     solve_opt_cep(cep::OptModelCEP,ts_data::ClustData,opt_data::OptDataCEP,opt_config::Dict{String,Any})
solving the cep model and writing it's results and `co2_limit` into an OptResult-Struct
"""
function solve_opt_cep(cep::OptModelCEP,
                            ts_data::ClustData,
                            opt_data::OptDataCEP,
                            opt_config::Dict{String,Any})
  optimize!(cep.model)
  status=Symbol(termination_status(cep.model))
  objective=objective_value(cep.model)
  total_demand=get_total_demand(cep,ts_data)
  variables=Dict{String,Any}()
  # cv - Cost variable, dv - design variable, which is used to fix variables in a dispatch model, ov - operational variable
  variables["COST"]=OptVariable(cep,:COST,"cv")
  variables["CAP"]=OptVariable(cep,:CAP,"dv")
  variables["GEN"]=OptVariable(cep,:GEN,"ov")
  lost_load=0
  lost_emission=0
  if opt_config["lost_load_cost"]["el"]!=Inf
    variables["SLACK"]=OptVariable(cep,:SLACK,"sv")
    variables["LL"]=OptVariable(cep,:LL,"sv")
    lost_load=sum(variables["LL"].data)
  end
  if opt_config["lost_emission_cost"]["CO2"]!=Inf
    variables["LE"]=OptVariable(cep,:LE,"sv")
    lost_emission=sum(variables["LE"].data)
  end
  if opt_config["storage_in"] && opt_config["storage_out"] && opt_config["storage_e"]
    variables["INTRASTOR"]=OptVariable(cep,:INTRASTOR,"ov")
    if opt_config["seasonalstorage"]
      variables["INTERSTOR"]=OptVariable(cep,:INTERSTOR,"ov")
    end
  end
  if opt_config["transmission"]
    variables["TRANS"]=OptVariable(cep,:TRANS,"dv")
    variables["FLOW"]=OptVariable(cep,:FLOW,"ov")
  end
  get_met_cap_limit(cep, opt_data, variables)
  currency=variables["COST"].axes[2][1]
  if lost_load==0 && lost_emission==0
    opt_config["print_flag"] && @info("Solved Scenario $(opt_config["descriptor"]): "*String(status)*" min COST: $(round(objective,sigdigits=4)) [$currency] ⇨ $(round(objective/total_demand,sigdigits=4)) [$currency per MWh] s.t. Emissions ≤ $(opt_config["co2_limit"]) [kg-CO₂-eq. per MWh]")
  else
    cost=variables["COST"]
    opt_config["print_flag"] && @info("Solved Scenario $(opt_config["descriptor"]): "*String(status)*" min COST: $(round(sum(cost[:,axes(cost,"impact")[1],:]),sigdigits=4)) [$currency] ⇨ $(round(sum(cost[:,axes(cost,"impact")[1],:])/total_demand,sigdigits=4)) [$currency per MWh] with LL: $lost_load [MWh] s.t. Emissions ≤ $(opt_config["co2_limit"]) + $(round(lost_emission/total_demand,sigdigits=4)) (violation) [kg-CO₂-eq. per MWh]")
  end
  opt_info=Dict{String,Any}("total_demand"=>total_demand,"model"=>cep.info,)
  return OptResult(status,objective,variables,cep.set,opt_config,opt_info)
end


text:
using StaticArrays
using SparseArrays: SparseMatrixCSC

# -----------------------------------
# iterating over an m collection
# -----------------------------------

_mvec(::CartesianIndex{0}) = SVector(IntS(0))

_mvec(mpre::CartesianIndex) = SVector(Tuple(mpre)..., - sum(Tuple(mpre)))

struct MRange{N, TI, T2}
   ll::SVector{N, TI}
   cartrg::T2
end

Base.length(mr::MRange) = sum(_->1, _mrange(mr.ll))

"""
Given an l-vector `ll` iterate over all combinations of `mm` vectors  of
the same length such that `sum(mm) == 0`
"""
_mrange(ll) = MRange(ll, Iterators.Stateful(
                        CartesianIndices(ntuple(i -> -ll[i]:ll[i], length(ll)-1))))

function Base.iterate(mr::MRange{1, TI}, args...) where {TI}
   if isempty(mr.cartrg)
      return nothing
   end
   while !isempty(mr.cartrg)
      popfirst!(mr.cartrg)
   end
   return SVector{1, TI}(0), nothing
end

function Base.iterate(mr::MRange, args...)
   while true
      if isempty(mr.cartrg)
         return nothing
      end
      mpre = popfirst!(mr.cartrg)
      if abs(sum(mpre.I)) <= mr.ll[end]
         return _mvec(mpre), nothing
      end
   end
   error("we should never be here")
end

# _mrange_prefilter(ll) = (
#                   _mvec(mpre) for mpre in CartesianIndices(
#                                 ntuple(i -> -ll[i]:ll[i], length(ll)-1) )
#               )

"""
`@generated function nfcalls(::Val{N}, f)`

Effectively generates a loop of functions calls, but fully unrolled and
therefore type-stable:
```{julia}
f(Val(1))
f(Val(2))
f(Val(3))
# ...
f(Val(N))
```
"""
@generated function nfcalls(::Val{N}, f) where {N}
   code = Expr[]
   for n = 1:N
      push!(code, :(f(Val($n))))
   end
   quote
      $(Expr(:block, code...))
      return nothing
   end
end

"""
`@generated function valnmapreduce(::Val{N}, v, f)`

Generates a map-reduce like code, with fully unrolled loop which makes this
type-stable,
```{julia}
begin
   v += f(Val(1))
   v += f(Val(2))
   # ...
   v += f(Val(N))
   return v
end
```
"""
@generated function valnmapreduce(::Val{N}, v, f) where {N}
   code = Expr[]
   for n = 1:N
      push!(code, :(v += f(Val($n))))
   end
   quote
      $(Expr(:block, code...))
      return v
   end
end

# (de-)serialize a sparse matric
Base.Dict(A::SparseMatrixCSC) =
   Dict("__id__" => "SparseMatrixCSC",
        "colptr" => A.colptr,
        "rowval" => A.rowval,
        "nzval" => A.nzval,
        "m" => m,
        "n" => n )

Base.convert(::Val{:SparseMatrixCSC}, D::Dict) =
   SparseMatrixCSC(D)

SparseMatrixCSC(D::Dict) =
   SparseMatrixCSC(D["m"], D["n"], D["colptr"], D["rowval"], D["nzval"])

ext: jl

max_stars_repo_name: cortner/SHIPs

max_issues_repo_name: cortner/SHIPs

max_forks_repo_name: cortner/SHIPs


text:
# Copyright (c) 2017: Miles Lubin and contributors
# Copyright (c) 2017: Google Inc.
#
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

module Variable

import MathOptInterface

const MOI = MathOptInterface
const MOIU = MOI.Utilities
const MOIB = MOI.Bridges

include("bridge.jl")
include("map.jl")
include("set_map.jl")
include("single_bridge_optimizer.jl")

include("bridges/flip_sign.jl")
include("bridges/free.jl")
include("bridges/rsoc_to_psd.jl")
include("bridges/soc_rsoc.jl")
include("bridges/vectorize.jl")
include("bridges/zeros.jl")

"""
    add_all_bridges(model, ::Type{T}) where {T}

Add all bridges defined in the `Bridges.Variable` submodule to `model`.

The coefficient type used is `T`.
"""
function add_all_bridges(model, ::Type{T}) where {T}
    MOI.Bridges.add_bridge(model, ZerosBridge{T})
    MOI.Bridges.add_bridge(model, FreeBridge{T})
    MOI.Bridges.add_bridge(model, NonposToNonnegBridge{T})
    MOI.Bridges.add_bridge(model, VectorizeBridge{T})
    MOI.Bridges.add_bridge(model, SOCtoRSOCBridge{T})
    MOI.Bridges.add_bridge(model, RSOCtoSOCBridge{T})
    MOI.Bridges.add_bridge(model, RSOCtoPSDBridge{T})
    return
end

end

max_stars_repo_name: JuliaOpt/MathOptInterface

max_issues_repo_name: JuliaOpt/MathOptInterface

max_forks_repo_name: JuliaOpt/MathOptInterface


text:
function luhntest(x::Integer)
    d = reverse(digits(x))
    s = sum(d[1:2:end])
    s += sum(sum.(digits.(2d[2:2:end])))
    return s % 10 == 0
end

for card in [49927398716, 49927398717, 1234567812345678, 1234567812345670]
    println(luhntest(card) ? "PASS " : "FAIL ", card)
end

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
include("Crystal.jl")
include("PhantomCrystal.jl")
const CRYSTAL_TYPE = "crystals.crystal"
const PHANTOMCRYSTAL_TYPE = "crystals.phantomcrystal"
AetherlangObject(c::CrystalsCrystal) = AetherlangObject{CrystalsCrystal}(c, Ref(CRYSTAL_TYPE))

AE_crystal(line::Ref{UInt}, ns::Namespace, args...)::AetherlangObject = AetherlangObject(CrystalsCrystal(Set([arg.dataref for arg in args])))
function AE_add(line::Ref{UInt}, ns::Namespace, crs::AetherlangObject{CrystalsCrystal}, x::AetherlangObject)::AetherlangObject
    T::Type = Union{typeof(x.dataref), crystaltype(typeof(crs.dataref))}
    AetherlangObject(CrystalsCrystal(Set(T[crs.dataref.data..., x.dataref])))
end
function AE_remove(line::Ref{UInt}, ns::Namespace, crs::AetherlangObject{CrystalsCrystal}, x::AetherlangObject)::AetherlangObject
    AetherlangObject(CrystalsCrystal(Set([e for e in crs.dataref.data if e != x.dataref])))
end

crystals_namespace_modify = Namespace(
    "crystal" => AetherlangObject(AE_crystal),
    "add" => AetherlangObject(AE_add),
    "remove" => AetherlangObject(AE_remove)
)

max_stars_repo_name: Aetherlang/aetherlang

max_issues_repo_name: gojakuch/aetherlang

max_forks_repo_name: gojakuch/aetherlang


text:
class C {
    public static int test(int h, int l) {
	while (h > 0) {
	    h--;
	}

	return l;
    }

    public static void main(String[] args) {
	int{H} x = 7;
	int{L} y = 0;
	int{L} r = test(x,y);
    }
}

max_stars_repo_name: HarvardPL/cryptoerase

max_issues_repo_name: HarvardPL/cryptoerase

max_forks_repo_name: HarvardPL/cryptoerase


text:
@testset "4.4.9 trig^m (a+b cot^n+c cot^(2 n))^p" begin
    (a, b, c, d, e, x, ) = @variables a b c d e x

    #= ::Package:: =#

    #= ::Title:: =#
    #=Integrands*of*the*form*Trig(d+e*x)^m*(a+b*cot(d+e*x)^n+c*cot(d+e*x)^(2*n))^p=#

    #= ::Section:: =#
    #=Integrands*of*the*form*sin(d+e*x)^m*(a+b*cot(d+e*x)^n+c*cot(d+e*x)^(2*n))^p=#

    #= ::Section:: =#
    #=Integrands*of*the*form*cos(d+e*x)^m*(a+b*cot(d+e*x)^n+c*cot(d+e*x)^(2*n))^p=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*cot(d+e*x)^m*(a+b*cot(d+e*x)^n+c*cot(d+e*x)^(2*n))^p=#

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*cot(d+e*x)^m*(a+b*cot(d+e*x)+c*cot(d+e*x)^2)^(p/2)=#

    @test_int [cot(d + e*x)^5/sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 15, -((sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c - sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e)) + (sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c + sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) - (b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*c^(3/2)*e) + (b*(5*b^2 - 12*a*c)*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(16*c^(7/2)*e) + sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)/(c*e) - (cot(d + e*x)^2*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(3*c*e) - ((15*b^2 - 16*a*c - 10*b*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(24*c^3*e)]
    @test_int [cot(d + e*x)^3/sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 11, (sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c - sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) - (sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c + sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) + (b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*c^(3/2)*e) - sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)/(c*e)]
    @test_int [cot(d + e*x)^1/sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 6, -((sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c - sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e)) + (sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c + sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e)]
    @test_int [tan(d + e*x)^1/sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 10, atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))/(sqrt(a)*e) + (sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c - sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) - (sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c + sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e)]
    @test_int [tan(d + e*x)^3/sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 14, -(atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))/(sqrt(a)*e)) + ((3*b^2 - 4*a*c)*atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(8*a^(5/2)*e) - (sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c - sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) + (sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((a - c + sqrt(a^2 + b^2 - 2*a*c + c^2) + b*cot(d + e*x))/(sqrt(2)*sqrt(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*sqrt(a^2 + b^2 - 2*a*c + c^2)*e) - (3*b*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)*tan(d + e*x))/(4*a^2*e) + (sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)*tan(d + e*x)^2)/(2*a*e)]

    @test_int [cot(d + e*x)^5*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 21, -((sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*atan((b^2 + (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e)) - (b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*sqrt(c)*e) + (b*(b^2 - 4*a*c)*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(16*c^(5/2)*e) - (b*(7*b^2 - 12*a*c)*(b^2 - 4*a*c)*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(256*c^(9/2)*e) + (sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*atanh((b^2 + (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) + b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) - sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)/e - (b*(b + 2*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(8*c^2*e) + (b*(7*b^2 - 12*a*c)*(b + 2*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(128*c^4*e) + (a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2)/(3*c*e) - (cot(d + e*x)^2*(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2))/(5*c*e) - ((35*b^2 - 32*a*c - 42*b*c*cot(d + e*x))*(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2))/(240*c^3*e)]
    @test_int [cot(d + e*x)^3*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 16, (sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*atan((b^2 + (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) + (b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*sqrt(c)*e) - (b*(b^2 - 4*a*c)*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(16*c^(5/2)*e) - (sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*atanh((b^2 + (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) + b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) + sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)/e + (b*(b + 2*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(8*c^2*e) - (a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2)/(3*c*e)]
    @test_int [cot(d + e*x)^1*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 10, -((sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*atan((b^2 + (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e)) - (b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*sqrt(c)*e) + (sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*atanh((b^2 + (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) + b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) - sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)/e]
    @test_int [tan(d + e*x)^1*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 18, (sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*atan((b^2 + (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) + (sqrt(a)*atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/e - (sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*atanh((b^2 + (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) + b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e)]
    @test_int [tan(d + e*x)^3*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2), x, 21, -((sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*atan((b^2 + (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c + sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e)) - (sqrt(a)*atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/e - ((b^2 - 4*a*c)*atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(8*a^(3/2)*e) + (sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*atanh((b^2 + (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) + b*sqrt(a^2 + b^2 - 2*a*c + c^2)*cot(d + e*x))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*sqrt(a^2 + b^2 + c*(c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - a*(2*c - sqrt(a^2 + b^2 - 2*a*c + c^2)))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(1/4)*e) + ((2*a + b*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)*tan(d + e*x)^2)/(4*a*e)]

    @test_int [cot(d + e*x)^7/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 20, -((3*b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*c^(5/2)*e)) + (5*b*(7*b^2 - 12*a*c)*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(16*c^(9/2)*e) + (sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (2*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) + (2*cot(d + e*x)^2*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - (2*cot(d + e*x)^4*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) + (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - ((7*b^2 - 16*a*c)*cot(d + e*x)^2*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(3*c^2*(b^2 - 4*a*c)*e) + (2*b*cot(d + e*x)^3*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(c*(b^2 - 4*a*c)*e) + ((3*b^2 - 8*a*c - 2*b*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(c^2*(b^2 - 4*a*c)*e) - ((105*b^4 - 460*a*b^2*c + 256*a^2*c^2 - 2*b*c*(35*b^2 - 116*a*c)*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(24*c^4*(b^2 - 4*a*c)*e)]
    @test_int [cot(d + e*x)^5/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 14, (3*b*atanh((b + 2*c*cot(d + e*x))/(2*sqrt(c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(2*c^(5/2)*e) - (sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) + (sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) + (2*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - (2*cot(d + e*x)^2*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - ((3*b^2 - 8*a*c - 2*b*c*cot(d + e*x))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))/(c^2*(b^2 - 4*a*c)*e)]
    @test_int [cot(d + e*x)^3/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 10, (sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (2*(2*a + b*cot(d + e*x)))/((b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) + (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))]
    @test_int [cot(d + e*x)^1/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 7, -((sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e)) + (sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))]
    @test_int [tan(d + e*x)^1/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 13, atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))/(a^(3/2)*e) + (sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e) - (2*(b^2 - 2*a*c + b*c*cot(d + e*x)))/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) + (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))]
    @test_int [tan(d + e*x)^3/(a + b*cot(d + e*x) + c*cot(d + e*x)^2)^(3/2), x, 18, -(atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))/(a^(3/2)*e)) + (3*(5*b^2 - 4*a*c)*atanh((2*a + b*cot(d + e*x))/(2*sqrt(a)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2))))/(8*a^(7/2)*e) - (1/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e))*(sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c + sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c - sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 + (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))) + (1/(sqrt(2)*(a^2 + b^2 - 2*a*c + c^2)^(3/2)*e))*(sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*atanh((b^2 - (a - c)*(a - c - sqrt(a^2 + b^2 - 2*a*c + c^2)) - b*(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*cot(d + e*x))/(sqrt(2)*sqrt(2*a - 2*c + sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a^2 - b^2 - 2*a*c + c^2 - (a - c)*sqrt(a^2 + b^2 - 2*a*c + c^2))*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)))) + (2*(b^2 - 2*a*c + b*c*cot(d + e*x)))/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - (2*(a*(b^2 - 2*(a - c)*c) + b*c*(a + c)*cot(d + e*x)))/((b^2 + (a - c)^2)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) - (b*(15*b^2 - 52*a*c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)*tan(d + e*x))/(4*a^3*(b^2 - 4*a*c)*e) - (2*(b^2 - 2*a*c + b*c*cot(d + e*x))*tan(d + e*x)^2)/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)) + ((5*b^2 - 12*a*c)*sqrt(a + b*cot(d + e*x) + c*cot(d + e*x)^2)*tan(d + e*x)^2)/(2*a^2*(b^2 - 4*a*c)*e)]

    #= ::Subsection::Closed:: =#
    #=Integrands*of*the*form*cot(d+e*x)^m*(a+b*cot(d+e*x)^2+c*cot(d+e*x)^4)^(p/2)=#

    @test_int [cot(d + e*x)^5/sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 8, atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a - b + c)*e) + ((b + 2*c)*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*c^(3/2)*e) - sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)/(2*c*e)]
    @test_int [cot(d + e*x)^3/sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 7, -(atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a - b + c)*e)) - atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(c)*e)]
    @test_int [cot(d + e*x)^1/sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 4, atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a - b + c)*e)]
    @test_int [tan(d + e*x)^1/sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 8, atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a)*e) - atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a - b + c)*e)]
    @test_int [tan(d + e*x)^3/sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 11, -(atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a)*e)) - (b*atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*a^(3/2)*e) + atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*sqrt(a - b + c)*e) + (sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)*tan(d + e*x)^2)/(2*a*e)]

    @test_int [cot(d + e*x)^5*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 9, (sqrt(a - b + c)*atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) - ((b^3 + 2*b^2*c - 4*b*(a - 2*c)*c - 8*c^2*(a + 2*c))*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(32*c^(5/2)*e) + (((b - 2*c)*(b + 4*c) + 2*c*(b + 2*c)*cot(d + e*x)^2)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))/(16*c^2*e) - (a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2)/(6*c*e)]
    @test_int [cot(d + e*x)^3*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 8, -((sqrt(a - b + c)*atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e)) + ((b^2 + 4*b*c - 4*c*(a + 2*c))*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(16*c^(3/2)*e) - ((b - 4*c + 2*c*cot(d + e*x)^2)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))/(8*c*e)]
    @test_int [cot(d + e*x)^1*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 8, (sqrt(a - b + c)*atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) - ((b - 2*c)*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*sqrt(c)*e) - sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)/(2*e)]
    @test_int [tan(d + e*x)^1*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 10, (sqrt(a)*atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) - (sqrt(a - b + c)*atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) - (sqrt(c)*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e)]
    @test_int [tan(d + e*x)^3*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4), x, 22, -((sqrt(a)*atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e)) + (b*atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*sqrt(a)*e) + (sqrt(a - b + c)*atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) + (b*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*sqrt(c)*e) - ((b - 2*c)*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*sqrt(c)*e) - (sqrt(c)*atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(2*e) + (sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)*tan(d + e*x)^2)/(2*e)]

    @test_int [cot(d + e*x)^7/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 8, -(atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e)) - atanh((b + 2*c*cot(d + e*x)^2)/(2*sqrt(c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*c^(3/2)*e) - (a*(b^2 - a*(b + 2*c)) + (b^3 + 2*a^2*c - a*b*(b + 3*c))*cot(d + e*x)^2)/(c*(a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))]
    @test_int [cot(d + e*x)^5/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 6, atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e) - (a*(2*a - b) + ((a - b)*b + 2*a*c)*cot(d + e*x)^2)/((a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))]
    @test_int [cot(d + e*x)^3/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 6, -(atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e)) + (a*(b - 2*c) + (2*a - b)*c*cot(d + e*x)^2)/((a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))]
    @test_int [cot(d + e*x)^1/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 6, atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e) - (b^2 - 2*a*c - b*c + (b - 2*c)*c*cot(d + e*x)^2)/((a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))]
    @test_int [tan(d + e*x)^1/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 12, atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*a^(3/2)*e) - atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e) - (b^2 - 2*a*c + b*c*cot(d + e*x)^2)/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)) + (b^2 - 2*a*c - b*c + (b - 2*c)*c*cot(d + e*x)^2)/((a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))]
    @test_int [tan(d + e*x)^3/(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)^(3/2), x, 16, -(atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*a^(3/2)*e)) - (3*b*atanh((2*a + b*cot(d + e*x)^2)/(2*sqrt(a)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4))))/(4*a^(5/2)*e) + atanh((2*a - b + (b - 2*c)*cot(d + e*x)^2)/(2*sqrt(a - b + c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)))/(2*(a - b + c)^(3/2)*e) + (b^2 - 2*a*c + b*c*cot(d + e*x)^2)/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)) - (b^2 - 2*a*c - b*c + (b - 2*c)*c*cot(d + e*x)^2)/((a - b + c)*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)) - ((b^2 - 2*a*c + b*c*cot(d + e*x)^2)*tan(d + e*x)^2)/(a*(b^2 - 4*a*c)*e*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)) + ((3*b^2 - 8*a*c)*sqrt(a + b*cot(d + e*x)^2 + c*cot(d + e*x)^4)*tan(d + e*x)^2)/(2*a^2*(b^2 - 4*a*c)*e)]
    end

max_stars_repo_path: test/4 Trig functions/4.4 Cotangent/4.4.9 trig^m (a+b cot^n+c cot^(2 n))^p.jl


text:
# AUTO GENERATED FILE - DO NOT EDIT

export dcc_store

"""
    dcc_store(;kwargs...)

A Store component.
Easily keep data on the client side with this component.
The data is not inserted in the DOM.
Data can be in memory, localStorage or sessionStorage.
The data will be kept with the id as key.
Keyword arguments:
- `id` (String; required): The ID of this component, used to identify dash components
in callbacks. The ID needs to be unique across all of the
components in an app.
- `storage_type` (a value equal to: 'local', 'session', 'memory'; optional): The type of the web storage.

memory: only kept in memory, reset on page refresh.
local: window.localStorage, data is kept after the browser quit.
session: window.sessionStorage, data is cleared once the browser quit.
- `data` (Dict | Array | Real | String | Bool; optional): The stored data for the id.
- `clear_data` (Bool; optional): Set to true to remove the data contained in `data_key`.
- `modified_timestamp` (Real; optional): The last time the storage was modified.
"""
function dcc_store(; kwargs...)
        available_props = Symbol[:id, :storage_type, :data, :clear_data, :modified_timestamp]
        wild_props = Symbol[]
        return Component("dcc_store", "Store", "dash_core_components", available_props, wild_props; kwargs...)
end

max_stars_repo_name: asc-csa/dash-core-components

max_issues_repo_name: asc-csa/dash-core-components

max_forks_repo_name: asc-csa/dash-core-components


text:
using PyCall

export scipy_quad, cauchy_principal_value

const scipy_integrate = PyNULL()

function __init__()
    copy!(scipy_integrate, pyimport_conda("scipy.integrate", "scipy"))
end

function scipy_quad(func, a, b; args=(), full_output=0, atol=1.49e-8, rtol=1.49e-8, limit=50, points=nothing, weight=nothing, wvar=nothing, wopts=nothing, maxp1=50, limlst=50)
    scipy_integrate[:quad](func, a, b; args=args, full_output=full_output, epsabs=atol, epsrel=rtol, limit=limit, points=points, weight=weight, wvar=wvar, wopts=wopts, maxp1=maxp1, limlst=limlst)
end

function cauchy_principal_value(func, pole; atol = 1e-8)
    s = scipy_integrate[:quad](func,pole-1.0,pole+1.0,weight="cauchy",wvar=pole)
    g(x) = func(x) / (x - pole)
    n = scipy_integrate[:quad](g,-Inf,pole-1.0)
    p = scipy_integrate[:quad](g,pole+1.0,Inf)
    err = n[2]+s[2]+p[2]
    if (err > atol) || (isnan(err))
        @warn "Absolute error of integration is larger than the tolerance."
    end
    s[1]+n[1]+p[1] , err
end


text:
function through_rectangles_into_angle(r,angle::NTuple{2,HorizonSide})
    num_steps=[]
    while isborder(r,angle[1])==false || isborder(r,angle[2]) # Робот - не в юго-западном углу
        push!(num_steps, moves!(r, angle[2]))
        push!(num_steps, moves!(r, angle[1]))
    end
    return num_steps
end

function moves!(r,sides,num_steps::Vector{Int})
    for (i,n) in enumerate(reverse!(num_steps))
        moves!(r, sides[mod(i-1, length(sides))+1], n) # - это не рекурсия (не вызов функцией самой себя), это вызов другой, ранее определенной функции
        # выражение индекса массива mod(i-1, length(sides))+1 обеспечисвает периодическое продолжение последовательности из вектора sides до длины вектора num_steps
    end
end


text:
# developed with Julia 1.1.1
#
# Stochastic Dynamic Programming (SDP) controller
# for EMS simulation
#
# SDP is computed with a package available at
# https://github.com/adrien-le-franc/StoOpt.jl

using EMSx
using StoOpt

using JLD2

include("../arguments.jl")
include("function.jl")
include("calibrate.jl")

args = parse_commandline()

mutable struct Sdp <: EMSx.AbstractController
   model::StoOpt.SDP
   value_functions::Union{StoOpt.ArrayValueFunctions, Nothing}
   Sdp() = new()
end

## constant values and functions for both simulation and calibration

const controller = Sdp()
const dx = 0.1
const du = 0.1
const horizon = 672

function EMSx.initialize_site_controller(controller::Sdp, site::EMSx.Site, prices::EMSx.Prices)

    controller = Sdp()

    offline_law_data_frames = net_demand_offline_law(site.path_to_train_data_csv)
    noises = data_frames_to_noises(offline_law_data_frames)

    function offline_dynamics(t::Int64, state::Array{Float64,1}, control::Array{Float64,1},
    noise::Array{Float64,1})
        scale_factor = site.battery.power*0.25/site.battery.capacity
        soc = state + (site.battery.charge_efficiency*max.(0.,control) -
            max.(0.,-control)/site.battery.discharge_efficiency)*scale_factor
        return soc
    end

    function offline_cost(t::Int64, state::Array{Float64,1}, control::Array{Float64,1},
    noise::Array{Float64,1})
        control = control[1]*site.battery.power*0.25
        imported_energy = control + noise[1]
        return (prices.buy[t]*max(0.,imported_energy) - prices.sell[t]*max(0.,-imported_energy))
    end

    model = StoOpt.SDP(Grid(0:dx:1, enumerate=true),
        Grid(-1:du:1),
        noises,
        offline_cost,
        offline_dynamics,
        horizon)

    controller.model = model

   return controller

end

## calibration specific function

function compute_value_functions(controller::Sdp)
    return StoOpt.compute_value_functions(controller.model)
end

## simulation specific functions

function load_value_functions(site_id::String)
    return load(joinpath(args["save"],
                "sdp",
                "value_functions",
                site_id*".jld2"))["value_function"]
end

function EMSx.compute_control(controller::Sdp, information::EMSx.Information)

    if information.t == 1
        controller.value_functions = load_value_functions(information.site_id)
    end

    control = compute_control(controller.model, information.t, [information.soc],
        StoOpt.RandomVariable(controller.model.noises, information.t), controller.value_functions)

    return control[1]

end

if args["calibrate"]

    calibrate_sites(controller,
    joinpath(args["save"], "sdp"),
    args["price"],
    args["metadata"],
    args["train"])

end

if args["simulate"]

EMSx.simulate_sites(controller,
    joinpath(args["save"], "sdp"),
    args["price"],
    args["metadata"],
    args["test"],
    args["train"])

end


text:
using HypothesisTests

function pearson_correlation(project,modelname,parameter)
     rpoB_eq_table = project["rpoB_equiv_table"]
	metadata_table = project["project_table"]
	single_model = melt(rpoB_eq_table[rpoB_eq_table[:PFAM_Model] .== modelname, :], :PFAM_Model)
     single_model[:param] = reverse(metadata_table[parameter])
    return cor(single_model[:param],single_model[:value])
end

function mann_whitney_compare_projects(project1,project2,modelname)
	project_1_vector = vec(Array{Float64}(project1["rpoB_equiv_table"][project1["rpoB_equiv_table"][:PFAM_Model] .== modelname,:][2:end]))
	project_2_vector = vec(Array{Float64}(project2["rpoB_equiv_table"][project2["rpoB_equiv_table"][:PFAM_Model] .== modelname,:][2:end]))
	return MannWhitneyUTest(project_1_vector, project_2_vector)
end

function mann_whitney_compare_models(project,model1,model2)
	model_1_vector = vec(Array{Float64}(project["rpoB_equiv_table"][project["rpoB_equiv_table"][:PFAM_Model] .== model1,:][2:end]))
	model_2_vector = vec(Array{Float64}(project["rpoB_equiv_table"][project["rpoB_equiv_table"][:PFAM_Model] .== model2,:][2:end]))
	return MannWhitneyUTest(model_1_vector, model_2_vector)
end

max_stars_repo_name: ianpgm/apfamet

max_issues_repo_name: ianpgm/apfamet

max_forks_repo_name: ianpgm/apfamet


text:
@testset "CompoundNode" begin

@testset "Constructor" begin
    compoundNode = CompoundNode( "Compound node" )
    @test all( [compoundNode.name == "Compound node",
        isempty( compoundNode.baseNodeList ), compoundNode.nodeTarget == -1] )
end  # @testset "Constructor"

compoundNode = CompoundNode( "Compound node" )

@testset "function addCompoundNodeComponent!" begin
    addCompoundNodeComponent!( compoundNode, "Air Officer",
        "Air Non-Com", "Air Officer" )
    @test ( length( compoundNode.baseNodeList ) == 2 ) &&
        ( ["Air Officer", "Air Non-Com"] ⊆ compoundNode.baseNodeList )
    addCompoundNodeComponent!( compoundNode, "Air Officer", "Air Volunteer" )
    @test ( length( compoundNode.baseNodeList ) == 3 ) &&
        ( "Air Volunteer" ∈ compoundNode.baseNodeList )
    @test !addCompoundNodeComponent!( compoundNode, "Air Officer" )
end  # @testset "function addCompoundNodeComponent!"

@testset "function removeCompoundNodeComponent!" begin
    removeCompoundNodeComponent!( compoundNode, "Air Officer",
        "Air General" )
    @test ( length( compoundNode.baseNodeList ) == 2 ) &&
        ( "Air Officer" ∉ compoundNode.baseNodeList )
    removeCompoundNodeComponent!( compoundNode, "Air Officer", "Air Non-Com" )
    @test ( length( compoundNode.baseNodeList ) == 1 ) &&
        ( "Air Non-Com" ∉ compoundNode.baseNodeList )
    @test !removeCompoundNodeComponent!( compoundNode, "Air Non-Com",
        "Air Officer" )
end  # @testset "function removeCompoundNodeComponent!"

@testset "function clearCompoundNodeComponents!" begin
    clearCompoundNodeComponents!( compoundNode )
    @test isempty( compoundNode.baseNodeList)
end  # @testset "function clearCompoundNodeComponents!"

@testset "function setCompoundNodeComponents!" begin
    setCompoundNodeComponents!( compoundNode, ["Ground Officer",
        "Ground Non-Com", "Ground Officer"] )
    @test ( length( compoundNode.baseNodeList ) == 2 ) &&
        ( ["Ground Officer", "Ground Non-Com"] ⊆ compoundNode.baseNodeList )
    setCompoundNodeComponents!( compoundNode, "Medical Volunteer",
        "Medical Officer" )
    @test ( length( compoundNode.baseNodeList ) == 2 ) &&
        ( ["Medical Officer", "Medical Volunteer"] ⊆
        compoundNode.baseNodeList )
end  # @testset "function setCompoundNodeComponents!"

@testset "function setCompoundNodeTarget!" begin
    setCompoundNodeTarget!( compoundNode, 1000 )
    @test compoundNode.nodeTarget == 1000
    setCompoundNodeTarget!( compoundNode, -500 )
    @test compoundNode.nodeTarget == -1
end  # @testset "function setCompoundNodeTarget!"

end  # @testset "CompoundNode"


text:
# Test the correctness of f(x) and prox(f,x,gamma) for a few hardcoded cases

stuff = [
  Dict( "f"      => NormL2(0.5),
        "x"      => [-1.472658469388188,-0.2715944116787317,-0.05323943816203797,1.0714599486778327,-1.5331256392574706,0.4083764366610342,-0.9444383691511559,-0.7504607478410741,0.7438914169983039,-0.15652009656239366],
        "f(x)"   => 1.4092215084194275,
        "gamma"  => 0.3,
        "y"      => [-1.3942822988967276,-0.2571399197807538,-0.0504059887445427,1.0144359140099486,-1.4515313531517497,0.38664228587878424,-0.8941745339321049,-0.7105205711181053,0.7043008658028084,-0.14818996026228431],
        "f(y)"   => 1.3342215084194275,
      ),

  Dict( "f"      => NormL1(0.6),
        "x"      => [0.24488032099324117,0.6361148017053393,-0.7468003460445393,-0.39461027607226284,-0.766936244339526,0.08238242897650354,-1.4822688010626806,0.23915849610266143,-0.5124773673251194,0.14222091048851146],
        "f(x)"   => 3.148709995866231,
        "gamma"  => 0.4,
        "y"      => [0.004880320993241177,0.3961148017053393,-0.5068003460445393,-0.15461027607226285,-0.526936244339526,0.0,-1.2422688010626806,0.0,-0.2724773673251194,0.0],
        "f(y)"   => 1.8624528945256253,
      ),

  Dict( "f"      => NormL1(0.45),
        "x"      => Complex{Float64}[0.48383139850861223 + 0.14880666357496075im -0.476452189543104 + 0.5373862840906938im -0.47734819961688757 + 1.5821400827207137im;
                      0.731503968722083 + 0.16028191387997026im -0.43401778891072196 + 0.31094682923492956im -0.6171419681732582 + 1.6633154232600766im;
                      0.8143294700727339 + 0.9825764200556435im 0.9956758203961695 + 0.6666719567389796im 0.9364063971363472 + 0.03175404144697325im],
        "f(x)"   => 4.2053455230857,
        "gamma"  => 0.55,
        "y"      => Complex{Float64}[0.24726722632640047 + 0.07604924168725978im -0.3122580040459822 + 0.3521930891591931im -0.40585785798447027 + 1.3451899169615815im;
                      0.48973954188193203 + 0.1073082231018745im -0.23282376734737972 + 0.16680379025222528im -0.5310468296940786 + 1.4312725885716275im;
                      0.6563976577692634 + 0.7920146383087744im 0.7900191090320431 + 0.5289709506755073im 0.6890485776638721 + 0.02336600557303825im],
        "f(y)"   => 3.2029705230857,
      ),

  Dict( "f"      => NormL0(0.6),
        "x"      => [0.14315338571566838,0.6534693088076117,-0.35221109634545744,-1.0843092036012738,-0.21687748781464977,0.38416472626106707,0.46644748241896083,-1.7104462861427205,0.29913996761129763,1.4566599915371263],
        "f(x)"   => 6.0,
        "gamma"  => 0.4,
        "y"      => [0.0,0.0,-0.0,-1.0843092036012738,-0.0,0.0,0.0,-1.7104462861427205,0.0,1.4566599915371263],
        "f(y)"   => 1.7999999999999998,
      ),

  Dict( "f"      => NormL0(0.45),
        "x"      => [-0.9617311985566904 -0.518012365217699 0.4416517549177308 1.0497034474382447;
         0.273994311984438 0.33356795744106194 0.24747082687586053 1.369695656039301;
         -0.778053112909331 1.7320620010973118 1.6366272293068256 -0.5828690748881356;
         -0.9706863561972737 1.4039270788692668 1.126542963082653 -0.06669611410738466],
        "f(x)"   => 7.2,
        "gamma"  => 0.55,
        "y"      => [-0.9617311985566904 -0.0 0.0 1.0497034474382447;
         0.0 0.0 0.0 1.369695656039301;
         -0.778053112909331 1.7320620010973118 1.6366272293068256 -0.0;
         -0.9706863561972737 1.4039270788692668 1.126542963082653 -0.0],
        "f(y)"   => 4.05,
      ),

  Dict( "f"      => IndBallL0(5),
        "x"      => [-0.1553737486872724,-0.3805093036732066,-1.1359877819928568,-1.4074575535421312,-0.014354093517417054,-0.7828347886276972,0.7289354484199504,0.8077049251507309,-0.011180606660407861,-0.08252274792015224],
        "f(x)"   => +Inf,
        "gamma"  => rand(),
        "y"      => [0.0,0.0,-1.1359877819928568,-1.4074575535421312,0.0,-0.7828347886276972,0.7289354484199504,0.8077049251507309,0.0,0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndBallL0(4),
        "x"      => [0.11718035918656403 0.7413899585297815 2.536889607960003;
         -0.7905417065462554 -2.528853472235987 -0.21157829025742098;
         0.7335959778823463 -0.842619689213128 -1.6389387126978623],
        "f(x)"   => +Inf,
        "gamma"  => rand(),
        "y"      => [0.0 0.0 2.536889607960003;
         0.0 -2.528853472235987 0.0;
         0.0 -0.842619689213128 -1.6389387126978623],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndBallL0(6),
        "x"      => Complex{Float64}[0.4123814653942677 + 0.5477281536949097im 0.1180210182125836 + 0.48721833026698946im 0.18165793415201192 + 0.33083070659243896im;
                         0.14567574789746107 + 0.9797631246910778im 0.8859137252355573 + 0.24593117579841173im 0.1119791184116512 + 0.1782455833267571im;
                         0.6971105660873709 + 0.4456778795521643im 0.6815819496354292 + 0.7246319393377785im 0.36348180980544 + 0.06420454004464782im],
        "f(x)"   => +Inf,
        "gamma"  => rand(),
        "y"      => Complex{Float64}[0.4123814653942677 + 0.5477281536949097im 0.1180210182125836 + 0.48721833026698946im 0.0 + 0.0im;
                         0.14567574789746107 + 0.9797631246910778im 0.8859137252355573 + 0.24593117579841173im 0.0 + 0.0im;
                         0.6971105660873709 + 0.4456778795521643im 0.6815819496354292 + 0.7246319393377785im 0.0 + 0.0im],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndBallRank(2),
        "x"      => [0.3251909299381841 0.32669352058736867 0.30878476770613905 0.16430992796261545 0.34512333306839693 0.7106693424891355 0.671658396200979;
         0.6281016205611978 0.6824858855301283 0.606248150077644 0.7254139031156339 0.1170408384465551 0.4388768890760757 0.8615311184291088;
         0.8463682898731775 0.41051188285054874 0.2212552529414713 0.017263014648567054 0.5688479305824816 0.5689918983334776 0.6308030513994181;
         0.9844519526932385 0.05957039918524343 0.16920598873503145 0.26466787431210026 0.3273430016867569 0.4490502773732654 0.6726433619983658],
        "f(x)"   => +Inf,
        "gamma"  => rand(),
        "y"      => [0.5886430110085807 0.32914238645718963 0.2888520521840012 0.26968674730017794 0.27465218034535255 0.4459822389240827 0.6034776156707196;
         0.5489756852899045 0.6774563889771498 0.6117937125809438 0.6957514636660374 0.1363090899378463 0.519717627394074 0.8835443097850474;
         0.874187543238049 0.24314229392781217 0.20193146854590316 0.10594782088443547 0.4873420015660753 0.5935040655910679 0.6835493401730847;
         0.8183028926081628 0.23998278025388683 0.2004676236930234 0.11402374950138522 0.45218188314537655 0.5590320254995675 0.6505724202640549],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndBallRank(3),
        "x"      => Complex{Float64}[0.2894901144233224 + 0.7901100704032158im 0.6756627927190222 + 0.17732824522289703im 0.4032334590351583 + 0.5586502215509941im 0.6765530083696047 + 0.9932602290818195im 0.6239659886851328 + 0.4722390586145797im;
                         0.9584404572720246 + 0.3400250643041498im 0.2817204876721717 + 0.1672398933443462im 0.12128240130180257 + 0.4551933013068352im 0.009961310207793783 + 0.7338453218632623im 0.6212643707424914 + 0.9635158606442724im;
                         0.24433751578157148 + 0.9730339027739963im 0.561280208357009 + 0.633283020406419im 0.7756547213943652 + 0.6363562132601082im 0.524463206504971 + 0.4679827241988874im 0.8880524015305997 + 0.7435744407640921im;
                         0.269826028779663 + 0.9982313659183581im 0.41546528075221145 + 0.6214520195056343im 0.8504698227465424 + 0.2768665057621147im 0.8444300571451868 + 0.03191011411950728im 0.03554939244925781 + 0.14138957996692292im;
                         0.2597821446989732 + 0.17685782088084867im 0.019472122622971932 + 0.06869500820139018im 0.25268066733355 + 0.9806451815396378im 0.48324598010201014 + 0.44249079773617583im 0.6889781312674093 + 0.7634231410250403im;
                         0.43816794443248064 + 0.6397332714961954im 0.46903438458543123 + 0.8824836781826655im 0.7497646614950952 + 0.36740503730557905im 0.3126961801169257 + 0.3291723529075903im 0.8244963378972998 + 0.008092801141097006im],
        "f(x)"   => +Inf,
        "gamma"  => rand(),
        "y"      => Complex{Float64}[0.3585122350782503 + 0.7204931620772194im 0.6873338530452431 + 0.2610974701292823im 0.39252783201763075 + 0.6238384834518138im 0.700958438487958 + 0.9854327001665436im 0.5535168614106272 + 0.44685210138441234im;
                         0.8350120893298553 + 0.3426664307287768im 0.4178136548191302 + 0.12698832094230983im 0.07358671256699245 + 0.47861707516508023im 0.002816461229650763 + 0.6363648374894336im 0.6956352575477227 + 1.0157211189866961im;
                         0.4135468294332672 + 0.9576574664510645im 0.4469496743511391 + 0.715289225146536im 0.7730346403491004 + 0.687733965182209im 0.5363213279663741 + 0.5318375665022115im 0.7965680634261025 + 0.6450297581065603im;
                         0.18649674078077969 + 1.095680382782847im 0.44917829901846035 + 0.5101097836542252im 0.824251628465519 + 0.2737731007006557im 0.7934464219269162 - 0.008707537347000721im 0.13522586261104846 + 0.137751277271351im;
                         0.27744885345156756 + 0.22735326748520787im -0.09129603800027204 + 0.0806859574437441im 0.23111156369091165 + 0.8472792964657452im 0.5259959290489749 + 0.5120663051072597im 0.7236832860052391 + 0.7728579942500509im;
                         0.3176634693027552 + 0.6443692910531424im 0.506476440217625 + 0.7834437422168772im 0.8489778225663775 + 0.2954271540742297im 0.27758349592855164 + 0.34110887017651426im 0.8565371173527224 + 0.09997874104615029im],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => NuclearNorm(1.0),
        "x"      => Float64[
          1.0  2.0  3.0;
          4.0  5.0  6.0;
          7.0  8.0  9.0 ],
        "f(x)"   => 17.916472867168920,
        "gamma"  => 1.0,
        "y"      => Float64[
          1.586052850795247   1.944185442781408   2.302318034767569;
          3.944185442781405   4.720927213907027   5.497668985032647;
          6.302318034767567   7.497668985032650   8.693019935297732 ],
        "f(y)"   => 15.916472867168915,
      ),

  Dict( "f"      => IndPSD(),
        "x"      => Symmetric(Float64[
          1.0  2.0  3.0  2.0;
          2.0  2.0  6.0  2.5;
          3.0  6.0  3.0  1.5;
          2.0  2.5  1.5  1.0 ]),
        "f(x)"   => +Inf,
        "gamma"  => 1.0,
        "y"      => Symmetric(Float64[
          1.6410947195520720 2.3777145021117252 2.5281090002887159 1.4927448378285653;
          2.3777145021117252 3.9278061374789126 4.2522683130214816 1.9740014117486595;
          2.5281090002887159 4.2522683130214816 4.6140313368981438 2.0691378959547362;
          1.4927448378285653 1.9740014117486600 2.0691378959547362 1.4316113417275229 ]),
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndPSD(),
        "x"      => Float64[1.0, 2.0, 3.0, 2.0, 2.0, 6.0, 2.5, 3.0, 1.5, 1.0],
        "f(x)"   => +Inf,
        "gamma"  => 1.0,
        "y"      => Float64[1.6410947195520720, 2.3777145021117252, 2.5281090002887159, 1.4927448378285653,
                            3.9278061374789126, 4.2522683130214816, 1.9740014117486600,
                            4.6140313368981438, 2.0691378959547362,
                            1.4316113417275229],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndBallL1(3.5),
        "x"      => [0.183227263001437, -1.029767543566621, 0.949221831131023, 0.307061919146703,
            0.135174942099456, 0.515246335524849, 0.261406324055383, -0.941485770955434,
            -0.162337672803828, -0.146054634331526, -0.532011376808821, 1.682103594663179,
            -0.875729346160017, -0.483815050110121, -0.712004549027422, -1.174212331456816,
            -0.192239517539275, -0.274070229932602, 1.530072514424096, -0.249024742513714,
            -1.064213412889327, 1.603457298120044, 1.234679146890778, -0.229626450963180,
            -1.506159703979719, -0.444627816446985, -0.155941035724769, 0.276068253931536,
            -0.261163645776479, 0.443421912904091],
        "f(x)"   => +Inf,
        "gamma"  => 1.0,
        "y"      => [   0.0000000000000000e+00, -1.0823022875891708e-01, 2.7684516323319142e-02, 0.0000000000000000e+00,
            0.0000000000000000e+00, 0.0000000000000000e+00, 0.0000000000000000e+00, -1.9948456147730109e-02,
            -0.0000000000000000e+00, -0.0000000000000000e+00, -0.0000000000000000e+00, 7.6056627985547520e-01,
            -0.0000000000000000e+00, -0.0000000000000000e+00, -0.0000000000000000e+00, -2.5267501664911218e-01,
            -0.0000000000000000e+00, -0.0000000000000000e+00, 6.0853519961639224e-01, -0.0000000000000000e+00,
            -1.4267609808162318e-01, 6.8191998331234005e-01, 3.1314183208307422e-01, -0.0000000000000000e+00,
            -5.8462238917201514e-01, -0.0000000000000000e+00, -0.0000000000000000e+00, 0.0000000000000000e+00,
            -0.0000000000000000e+00, 0.0000000000000000e+00],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndExpPrimal(),
        "x"      => [0.537667139546100, 1.833885014595086, -2.258846861003648],
        "f(x)"   => +Inf,
        "gamma"  => 2*rand(),
        "y"      => [-2.331395211405815e-01, 2.108704992310933e-01, 6.980034791326437e-02],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndExpPrimal(),
        "x"      => [8.621733203681206e-01, 3.187652398589808e-01, -1.307688296305273e+00],
        "f(x)"   => +Inf,
        "gamma"  => 2*rand(),
        "y"      => [0.0, 0.0, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndExpPrimal(),
        "x"      => [-4.335920223056836e-01, 3.426244665386499e-01, 3.578396939725760e+00],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [-4.335920223056836e-01, 3.426244665386499e-01, 3.578396939725760e+00],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndExpPrimal(),
        "x"      => [-2.049660582997746e-01, -1.241443482163119e-01, 1.489697607785465e+00],
        "f(x)"   => +Inf,
        "gamma"  => 2*rand(),
        "y"      => [-2.049660582997746e-01, 0, 1.489697607785465e+00],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndExpPrimal(),
        "x"      => [0.7647528861899316, -0.20198832835175584, 0.9528202307304982],
        "f(x)"   => +Inf,
        "gamma"  => 2*rand(),
        "y"      => [0.30504984970236265,0.1688454299327435,1.0283026364773413],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndNonnegative(),
        "x"      => [0.7647528861899316, 0.20198832835175584, 0.0],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [0.7647528861899316, 0.20198832835175584, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndNonnegative(),
        "x"      => [0.7647528861899316, -0.20198832835175584, 0.0],
        "f(x)"   => Inf,
        "gamma"  => 2*rand(),
        "y"      => [0.7647528861899316, 0.0, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndNonpositive(),
        "x"      => [-0.7647528861899316, -0.20198832835175584, 0.0],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [-0.7647528861899316, -0.20198832835175584, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndNonpositive(),
        "x"      => [-0.7647528861899316, 0.20198832835175584, 0.0],
        "f(x)"   => Inf,
        "gamma"  => 2*rand(),
        "y"      => [-0.7647528861899316, 0.0, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndZero(),
        "x"      => [-0.0, 0.0],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [0.0, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndZero(),
        "x"      => [-0.01, 0.0],
        "f(x)"   => Inf,
        "gamma"  => 2*rand(),
        "y"      => [0.0, 0.0],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndSOC(),
        "x"      => [1., 2.],
        "f(x)"   => Inf,
        "gamma"  => 2*rand(),
        "y"      => [1.5, 1.5],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndSOC(),
        "x"      => [2., 1.],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [2., 1.],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndRotatedSOC(),
        "x"      => [1., 1., 2.],
        "f(x)"   => Inf,
        "gamma"  => 2*rand(),
        "y"      => [1/2*(1+sqrt(2)), 1/2*(1+sqrt(2)), 1/2*(2+sqrt(2))],
        "f(y)"   => 0.0,
      ),

  Dict( "f"      => IndRotatedSOC(),
        "x"      => [1., 1., 1.],
        "f(x)"   => 0.0,
        "gamma"  => 2*rand(),
        "y"      => [1., 1., 1.],
        "f(y)"   => 0.0,
      )
]

for i = 1:length(stuff)

  println("----------------------------------------------------------")

  f = stuff[i]["f"]
  x = stuff[i]["x"]

  println(string(typeof(f), " on ", typeof(x)))

  ref_fx = stuff[i]["f(x)"]
  gamma = stuff[i]["gamma"]
  ref_y = stuff[i]["y"]
  ref_fy = stuff[i]["f(y)"]

  fx = 0.0

  try
    fx = call_test(f, x)
  catch e
    if isa(e, MethodError)
      println("(not defined)")
      continue
    end
  end

  @test fx == ref_fx || abs(fx-ref_fx)/(1+abs(ref_fx)) <= TOL_ASSERT
  y, fy = prox_test(f, x, gamma)
  @test vecnorm(y-ref_y, Inf)/(1+norm(ref_y, Inf)) <= TOL_ASSERT

  if ProximalOperators.is_prox_accurate(f)
    @test fy == ref_fy || abs(fy-ref_fy)/(1+abs(ref_fy)) <= TOL_ASSERT
  end

end


text:
module QuantumInfo
using Cliffords
using LinearAlgebra: I, norm, tr, eigvals, eigen, svdvals, lmul!

# As a stopgap, reintroduce the old `eye`.
eye(m::AbstractMatrix) = Matrix{eltype(m)}(I, size(m))

eye(n::Integer) = Matrix{Float64}(I, (n, n))

eye(T::DataType, n::Integer) = Matrix{T}(I, (n, n))

include("basics.jl")
include("open-systems.jl")

end