Closed FriesischScott closed 4 years ago
So great call on removing the MIO function, we really have no need for it. And I agree with everything that you have done.
I've made a couple of changes:
Abstract types: I've created an abstract type called UQtypes, which all of our types will inherit. This is to allow us to work with Julia multiple dispatch functionality. I've created 3 sub abstract types. AbstractInput
, AbstractModel
and AbstractSimulation
. I'm not sure if we're going to need multiple model
types, but its there just in case.
The samples function can now take singular inputs. This was done with just a wrapper function.
Probability of failure can also take singular inputs, as well as the arrays. This was done with a type Union in it's input
Reeport package has been added so we can auto-export the distributions package
I've also added a function for the model
type. This allows you to just call the variable as if it were a function. Example:
julia> model1 = Model(df -> df.b .* df.h .^ 3 / 12, "I");
julia> df = DataFrame(b = 0.3, h = 0.4);
julia>ou1 = model1(df)
1-element Array{Float64,1}:
0.0016000000000000005
This just does the same as the evaluate function, but I think this is a cool Julia feature
I think we should reexport as little modules as possible. I agree that reexporting Distributions makes sense, since its such an integral part the whole UQ thing. However, I don't think we should reexport DataFrames
, as it is only necessary if you want to do additional manipulation of the DataFrame
after the simulation is done.
I like being able to call the Model
like a function, nicely done! Is there any documentation on that function ()()
double parentheses syntax? I couldn't find any but it looks interesting.
What I do not agree with is the AbstractSimulation
type. Or at least I don't see any use for it (yet). The problem with the way you implemented it now is that it goes against how multiple dispatch works.
By using sim::AbstractSimulation
, Julia can not determine at run-time which simulation is required and we would need to switch
on the type of simulation to distinguish between for example standard Monte Carlo and Line Sampling for computing the probability of failure. The way it should work is that you define multiple methods with different simulation types like so:
function probabilityOfFailure(
models::Union{Array{<:AbstractModel}, AbstractModel},
performance::Function,
inputs::Union{Array{<:AbstractInput}, AbstractInput},
sim::MonteCarlo,
)
# compute pf with standard Monte Carlo
end
function probabilityOfFailure(
models::Union{Array{<:AbstractModel}, AbstractModel},
performance::Function,
inputs::Union{Array{<:AbstractInput}, AbstractInput},
sim::LineSampling,
)
# compute pf with Line Sampling
end
Then, depending on what Simulation
object you pass, the correct method is run. Or am I wrong?
It does make perfect sense for the AbstractInput
and AbstractModel
types.
Also I would like to keep using UncertaintyQuantification
at the beginning of any demo
files we have. This way, the demos you can find in the repository can be run as is if you just install UncertaintyQuantification
using Pkg (once we upload it ofc.)
@AnderGray If you agree with this, I will write some tests and merge to master and we can keep going from a good basis. If you don't, we can of course iterate further.
@FriesischScott I'm happy to merge this with the master.
Also you're totally right about the abstract type for simulations not making sense.
I can't remember where I saw it, I think it was on a Julia presentation... and I can't find it anywhere in the documentation anyway.
This is my proposal for a base layout of the project. It adds basic structures for the required inputs and a method to calculate a probability of failure using Monte Carlo simulation.
I decided to wrap
Distributions
in aRandomVariable
in order to assign names to all inputs. It preserves complete functionality ofDistributions
.RandomVariables
can be used independently from theRandomVariableSet
. This way independent variables can be excluded from the set. I also created aParameter
which just wraps avalue::Real
and aname
. Attaching the name to the random variable also simplifies the rvset.Since
Function
andMIO
in OpenCossan basically do the same, I decided to drop theFunction
completely. If the user needs to have intermediate results, models can be split and passed as a list toprobabilityOfFailure
(see demo).The goal is to allow for Julia's multiple dispatch to figure out which way to compute the pf based on which
simulation
structure is passed.I updated
demo/cantilever.jl
to show an example script using all the new structures/functions.Thoughts?
Closes #2 and closes #3