Skip to content

Commit 7ffe625

Browse files
author
Luca Geretti
authored
Merge python-enclosure-list#543
2 parents 28971fc + f3cddaa commit 7ffe625

File tree

10 files changed

+84
-72
lines changed

10 files changed

+84
-72
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Legenda for the issue kind:
1212

1313
### 2.2
1414

15-
*Date: /2021*
15+
*Date: 25/04/2021*
1616

1717
- [#441](https://github.com/ariadne-cps/ariadne/issues/441) (N) Add support for Gnuplot output, including animated gif plot of sets and tridimensional plots for PDEs
1818
- [#507](https://github.com/ariadne-cps/ariadne/issues/507) (N) Add a simulator for vector field dynamics
@@ -22,6 +22,7 @@ Legenda for the issue kind:
2222
- [#516](https://github.com/ariadne-cps/ariadne/issues/516) (A) Add missing Python bindings for Real predicates to be used in automata specification
2323
- [#518](https://github.com/ariadne-cps/ariadne/issues/518) (A) Add missing Python bindings for evolver configuration and initial set assignment
2424
- [#520](https://github.com/ariadne-cps/ariadne/issues/520) (A) Add missing Python bindings for plotting using HybridFigure
25+
- [#543](https://github.com/ariadne-cps/ariadne/issues/543) (A) Add missing Python bindings for iterating across ListSet of Enclosure classes
2526
- [#527](https://github.com/ariadne-cps/ariadne/issues/527) (A) Allow to draw a Labelled/Hybrid orbit directly to a Labelled/Hybrid figure
2627
- [#492](https://github.com/ariadne-cps/ariadne/issues/492) (C) Modify SFINAE code to use C++20 concepts, currently preventing AppleClang compilation under macOS until the compiler supports Concepts
2728
- [#529](https://github.com/ariadne-cps/ariadne/issues/529) (C) Disallow construction of VectorField and IteratedMap from a Function, since it was broken

experimental/examples/arch/LOVO20.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void LOVO20()
6969
RealPoint ic({1.3_dec,1.0_dec});
7070
Real e(0.008_dec);
7171
HybridSet initial_set(lotkavolterra|outside,{ic[0]-e<=x<=ic[0]+e,y==ic[1],cnt==0});
72-
HybridTime evolution_time(3.64,3);
72+
HybridTime evolution_time(3.64_dec,3u);
7373

7474
StopWatch sw;
7575

@@ -97,7 +97,7 @@ void LOVO20()
9797
else ARIADNE_LOG_PRINTLN("No final set with two transitions has been found!");
9898

9999
ARIADNE_LOG_PRINTLN("Trajectory stays within " << (radius*100).get_d() << "% of the equilibrium for at most " <<
100-
final_bounds[cnt].upper() << " time units: " << ((definitely(final_bounds[cnt] <= 0.2_dec)) ?
100+
final_bounds[cnt].upper_bound() << " time units: " << ((definitely(final_bounds[cnt] <= 0.2_dec)) ?
101101
"constraint satisfied." : "constraint not satisfied!"));
102102

103103
ARIADNE_LOG_PRINTLN("Done in " << sw.elapsed() << " seconds.");
@@ -109,19 +109,19 @@ void LOVO20()
109109
instance.set_verified(1)
110110
.set_execution_time(sw.elapsed())
111111
.add_loss((final_bounds[x].width()*final_bounds[y].width()).get_d())
112-
.add_loss(final_bounds[cnt].upper().get_d());
112+
.add_loss(final_bounds[cnt].upper_bound().get_d());
113113
}
114114
instance.write();
115115

116116
HybridAutomaton circle;
117117
DiscreteLocation rotate;
118118
RealVariable t("t");
119119
circle.new_mode(rotate,{let(x)=cx+radius*cos(t),let(y)=cy-radius*sin(t)},{dot(t)=1});
120-
HybridSimulator simulator;
121-
simulator.set_step_size(0.1);
120+
HybridSimulator simulator(circle);
121+
simulator.configuration().set_step_size(0.1);
122122
HybridRealPoint circle_initial(rotate,{t=0});
123123
HybridTime circle_time(2*pi,1);
124-
ARIADNE_LOG_RUN_MUTED(auto circle_orbit = simulator.orbit(circle,circle_initial,circle_time));
124+
ARIADNE_LOG_RUN_MUTED(auto circle_orbit = simulator.orbit(circle_initial,circle_time));
125125

126126
ARIADNE_LOG_RUN_AT(2,plot(benchmark.name().c_str(),Axes2d(0.6<=x<=1.4,0.6<=y<=1.4), orange, orbit, black, circle_orbit));
127127
ARIADNE_LOG_PRINTLN("File " << benchmark.name() << ".png written.");

python/examples/hybrid/LOVO20.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,16 @@ def plot_all(LOVO20_orbit,circle_orbit):
122122
#! [/compute_evolution]
123123

124124

125-
#! [check_number_of_events]
126-
def check_number_of_events(orbit):
125+
#! [verify]
126+
def verify(orbit):
127127

128128
has_any_zero_transitions = False
129129
has_any_two_transitions = False
130130

131131
for enclosure in orbit.final():
132-
if (not has_any_zero_transitions) and enclosure.previous_events().size() == 0:
132+
if (not has_any_zero_transitions) and len(enclosure.previous_events()) == 0:
133133
has_any_zero_transitions = True
134-
if (not has_any_two_transitions) and enclosure.previous_events().size() == 2:
134+
if (not has_any_two_transitions) and len(enclosure.previous_events()) == 2:
135135
has_any_two_transitions = True
136136

137137
if has_any_zero_transitions:
@@ -144,7 +144,17 @@ def check_number_of_events(orbit):
144144
else:
145145
print("No final set with two transitions has been found!")
146146

147-
#! [/check_number_of_events]
147+
x = RealVariable("x")
148+
y = RealVariable("y")
149+
cnt = RealVariable("cnt")
150+
151+
final_bounds = orbit.final().bounding_box()
152+
153+
print("Trajectory stays in the reference circle for at most", final_bounds[cnt].upper_bound(), "time units: ", end='')
154+
print("constraint satisfied") if final_bounds[cnt].upper_bound().raw() <= FloatDP(0.2,DoublePrecision()) else print("constraint NOT satisfied!")
155+
156+
157+
#! [/verify]
148158

149159
#! [main]
150160
if __name__ == '__main__':
@@ -165,7 +175,7 @@ def check_number_of_events(orbit):
165175
LOVO20_orbit = evolver.orbit(initial_set,final_time,Semantics.UPPER)
166176

167177
# Check number of events
168-
#check_number_of_events(LOVO20_orbit)
178+
verify(LOVO20_orbit)
169179

170180
# Get the orbit of the circle to plot, by points
171181
circle_orbit = get_circle_orbit()

python/source/evolution_submodule.cpp

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,37 @@
3434

3535
using namespace Ariadne;
3636

37+
Void export_labelled_drawable_2d_interface(pybind11::module& module) {
38+
pybind11::class_<LabelledDrawable2dInterface> labelled_drawable_interface_class(module,"LabelledDrawable2dInterface");
39+
}
40+
41+
Void export_semantics(pybind11::module& module) {
42+
pybind11::enum_<Semantics> semantics_enum(module,"Semantics");
43+
semantics_enum.value("UPPER", Semantics::UPPER);
44+
semantics_enum.value("LOWER", Semantics::LOWER);
45+
// semantics_enum.def("__repr__" , &__cstr__<Semantics>);
46+
}
47+
48+
Void export_storage(pybind11::module& module) {
49+
pybind11::class_<Storage,pybind11::bases<Drawable2dInterface>> storage_class(module,"Storage");
50+
pybind11::class_<LabelledStorage,pybind11::bases<LabelledDrawable2dInterface>> labelled_storage_class(module,"LabelledStorage");
51+
}
52+
53+
Void export_enclosure(pybind11::module& module) {
54+
pybind11::class_<Enclosure,pybind11::bases<Drawable2dInterface>> enclosure_class(module,"Enclosure");
55+
enclosure_class.def("bounding_box",&Enclosure::bounding_box);
56+
enclosure_class.def("__str__", &__cstr__<Enclosure>);
57+
pybind11::class_<LabelledEnclosure,pybind11::bases<LabelledDrawable2dInterface,Enclosure>> labelled_enclosure_class(module,"LabelledEnclosure");
58+
labelled_enclosure_class.def("bounding_box",&LabelledEnclosure::bounding_box);
59+
labelled_enclosure_class.def("__str__", &__cstr__<LabelledEnclosure>);
60+
}
61+
62+
template<class T> Void export_list_set(pybind11::module& module, const char* name) {
63+
pybind11::class_<ListSet<T>> list_set_class(module,name);
64+
list_set_class.def("__iter__", [](ListSet<T> const& l){return pybind11::make_iterator(l.begin(),l.end());});
65+
list_set_class.def("size",&ListSet<T>::size);
66+
}
67+
3768

3869
template<class ORB>
3970
Void export_orbit(pybind11::module& module, const char* name)
@@ -45,15 +76,6 @@ Void export_orbit(pybind11::module& module, const char* name)
4576
orbit_class.def("__str__", &__cstr__<ORB>);
4677
}
4778

48-
49-
Void export_semantics(pybind11::module& module) {
50-
pybind11::enum_<Semantics> semantics_enum(module,"Semantics");
51-
semantics_enum.value("UPPER", Semantics::UPPER);
52-
semantics_enum.value("LOWER", Semantics::LOWER);
53-
// semantics_enum.def("__repr__" , &__cstr__<Semantics>);
54-
}
55-
56-
5779
template<class SIM> Void export_simulator(pybind11::module& module, const char* name);
5880

5981
template<> Void export_simulator<VectorFieldSimulator>(pybind11::module& module, const char* name)
@@ -65,7 +87,6 @@ template<> Void export_simulator<VectorFieldSimulator>(pybind11::module& module,
6587

6688
auto const& reference_internal = pybind11::return_value_policy::reference_internal;
6789

68-
pybind11::class_<LabelledDrawable2dInterface> labelled_drawable_interface_class(module,"LabelledDrawable2dInterface");
6990
pybind11::class_<LabelledInterpolatedCurve,pybind11::bases<LabelledDrawable2dInterface>> labelled_interpolated_curve_class(module,"LabelledInterpolatedCurve");
7091

7192
pybind11::class_<OrbitType,pybind11::bases<LabelledDrawable2dInterface>> simulator_orbit_class(module,"ApproximatePointOrbit");
@@ -124,10 +145,6 @@ Void export_vector_field_evolver_configuration(pybind11::module& module) {
124145
vector_field_evolver_configuration_class.def("__repr__",&__cstr__<ConfigurationType>);
125146
}
126147

127-
Void export_labelled_storage(pybind11::module& module) {
128-
pybind11::class_<LabelledStorage,pybind11::bases<LabelledDrawable2dInterface>> labelled_storage_class(module,"LabelledStorage");
129-
}
130-
131148
template<class RA> Void export_safety_certificate(pybind11::module& module, const char* name) {
132149
typedef typename RA::StorageType StorageType;
133150
typedef typename RA::StateSpaceType StateSpaceType;
@@ -175,8 +192,15 @@ Void export_reachability_analyser(pybind11::module& module, const char* name)
175192

176193
Void evolution_submodule(pybind11::module& module)
177194
{
195+
export_labelled_drawable_2d_interface(module);
196+
178197
export_semantics(module);
179198

199+
export_storage(module);
200+
export_enclosure(module);
201+
202+
export_list_set<LabelledEnclosure>(module,"LabelledEnclosureListSet");
203+
180204
export_simulator<VectorFieldSimulator>(module,"VectorFieldSimulator");
181205

182206
export_evolver_interface<IteratedMapEvolver::Interface>(module, "IteratedMapEvolverInterface");
@@ -189,8 +213,6 @@ Void evolution_submodule(pybind11::module& module)
189213

190214
export_vector_field_evolver_configuration(module);
191215

192-
export_labelled_storage(module);
193-
194216
export_safety_certificate<ContinuousReachabilityAnalyser>(module,"SafetyCertificate");
195217
export_reachability_analyser<ContinuousReachabilityAnalyser,VectorFieldEvolver>(module,"ContinuousReachabilityAnalyser");
196218
}

python/source/geometry_submodule.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,6 @@ Void export_constrained_image_set(pybind11::module& module)
812812
//module.def("product", (ValidatedConstrainedImageSet(*)(const ValidatedConstrainedImageSet&,const BasicSetType&)) &product);
813813
}
814814

815-
816-
817815
Void geometry_submodule(pybind11::module& module) {
818816
export_drawable_interface(module);
819817
export_set_interface(module);

python/source/hybrid_submodule.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,19 @@ Void export_hybrid_storage(pybind11::module& module) {
280280
}
281281

282282
Void export_hybrid_enclosure(pybind11::module& module) {
283+
auto const& reference_internal = pybind11::return_value_policy::reference_internal;
284+
283285
pybind11::class_<HybridEnclosure> hybrid_enclosure_class(module,"HybridEnclosure");
286+
hybrid_enclosure_class.def("previous_events", &HybridEnclosure::previous_events,reference_internal);
284287
hybrid_enclosure_class.def("__repr__", &__cstr__<HybridEnclosure>);
285288
}
286289

290+
Void export_list_set_hybrid_enclosure(pybind11::module& module) {
291+
pybind11::class_<ListSet<HybridEnclosure>> list_set_hybrid_enclosure_class(module,"HybridEnclosureListSet");
292+
list_set_hybrid_enclosure_class.def("__iter__", [](ListSet<HybridEnclosure> const& l){return pybind11::make_iterator(l.begin(),l.end());});
293+
list_set_hybrid_enclosure_class.def("bounding_box",&ListSet<HybridEnclosure>::bounding_box);
294+
}
295+
287296
Void export_hybrid_automaton(pybind11::module& module)
288297
{
289298
// Don't use return_value_policy<copy_const_reference> since reference lifetime should not exceed automaton lifetime
@@ -293,8 +302,7 @@ Void export_hybrid_automaton(pybind11::module& module)
293302

294303
pybind11::class_<HybridAutomatonInterface> hybrid_automaton_interface_class(module,"HybridAutomatonInterface");
295304

296-
pybind11::class_<HybridAutomaton,pybind11::bases<HybridAutomatonInterface>>
297-
hybrid_automaton_class(module,"HybridAutomaton");
305+
pybind11::class_<HybridAutomaton,pybind11::bases<HybridAutomatonInterface>> hybrid_automaton_class(module,"HybridAutomaton");
298306
hybrid_automaton_class.def(pybind11::init<>());
299307
hybrid_automaton_class.def(pybind11::init<Identifier>());
300308
hybrid_automaton_class.def("locations", &HybridAutomaton::locations);
@@ -520,8 +528,9 @@ Void hybrid_submodule(pybind11::module& module) {
520528
export_hybrid_storage(module);
521529
export_hybrid_enclosure(module);
522530

523-
export_hybrid_automaton(module);
531+
export_list_set_hybrid_enclosure(module);
524532

533+
export_hybrid_automaton(module);
525534

526535
export_hybrid_time(module);
527536
export_hybrid_termination_criterion(module);

python/source/symbolic_submodule.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,18 @@ Void export_sets(pybind11::module& module, pybind11::class_<RealVariable>& real_
445445
pybind11::class_<RealVariablesBox> real_variables_box_class(module,"RealVariablesBox");
446446
real_variables_box_class.def(pybind11::init<Map<RealVariable,RealInterval>>());
447447
real_variables_box_class.def(pybind11::init<List<RealVariableInterval>>());
448-
// real_variables_box_class.def(pybind11::init<Set<RealVariableInterval>>());
449448
real_variables_box_class.def("__getitem__", &RealVariablesBox::operator[]);
450449
real_variables_box_class.def("__str__",&__cstr__<RealVariablesBox>);
451450

451+
typedef VariablesBox<FloatDPUpperInterval> FloatDPVariablesBox;
452+
pybind11::class_<FloatDPVariablesBox> floatdp_variables_box_class(module,"FloatDPVariablesBox");
453+
floatdp_variables_box_class.def("__getitem__", &FloatDPVariablesBox::operator[]);
454+
floatdp_variables_box_class.def("__str__",&__cstr__<FloatDPVariablesBox>);
455+
456+
pybind11::class_<LabelledBox<FloatDPUpperInterval>> labelled_floatdp_upper_box_class(module,"LabelledFloatDPUpperBox");
457+
labelled_floatdp_upper_box_class.def("__getitem__", &LabelledBox<FloatDPUpperInterval>::operator[]);
458+
labelled_floatdp_upper_box_class.def("__str__",&__cstr__<LabelledBox<FloatDPUpperInterval>>);
459+
452460
pybind11::class_<RealExpressionConstraintSet> real_expression_constraint_set_class(module,"RealExpressionConstraintSet");
453461
real_expression_constraint_set_class.def(pybind11::init<List<ContinuousPredicate>>());
454462
real_expression_constraint_set_class.def("__str__",&__cstr__<RealExpressionConstraintSet>);

source/dynamics/enclosure.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,31 +1592,6 @@ Void ListSet<LabelledEnclosure>::draw(CanvasInterface& cnvs, const Variables2d&
15921592
}
15931593
}
15941594

1595-
const RealSpace LabelledSet<ListSet<Enclosure>>::space() const {
1596-
return (*this)[0].space();
1597-
}
1598-
1599-
const RealSpace LabelledSet<ListSet<Enclosure>>::state_space() const {
1600-
return (*this)[0].state_space();
1601-
}
1602-
1603-
const ListSet<Enclosure> LabelledSet<ListSet<Enclosure>>::euclidean_set() const {
1604-
ListSet<Enclosure> result;
1605-
for (SizeType i=0; i!=this->size(); ++i) {
1606-
result.adjoin((*this)[i].euclidean_set());
1607-
}
1608-
return result;
1609-
}
1610-
1611-
const LabelledUpperBoxType LabelledSet<ListSet<Enclosure>>::bounding_box() const {
1612-
if (this->empty()) { return LabelledUpperBoxType(this->space(),UpperBoxType(this->space().dimension())); }
1613-
UpperBoxType bbx=(*this)[0].euclidean_set().bounding_box();
1614-
for (SizeType i=1; i!=this->size(); ++i) {
1615-
bbx=hull(bbx,(*this)[i].euclidean_set().bounding_box());
1616-
}
1617-
return LabelledUpperBoxType(this->state_space(),bbx);
1618-
}
1619-
16201595
} // namespace Ariadne
16211596

16221597

source/dynamics/enclosure.hpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -446,17 +446,6 @@ template<> class ListSet<LabelledEnclosure> : public LabelledDrawable2dInterface
446446
virtual Void draw(CanvasInterface&, const Variables2d&) const override;
447447
};
448448

449-
template<> class LabelledSet<ListSet<Enclosure>> : public ListSet<LabelledEnclosure> {
450-
public:
451-
LabelledSet<ListSet<Enclosure>>() : ListSet<LabelledEnclosure>() { }
452-
LabelledSet<ListSet<Enclosure>>(ListSet<LabelledEnclosure> lst) : ListSet<LabelledEnclosure>(lst) { }
453-
454-
const RealSpace state_space() const;
455-
const RealSpace space() const;
456-
const ListSet<Enclosure> euclidean_set() const;
457-
const LabelledUpperBoxType bounding_box() const;
458-
};
459-
460449
} //namespace Ariadne
461450

462451
#endif /* ARIADNE_ENCLOSURE_HPP */

source/dynamics/orbit.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class Orbit<LabelledEnclosure>
161161
: public LabelledDrawable2dInterface
162162
{
163163
typedef LabelledEnclosure ES;
164-
typedef LabelledSet<ListSet<Enclosure>> ESL;
164+
typedef ListSet<LabelledEnclosure> ESL;
165165
public:
166166
typedef ES EnclosureType;
167167
typedef ESL EnclosureListType;

0 commit comments

Comments
 (0)