Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions lib/CanonicalMoments/src/CanonicalMoments.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import DiscreteMeasures: support, weights
import Polynomials: denominator, numerator

function DEFAULT_ROOT_SOLVER(C, args...; kwargs...)
# The closed-form solvers take only the coefficient vector; any extra
# args/kwargs are solver options that only the generic fallback consumes.
return if length(C) == 3 # 2nd order
quadratic_eq_sridhare(C, args...; kwargs...)
quadratic_eq_sridhare(C)
elseif length(C) == 4 # 3rd order
simple_real_cubic_eq(C, args...; kwargs...)
simple_real_cubic_eq(C)
elseif length(C) == 5 # 4th order
simple_real_quartic_eq(C, args...; kwargs...)
simple_real_quartic_eq(C)
else
Polynomials.roots(Polynomial(C), args...; kwargs...)
end
Expand Down
2 changes: 0 additions & 2 deletions lib/OUQBase/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
PolynomialRoots = "3a141323-8675-5d76-9d11-e1df1406c778"
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
Expand All @@ -31,7 +30,6 @@ Optimization = "5"
OptimizationBBO = "0.4"
OrderedCollections = "1.7.0"
Pkg = "1.10"
PolynomialRoots = "1"
Polynomials = "4.0.13"
Reexport = "1.2.2"
SciMLBase = "2.153"
Expand Down
56 changes: 36 additions & 20 deletions lib/OUQBase/src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,32 +149,48 @@ struct OUQSystem{A <: ObjectiveType, B <: AbstractReductionAlgorithm, P} <: Abst
admissible_set::AdmissibleSet
reduction_data::B
parameters::P
function OUQSystem(;
objective,
admissible_set,
reduction_alg::B,
parameters = SciMLBase.NullParameters(),
) where {B}
reduction_data = ReductionData(admissible_set, reduction_alg) # Note: reduction_data is the populated reduction_alg.
objective = process_objective(objective)
return new{typeof(objective), B, typeof(parameters)}(
objective,
admissible_set,
reduction_data,
parameters,
)
function OUQSystem{A, B, P}(
objective::A,
admissible_set::AdmissibleSet,
reduction_data::B,
parameters::P,
) where {A <: ObjectiveType, B <: AbstractReductionAlgorithm, P}
return new{A, B, P}(objective, admissible_set, reduction_data, parameters)
end
end

function OUQSystem(;
objective,
admissible_set,
reduction_alg::AbstractReductionAlgorithm,
parameters = SciMLBase.NullParameters(),
)
reduction_data = ReductionData(admissible_set, reduction_alg) # Note: reduction_data is the populated reduction_alg.
# Function barrier: process_objective returns a Union, so build the concretely
# parameterized OUQSystem behind a dispatch on the realized objective type.
return _OUQSystem(process_objective(objective), admissible_set, reduction_data, parameters)
end

function _OUQSystem(
objective::A,
admissible_set::AdmissibleSet,
reduction_data::B,
parameters::P,
) where {A <: ObjectiveType, B <: AbstractReductionAlgorithm, P}
return OUQSystem{A, B, P}(objective, admissible_set, reduction_data, parameters)
end

objective(ouq_sys::OUQSystem) = ouq_sys.objective
random_variable_map(ouq_sys::OUQSystem) = ouq_sys.admissible_set.random_variable_map
constraints_map(ouq_sys::OUQSystem) = ouq_sys.reduction_data.constraints_map
raw_moments_map(ouq_sys::OUQSystem) =
ouq_sys.reduction_data isa StengerCanonicalMoments ?
ouq_sys.reduction_data.raw_moments_map : nothing
p_free_map(ouq_sys::OUQSystem) =
ouq_sys.reduction_data isa StengerCanonicalMoments ? ouq_sys.reduction_data.p_free_map :
nothing
# Dispatch on the (concretely typed) reduction_data so the accessors stay type
# stable: a StengerCanonicalMoments system returns its dict, anything else nothing.
raw_moments_map(ouq_sys::OUQSystem) = raw_moments_map(ouq_sys.reduction_data)
raw_moments_map(reduction_data::StengerCanonicalMoments) = reduction_data.raw_moments_map
raw_moments_map(::AbstractReductionAlgorithm) = nothing
p_free_map(ouq_sys::OUQSystem) = p_free_map(ouq_sys.reduction_data)
p_free_map(reduction_data::StengerCanonicalMoments) = reduction_data.p_free_map
p_free_map(::AbstractReductionAlgorithm) = nothing


function get_group_name(var, admissible_set::AdmissibleSet)
Expand Down
10 changes: 5 additions & 5 deletions lib/OUQBase/src/reduction_transformations/canonical_moments.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function get_raw_moment_order(equation::Union{Equation, Inequality}, random_var:
return order
end

function CanonicalMoments.RawMomentSequence(
function build_raw_moment_sequence(
random_var::Num,
constraints::Vector{Union{Equation, Inequality}},
)
Expand All @@ -47,7 +47,7 @@ function create_raw_moments_map(admissible_set::AbstractAdmissibleSet)
length(admissible_set.random_variable_map[k]) == 1 ||
error("Group is not independent, cannot use canonical moments")
random_var = only(admissible_set.random_variable_map[k])
raw_moments_map[k] = RawMomentSequence(random_var, v)
raw_moments_map[k] = build_raw_moment_sequence(random_var, v)
end
return raw_moments_map
end
Expand Down Expand Up @@ -93,8 +93,8 @@ function discrete_measure_map(
::Symbolic,
)
transformed_discrete_measure_map = OrderedDict{Symbol, DiscreteMeasure}()
_raw_moments_map = raw_moments_map(ouq_sys)
_p_free_map = p_free_map(ouq_sys)
_raw_moments_map = reduction_alg.raw_moments_map
_p_free_map = reduction_alg.p_free_map
for (k, v) in constraints_map(ouq_sys)
transform_functor = DiscreteMeasureTransform1(_raw_moments_map[k])
transformed_discrete_measure_map[k] = transform_functor(
Expand Down Expand Up @@ -271,7 +271,7 @@ function construct_optimization_problem(
(rand_var_vec) ->
substitute(~f, Dict(constituent_random_variables .=> rand_var_vec))
# QN: Will variables always be passed in right order? Should be correct since this order is preserved in getting the induced_discrete_measure.
ouq_obj_f = simplify(obj_expression; rewriter = extract_f_rule)
ouq_obj_f = Symbolics.simplify(obj_expression; rewriter = extract_f_rule)
else
error("Objective is not a ProbabilityObjective or ExpectationObjective")
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ function construct_optimization_problem(
oracle_or_symbolic::Symbolic;
kwargs...,
)
@debug "Objective: $objective.objective"
objective = ouq_sys.objective
@debug "Objective: $(objective._obj)"
extract_condition_rule = @rule ℙ(~condition) => ~condition
condition = Symbolics.simplify(objective._obj; rewriter = extract_condition_rule)
_discrete_measure_map =
Expand Down
Loading