Skip to content

Commit 746e51c

Browse files
committed
CORA v2026.0.0
- Automatic system identification: It is now possible to automatically identify a suitable dynamic model from data and establish reachset conformance via the identify and conform operators. We also overhauled how trajectories are handled in CORA to improve efficiency. For details, please visit Sec. 4.1.9, Sec. 4.1.11, and Sec. 7.2. - Neural network verification: We significantly improved the verification of neural networks in CORA, added the ability to verify graph neural networks, generate sufficient explanations for neural network predictions, and overhauled the training of verifiably robust neural networks. Details can be found in Sec. 6. - Set containment certificate: While contains has always returned true if CORA was able to determine containment, a returned false might also indicate that containment holds, but CORA is not able to determine it. To eliminate this ambiguity, contains now also returns a certificate on the result. Details are described in Sec. 2.1.2.1. - Visualizations: We revised the plotting capabilities of CORA and introduced a new default schema to plot sets to improve visibility on small monitors and beamers. It is also possible to create animated videos directly from CORA. Additionally, users might want to check CORAtables for better display of tabular data. For details, please visit Sec. 2.1.4.10. - Repeatability package: If you want to use CORA as part of a repeatability package, we got you covered and provide a Docker file with all dependencies installed. Instructions on how to set it up can be found in Appendix F. - Miscellaneous: Minor improvements have been made in various parts of the code: Some basic functionality runs more efficiently, several bug fixes result in an improved user experience, and more unit tests ensure greater reliability. Please also have a look at Appendix A.12 for deprecated functionality and their replacements.
1 parent 674cf93 commit 746e51c

File tree

1,550 files changed

+436322
-8376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,550 files changed

+436322
-8376
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
*.mexa32 filter=lfs diff=lfs merge=lfs -text
1414
*.mexa64 filter=lfs diff=lfs merge=lfs -text
1515
*.ins filter=lfs diff=lfs merge=lfs -text
16+

.github/ISSUE_TEMPLATE/issue-template.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ plot(Z2);
3535

3636
## Versions
3737

38-
- CORA version: *v2025.0.0* (type `CORAVERSION` in command window)
39-
- Matlab version: *R2024b* (type `version` in command window)
38+
- CORA version: *v202x.x.x* (type `CORAVERSION` in command window)
39+
- Matlab version: *R202xx* (type `version` in command window)
4040
- OS: *Linux/Windows/Mac*

.github/README.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.github/workflows/release-on-tag.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Get Commit Message
1616
id: get_commit_message
1717
run: |
18-
COMMIT_MESSAGE=$(git log -1 --pretty=format:%s ${{ github.ref }})
18+
COMMIT_MESSAGE=$(git log -1 --pretty=format:%B ${{ github.ref }})
1919
echo "commit_message=$COMMIT_MESSAGE" >> $GITHUB_ENV
2020
2121
- name: Create GitHub Release

.gitignore

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@ manual/*.pdf
3737
**/*.toc
3838
**/*.synctex.gz
3939
**/*-eps-converted-to.pdf
40+
**/*.synctex(busy)
4041

41-
manual/figures/externalize
42+
manual/figures/externalize/**/*.dpth
43+
manual/figures/externalize/**/*.log
44+
manual/figures/externalize/**/*.md5
4245

4346
*/.idea
4447
manual/manual.iml
4548

4649
# for MAC users
47-
**/.DS_Store
50+
**/.DS_Store
51+
52+
# exclude folders in workspace
53+
workspace/*

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,4 @@ Please visit `./unitTests/ci/repeatability-template` for details.
8484

8585
<hr style="height: 1px;">
8686

87-
<img src="./app/images/coraLogo_readme.svg"/>
87+
<img src="./app/images/coraLogo_readme.svg"/>

app/generate_file.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,10 @@
522522
% for Hybrid system the location was also inserted
523523
if ~strcmp(currentOption, 'Hybrid System')
524524
fprintf(id, '\n[t,x] = simulate(%s, paramsSim);\n', Sys);
525-
fprintf(id, 'simRes = simResult({x},{t});\n\n');
525+
fprintf(id, 'traj = trajectory([],x,[],t);\n\n');
526526
else
527527
fprintf(id, '\n[t,x,loc] = simulate(%s, paramsSim);\n', Sys);
528-
fprintf(id, 'simRes = simResult(x,t,loc);\n\n');
528+
fprintf(id, 'traj = trajectory([],x,[],t,[],loc);\n\n');
529529
end
530530

531531
elseif Random_Simulation
@@ -540,7 +540,7 @@
540540
fprintf(id, 'simOpt.fracInpVert = %s;\n', simOpt_fracInpVert_random);
541541
fprintf(id, 'simOpt.nrConstInp = %s;\n', simOpt_nrConstInp_random);
542542

543-
fprintf(id, '\nsimRes = simulateRandom(%s, params, simOpt);\n\n', Sys);
543+
fprintf(id, '\ntraj = simulateRandom(%s, params, simOpt);\n\n', Sys);
544544

545545
elseif Simulate_RRT
546546

@@ -558,7 +558,7 @@
558558
end
559559

560560
fprintf(id, 'simOpt.stretchFac = %s;\n', simOpt_stretchFac_RRT);
561-
fprintf(id, '\nsimRes = simulateRandom(%s, reachSet, params, simOpt, ''rrt'');\n\n', Sys);
561+
fprintf(id, '\ntraj = simulateRandom(%s, reachSet, params, simOpt, ''rrt'');\n\n', Sys);
562562
end
563563

564564
% ... write the fifth section which is the plotting settings
@@ -649,13 +649,13 @@
649649
fprintf(id, '\n %% plot simulation results');
650650
fprintf(id, '\n if length(projDims) == 1\n');
651651
if strcmp(color_simulation, 'gray')
652-
fprintf(id, ' plotOverTime(simRes, projDims, ''%s'', ''color'', %s);\n',line_simulation, gray_color);
652+
fprintf(id, ' plotOverTime(traj, projDims, ''%s'', ''color'', %s);\n',line_simulation, gray_color);
653653
fprintf(id, ' else\n');
654-
fprintf(id, ' plot(simRes, projDims, ''%s'', ''color'', %s);\n',line_simulation, gray_color);
654+
fprintf(id, ' plot(traj, projDims, ''%s'', ''color'', %s);\n',line_simulation, gray_color);
655655
else
656-
fprintf(id, ' plotOverTime(simRes, projDims, ''%s'', ''color'', ''%s'');\n',line_simulation, color_simulation);
656+
fprintf(id, ' plotOverTime(traj, projDims, ''%s'', ''color'', ''%s'');\n',line_simulation, color_simulation);
657657
fprintf(id, ' else\n');
658-
fprintf(id, ' plot(simRes,projDims, ''%s'', ''color'', ''%s'');\n',line_simulation, color_simulation);
658+
fprintf(id, ' plot(traj,projDims, ''%s'', ''color'', ''%s'');\n',line_simulation, color_simulation);
659659
end
660660
fprintf(id, ' end\n');
661661
end

contDynamics/@contDynamics/conform.m

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
function [params, results] = conform(sys,params,options,varargin)
1+
function [params,results] = conform(sys,params,options,varargin)
22
% conform - performs reachset conformance by computing the reachable
33
% of a system and checking whether all measurements are included
44
%
55
% Syntax:
6-
% [params, results] = conform(sys,params,options)
7-
% [params, results] = conform(sys,params,options,type)
6+
% [params,results] = conform(sys,params,options)
7+
% [params,results] = conform(sys,params,options,type)
88
%
99
% Inputs:
1010
% sys - contDynamics object
@@ -17,9 +17,9 @@
1717
% params - struct with conformant parameters
1818
% results - struct with the optimization results (dependent on type)
1919
% .R - reachSet object (only time steps for which measurments exist)
20-
% .simRes - states of the rapidly exploring random tree
21-
% .unifiedOutputs - unified test cases (only deviation to nominal
22-
% solution)
20+
% .traj - states of the rapidly exploring random tree
21+
% .unifiedOutputs - n_m x 1 cell array with dim_y x n_k x n_s
22+
% arrays describing the deviation to the nominal solution
2323
% .sys - updated system
2424
% .p - estimated parameters
2525
% .fval - final optimization cost
@@ -41,6 +41,7 @@
4141
% Authors: Matthias Althoff, Laura Luetzow
4242
% Written: 15-June-2023
4343
% Last update: 21-March-2024 (LL, change name from confSynth to conform)
44+
% 08-September-2025 (LL, change structure of unified outputs)
4445
% Last revision: ---
4546

4647
% ------------------------------ BEGIN CODE -------------------------------
@@ -52,47 +53,56 @@
5253
switch type
5354
case "RRT"
5455
% synthesize conformance using RRTs, see [1]
55-
[params, R, simRes] = priv_conform_RRT(sys, params, options);
56+
[params,R,traj] = priv_conform_RRT(sys,params,options);
5657
results.R = R;
57-
results.simRes = simRes;
58+
results.traj = traj;
5859

5960
otherwise
6061

61-
if contains(type,"black") % blackGP, blackCGP
62+
if type == "black"
6263
% approximate the system dynamics
63-
sys = priv_conform_black(params, options, type);
64+
traj = options.id.testSuite_id;
65+
options_ = options;
66+
options_.id = rmfield(options_.id, 'testSuite_id');
67+
if isa(sys, 'nonlinearARX') && contains(options.idAlg, 'gp')
68+
% requires system parameters and conformance testSuite for
69+
% identification
70+
options_.params = params;
71+
end
72+
sys = sys.identify(traj,options_);
73+
if options.id.save_res
74+
save(options.id.filename + "_sys", 'sys');
75+
end
76+
options = rmiffield(options,'id');
6477
results.sys = sys;
65-
options = rmfield(options, 'approx');
66-
params = rmfield(params, ["testSuite_train","testSuite_val"]);
6778
end
68-
79+
6980
% conformance synthesis for dedicated system dynamics
7081
[params,options] = validateOptions(sys,params,options);
7182
[sys_upd,params,options] = aux_updateSys(sys,params,options);
7283

7384
% Identify conformant parameters
74-
if type == "white" || contains(type,"black")
75-
[params, fval, p_opt, union_y_a] = priv_conform_white(sys_upd, params, options);
85+
if type == "white" || type == "black"
86+
[params,fval,p_opt,union_y_a] = priv_conform_white(sys_upd,params,options);
7687
results.sys = sys;
7788
results.unifiedOutputs = union_y_a;
78-
79-
elseif contains(type,"gray") % "graySim", "graySeq", "grayLS"
80-
[params, fval, p_opt, sys_opt] = priv_conform_gray(sys_upd, params, options, type);
89+
90+
elseif contains(type,"gray") % "graySim","graySeq","grayLS"
91+
[params,fval,p_opt,sys_opt] = priv_conform_gray(sys_upd,params,options,type);
8192
results.sys = sys_opt;
8293
end
83-
94+
8495
params = aux_updateUWV(params);
8596
results.fval = fval;
8697
results.p = p_opt;
87-
8898
end
8999

90100
end
91101

92102

93103
% Auxiliary functions -----------------------------------------------------
94104

95-
function [sys, params, options] = aux_updateSys(sys, params, options)
105+
function [sys,params,options] = aux_updateSys(sys,params,options)
96106
% preprocess sys, parameters and options
97107

98108
% augment input set with the additive uncertainty sets W and V if given
@@ -107,19 +117,9 @@
107117
sys = augment_u_with_v(sys);
108118
end
109119

110-
% add the dimensions of the optimization variables to options
111-
options.cs.n_a = size(params.U.generators,2) + size(params.R0.generators,2);
112-
if isa(sys, 'linearSysDT') || isa(sys, 'linearARX')
113-
% c can be computed with linear programming
114-
options.cs.n_c = size(params.U.generators,1) + size(params.R0.generators,1);
115-
else
116-
% c is not estimated in the linear program
117-
options.cs.n_c = 0;
118-
end
119-
120120
% adapt testSuite to the system dynamics (augment nominal input, update
121121
% initial state)
122-
params.testSuite = aux_preprocessTestSuite(sys, params.testSuite);
122+
params.testSuite = aux_preprocessTestSuite(sys,params.testSuite,options.cs.recMethod);
123123

124124
end
125125

@@ -141,45 +141,34 @@
141141

142142
end
143143

144-
function testSuite = aux_preprocessTestSuite(sys, testSuite)
144+
function testSuite = aux_preprocessTestSuite(sys,testSuite,recMethod)
145145
% preprocessTestSuite - preprocess testSuite, i.e.,
146146
% - augment nominal inputs with zeros to match input dimension of sys
147147
% - unify test cases for linear systems,
148148
% - adapt the initial state to the given system dynamics
149149

150150
% Augment nominal input with zeros
151151
for m = 1:length(testSuite)
152-
diff_u = sys.nrOfInputs - size(testSuite{m}.u,2);
152+
diff_u = sys.nrOfInputs - size(testSuite(m).u,1);
153153
if diff_u > 0
154-
u_in = cat(2, testSuite{m}.u, zeros(size(testSuite{m}.u,1), diff_u, size(testSuite{m}.u,3)));
155-
testSuite{m} = testCase(testSuite{m}.y, u_in, testSuite{m}.initialState, sys.dt, class(sys));
156-
end
157-
end
158-
159-
% Combine test cases for linear systems
160-
if (isa(sys, 'linearARX') || isa(sys, 'linearSysDT')) ...
161-
&& length(testSuite) > 1
162-
testSuite_m = combineTestCases(testSuite{1},testSuite{2});
163-
for m=3:length(testSuite)
164-
testSuite_m = combineTestCases(testSuite_m,testSuite{m});
154+
u_in = [testSuite(m).u; zeros(diff_u, testSuite(m).n_k)];
155+
testSuite(m) = trajectory(u_in, testSuite(m).x, testSuite(m).y, [], sys.dt, [], [], testSuite(m).name);
165156
end
166-
testSuite = {};
167-
testSuite{1} = testSuite_m;
168157
end
169158

170159
% Adaption initial state to state-space models
171160
if ~isa(sys, 'linearARX') && ~isa(sys, 'nonlinearARX')
172-
if sys.nrOfDims == size(testSuite{1}.initialState,1)
161+
if sys.nrOfDims == size(testSuite(1).x,1)
173162
% all good
174163
return
175164
end
176-
throw(CORAerror('CORA:notSupported',['Transformation of test cases created by input-output-models ' ...
165+
throw(CORAerror('CORA:notSupported',['Transformation of trajectories created by input-output-models ' ...
177166
'to state-space models is not implemented, yet.']))
178167
end
179168

180169
% Adaption initial state to input-output models
181-
if contains(testSuite{1}.name, ["ARX", "ARX"]) && ...
182-
sys.n_p*sys.nrOfOutputs == size(testSuite{1}.initialState,1)
170+
if contains(testSuite(1).name, ["ARX", "ARX"]) && ...
171+
sys.n_p*sys.nrOfOutputs == size(testSuite(1).x,1)
183172
% testSuite was generated by an input-output model with the same
184173
% model dimension
185174
% -> initial state should be set correctly
@@ -191,7 +180,7 @@
191180
n_m = length(testSuite);
192181
testSuite_new = {};
193182
for m=1:n_m
194-
testSuite_new = [testSuite_new; setInitialStateToMeas(testSuite{m},sys.nrOfDims)];
183+
testSuite_new = [testSuite_new; setInitialStateToMeas(testSuite(m),sys.nrOfDims)];
195184
end
196185
testSuite = testSuite_new;
197186

0 commit comments

Comments
 (0)