Skip to content

Commit

Permalink
getComposedEvent --> asComposedEvent
Browse files Browse the repository at this point in the history
Unit tests in t_Event_system.py are expanded to include a DomainEvent with a LevelSet,
and asComposedEvent is dropped from the RandomVector interface class.
  • Loading branch information
josephmure committed Oct 22, 2023
1 parent 9a2e68d commit 799758c
Show file tree
Hide file tree
Showing 20 changed files with 67 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ AdaptiveDirectionalStratification::AdaptiveDirectionalStratification()
AdaptiveDirectionalStratification::AdaptiveDirectionalStratification(const RandomVector & event,
const RootStrategy & rootStrategy,
const SamplingStrategy & samplingStrategy)
: EventSimulation(event)
, standardEvent_(StandardEvent(event))
: EventSimulation(event.getImplementation()->asComposedEvent())
, standardEvent_(StandardEvent(getEvent()))
, rootStrategy_(rootStrategy)
, samplingStrategy_(samplingStrategy)
, gamma_(ResourceMap::GetAsUnsignedInteger("AdaptiveDirectionalStratification-DefaultNumberOfSteps"), ResourceMap::GetAsScalar("AdaptiveDirectionalStratification-DefaultGamma"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ CrossEntropyImportanceSampling::CrossEntropyImportanceSampling()
// Default constructor
CrossEntropyImportanceSampling::CrossEntropyImportanceSampling(const RandomVector & event,
const Scalar quantileLevel)
: EventSimulation(event)
, initialDistribution_(event.getAntecedent().getDistribution())
: EventSimulation(event.getImplementation()->asComposedEvent())
, initialDistribution_(getEvent().getAntecedent().getDistribution())
{
if (quantileLevel > 1.)
throw InvalidArgumentException(HERE) << "In CrossEntropyImportanceSampling::CrossEntropyImportanceSampling, quantileLevel parameter value should be between 0.0 and 1.0";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ DirectionalSampling::DirectionalSampling()

/* Constructor with parameters */
DirectionalSampling::DirectionalSampling(const RandomVector & event)
: EventSimulation(event)
: EventSimulation(event.getImplementation()->asComposedEvent())
{
if (!event.isEvent() || !event.isComposite()) throw InvalidArgumentException(HERE) << "DirectionalSampling requires a composite event";
standardEvent_ = StandardEvent(getEvent());
Expand All @@ -61,7 +61,7 @@ DirectionalSampling::DirectionalSampling(const RandomVector & event)
DirectionalSampling::DirectionalSampling(const RandomVector & event,
const RootStrategy & rootStrategy,
const SamplingStrategy & samplingStrategy)
: EventSimulation(event)
: EventSimulation(event.getImplementation()->asComposedEvent())
, rootStrategy_(rootStrategy)
{
if (!event.isEvent() || !event.isComposite()) throw InvalidArgumentException(HERE) << "DirectionalSampling requires a composite event";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ EventSimulation::EventSimulation(const RandomVector & event,
const Bool verbose,
const HistoryStrategy & convergenceStrategy)
: SimulationAlgorithm()
, event_(event.getComposedEvent()) // for an Intersection/UnionEvent, we get its composedEvent if it can be built.
, event_(event)
, result_()
{
setVerbose(verbose);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ SubsetSampling::SubsetSampling()
SubsetSampling::SubsetSampling(const RandomVector & event,
const Scalar proposalRange,
const Scalar conditionalProbability)
: EventSimulation(event)
: EventSimulation(event.getImplementation()->asComposedEvent())
, proposalRange_(proposalRange)
, conditionalProbability_(conditionalProbability)
, iSubset_(false)
Expand Down
8 changes: 8 additions & 0 deletions lib/src/Uncertainty/Model/DomainEvent.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ Bool DomainEvent::isEvent() const
return true;
}

RandomVector DomainEvent::asComposedEvent() const
{
if (domain_.getImplementation()->getClassName() != "LevelSet")
throw NotYetImplementedException(HERE) << "DomainEvent is not based on a LevelSet.";

return RandomVector(clone());
}

/* Method save() stores the object through the StorageManager */
void DomainEvent::save(Advocate & adv) const
{
Expand Down
18 changes: 13 additions & 5 deletions lib/src/Uncertainty/Model/IntersectionEvent.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,33 @@ RandomVector IntersectionEvent::getAntecedent() const
return antecedent_;
}

RandomVector IntersectionEvent::getComposedEvent() const
RandomVector IntersectionEvent::asComposedEvent() const
{
const UnsignedInteger size = eventCollection_.getSize();
if (!size) throw InvalidArgumentException(HERE) << "Intersection has been improperly initialized: event collection is empty";

RandomVector composedEvent(eventCollection_[0].getComposedEvent());
RandomVector composedEvent;
try
{
// We get the first event in the collection as a composed event if possible.
composedEvent = eventCollection_[0].getImplementation()->asComposedEvent();
}
catch (const NotYetImplementedException &)
{
throw NotYetImplementedException(HERE) << "Event #0 could not be rebuilt as a ThresholdEvent.";
}

// Further build composedEvent by composing with the other events in the eventCollection_
for (UnsignedInteger i = 1; i < size; ++ i)
{
try
{
// We try to compose with the next event in the collection.
composedEvent = composedEvent.intersect(eventCollection_[i].getComposedEvent());
composedEvent = composedEvent.intersect(eventCollection_[i].getImplementation()->asComposedEvent());
}
catch (const NotYetImplementedException &)
{
// If no composition is possible, we default to the generic implementation.
return RandomVectorImplementation::getComposedEvent();
throw NotYetImplementedException(HERE) << "Event #" << i << " could not be rebuilt as a ThresholdEvent.";
}
}
return composedEvent;
Expand Down
9 changes: 2 additions & 7 deletions lib/src/Uncertainty/Model/RandomVector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ RandomVector RandomVector::intersect(const RandomVector & other)
d1 = *levelSet;
}

const RandomVector otherAsComposed(other.getComposedEvent());
const RandomVector otherAsComposed(other.getImplementation()->asComposedEvent());
LevelSet d2;
try
{
Expand Down Expand Up @@ -310,7 +310,7 @@ RandomVector RandomVector::join(const RandomVector & other)
d1 = *levelSet;
}

const RandomVector otherAsComposed(other.getComposedEvent());
const RandomVector otherAsComposed(other.getImplementation()->asComposedEvent());
LevelSet d2;
try
{
Expand All @@ -335,9 +335,4 @@ RandomVector RandomVector::join(const RandomVector & other)
}


RandomVector RandomVector::getComposedEvent() const
{
return getImplementation()->getComposedEvent();
}

END_NAMESPACE_OPENTURNS
6 changes: 2 additions & 4 deletions lib/src/Uncertainty/Model/RandomVectorImplementation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,9 @@ Bool RandomVectorImplementation::isEvent() const
return false;
}

RandomVector RandomVectorImplementation::getComposedEvent() const
RandomVector RandomVectorImplementation::asComposedEvent() const
{
if (!isEvent())
throw InvalidArgumentException(HERE) << "Not an event.";
return RandomVector(clone());
throw NotYetImplementedException(HERE) << "In RandomVectorImplementation::asComposedEvent";
}

/* Method save() stores the object through the StorageManager */
Expand Down
5 changes: 5 additions & 0 deletions lib/src/Uncertainty/Model/ThresholdEventImplementation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ Bool ThresholdEventImplementation::isEvent() const
return true;
}

RandomVector ThresholdEventImplementation::asComposedEvent() const
{
return RandomVector(clone());
}

/* Method save() stores the object through the StorageManager */
void ThresholdEventImplementation::save(Advocate & adv) const
{
Expand Down
20 changes: 14 additions & 6 deletions lib/src/Uncertainty/Model/UnionEvent.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,33 @@ RandomVector UnionEvent::getAntecedent() const
return antecedent_;
}

RandomVector UnionEvent::getComposedEvent() const
RandomVector UnionEvent::asComposedEvent() const
{
const UnsignedInteger size = eventCollection_.getSize();
if (!size) throw InvalidArgumentException(HERE) << "Union has been improperly initialized: event collection is empty";
if (!size) throw InvalidArgumentException(HERE) << "Intersection has been improperly initialized: event collection is empty";

RandomVector composedEvent(eventCollection_[0].getComposedEvent());
RandomVector composedEvent;
try
{
// We get the first event in the collection as a composed event if possible.
composedEvent = eventCollection_[0].getImplementation()->asComposedEvent();
}
catch (const NotYetImplementedException &)
{
throw NotYetImplementedException(HERE) << "Event #0 could not be rebuilt as a ThresholdEvent.";
}

// Further build composedEvent by composing with the other events in the eventCollection_
for (UnsignedInteger i = 1; i < size; ++ i)
{
try
{
// We try to compose with the next event in the collection.
composedEvent = composedEvent.join(eventCollection_[i].getComposedEvent());
composedEvent = composedEvent.join(eventCollection_[i].getImplementation()->asComposedEvent());
}
catch (const NotYetImplementedException &)
{
// If no composition is possible, we default to the generic implementation.
return RandomVectorImplementation::getComposedEvent();
throw NotYetImplementedException(HERE) << "Event #" << i << " could not be rebuilt as a ThresholdEvent.";
}
}
return composedEvent;
Expand Down
3 changes: 3 additions & 0 deletions lib/src/Uncertainty/Model/openturns/DomainEvent.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public:
/** Whether it is an event */
Bool isEvent() const override;

/** Build as composed event */
RandomVector asComposedEvent() const override;

/** Method save() stores the object through the StorageManager */
void save(Advocate & adv) const override;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/Uncertainty/Model/openturns/IntersectionEvent.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public:
/** Antecedent accessor */
RandomVector getAntecedent() const override;

RandomVector getComposedEvent() const override;
RandomVector asComposedEvent() const override;

/** Method save() stores the object through the StorageManager */
void save(Advocate & adv) const override;
Expand Down
3 changes: 0 additions & 3 deletions lib/src/Uncertainty/Model/openturns/RandomVector.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ public:
RandomVector intersect(const RandomVector & other);
RandomVector join(const RandomVector & other);

/** Composed event accessor */
RandomVector getComposedEvent() const;

protected:

}; /* class RandomVector */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public:
virtual Bool isEvent() const;

/** Composed event accessor */
virtual RandomVector getComposedEvent() const;
virtual RandomVector asComposedEvent() const;

/** Method save() stores the object through the StorageManager */
void save(Advocate & adv) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public:
/** Whether it is an event */
Bool isEvent() const override;

/** Build as composed event */
RandomVector asComposedEvent() const override;

/** Method save() stores the object through the StorageManager */
void save(Advocate & adv) const override;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/Uncertainty/Model/openturns/UnionEvent.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public:
/** Antecedent accessor */
RandomVector getAntecedent() const override;

RandomVector getComposedEvent() const override;
RandomVector asComposedEvent() const override;

/** Method save() stores the object through the StorageManager */
void save(Advocate & adv) const override;
Expand Down
9 changes: 4 additions & 5 deletions python/src/RandomVectorImplementation_doc.i.in
Original file line number Diff line number Diff line change
Expand Up @@ -510,16 +510,15 @@ OT_RandomVector_join_doc

// ---------------------------------------------------------------------

%define OT_RandomVector_getComposedEvent_doc
%define OT_RandomVector_asComposedEvent_doc
"If the random vector can be viewed as the composition of several :class:`~openturns.ThresholdEvent` objects,
this method builds and returns the composition.
If it is a different kind of event, returns the event itself.
Throws if it is no event.
Otherwise throws.

Returns
-------
composed : :class:`~openturns.RandomVector`
Composed event."
%enddef
%feature("docstring") OT::RandomVectorImplementation::getComposedEvent
OT_RandomVector_getComposedEvent_doc
%feature("docstring") OT::RandomVectorImplementation::asComposedEvent
OT_RandomVector_asComposedEvent_doc
2 changes: 0 additions & 2 deletions python/src/RandomVector_doc.i.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,3 @@ OT_RandomVector_isEvent_doc
OT_RandomVector_intersect_doc
%feature("docstring") OT::RandomVector::join
OT_RandomVector_join_doc
%feature("docstring") OT::RandomVector::getComposedEvent
OT_RandomVector_getComposedEvent_doc
4 changes: 2 additions & 2 deletions python/test/t_Event_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
f2 = ot.SymbolicFunction(["x" + str(i) for i in range(dim)], ["x1"])

Y1 = ot.CompositeRandomVector(f1, X)
Y2 = ot.CompositeRandomVector(f2, X)
l2 = ot.LevelSet(f2, ot.Greater(), 0.0)

e1 = ot.ThresholdEvent(Y1, ot.Less(), 0.0)
e2 = ot.ThresholdEvent(Y2, ot.Greater(), 0.0)
e2 = ot.DomainEvent(X, l2)

e3 = e1.intersect(e2)
# print('e3=', e3)
Expand Down

0 comments on commit 799758c

Please sign in to comment.