-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathidnlhybrid.m
123 lines (105 loc) · 4.13 KB
/
idnlhybrid.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
function model = idnlhybrid(modelname, order, params, ts, varargin)
%IDNLHYBRID Builds the Hybrid non linear model as an idnlgrey
% Argument Parsing
p = inputParser;
current_path = fullfile(pwd(), 'libhybrid');
validModelName = @(x) validateattributes(x, {'char'}, {'nonempty'});
validOrder = @(x) validateattributes(x, {'numeric'}, {'numel', 3});
validTs = @(x) true; % validateattributes(x, {'numeric'}, {'>', 0});
validBool = @(x) isa(x, 'logical');
validJumpCond = @(x) validatestring(x, {'C', 'D'});
addRequired(p, 'modelname', validModelName);
addRequired(p, 'order', validOrder);
addRequired(p, 'params');
addRequired(p, 'ts', validTs);
addParameter(p, 'ics', []);
addParameter(p, 'path', current_path, validModelName);
addParameter(p, 'jumpLogic', 'D', validJumpCond);
addParameter(p, 'forceCompile', false, validBool);
parse(p, modelname, order, params, ts, varargin{:});
args = p.Results;
% Checking sources and compiling
model_source = fullfile(pwd(), sprintf('%s.c', args.modelname));
if idnlhybrid_check_sources(model_source, args) || args.forceCompile
idnlhybrid_compile(model_source, args);
end
if ~exist(sprintf(modelname, mexext()), 'file')
error('LIBHYBRID:Idnlhybrid:ModelNotFound', 'File %s not found. Must be compiled', source);
end
% Fixing intitial conditions and order of the model
order_exp = args.order;
order_exp(3) = order_exp(3) + 2;
if ~isempty(args.ics)
if isa(args.ics, 'struct')
exp_size = size(args.ics(1).Value);
ics_exp(1).Name = 'Flow Time';
ics_exp(1).Unit = 'seconds';
ics_exp(1).Value = zeros(exp_size);
ics_exp(1).Minimum = -inf(exp_size);
ics_exp(1).Maximum = inf(exp_size);
ics_exp(1).Fixed = true;
ics_exp(2).Name = 'Jump Time';
ics_exp(2).Unit = 'jumps';
ics_exp(2).Value = zeros(exp_size);
ics_exp(2).Minimum = -inf(exp_size);
ics_exp(2).Maximum = inf(exp_size);
ics_exp(2).Fixed = true;
for i = 1:length(args.ics)
ics_exp(i + 2) = args.ics(i);
end
elseif isa(args.ics, 'numeric')
ics_exp = [zeros(1, size(args.ics,2)); zeros(1, size(args.ics,2)); args.ics];
else
error('LIBHYBRID:Idnlhybrid:InitialConditions', 'Unknown initial conditions type');
end
end
% Creating idnlgrey object with hybrid model
model = idnlgrey(args.modelname, order_exp, args.params, ics_exp, args.ts);
end
function compile = idnlhybrid_check_sources(model_source, args)
%IDNLHYBRID_CHECK_SOURCES Check that all files used in compilation exist
if ~exist(sprintf('%s.%s', args.modelname, mexext()), 'file')
compile = true;
return
end
sources = { ...
model_source, ...
sprintf('%s/libhybrid.h', args.path), ...
sprintf('%s/libhybrid.c', args.path), ...
sprintf('%s/librk4/librk4.h', args.path), ...
sprintf('%s/librk4/librk4.c', args.path), ...
sprintf('%s/mex_wrapper.c', args.path), ...
};
object_dir = dir(sprintf('%s.%s', args.modelname, mexext()));
for i = 1:length(sources)
source = sources{i};
if ~exist(source, 'file')
error('LIBHYBRID:Idnlhybrid:FileNotFound', 'File %s not found. Check the path!', source);
end
end
compile = false;
sources_dir = cellfun(@dir, sources);
model_time = object_dir.datenum;
for i = 1:length(sources_dir)
compile = compile || sources_dir(i).datenum > model_time;
end
end
function idnlhybrid_compile(model_source, args)
%IDNLHYBRID_COMPILE compiles the mex file
jump_logic = 1;
if (args.jumpLogic == 'C')
jump_logic = 2;
end
source_librk4 = sprintf('%s/librk4/librk4.c', args.path);
source_libhybrid = sprintf('%s/libhybrid.c', args.path);
source_mexwrapper = sprintf('%s/mex_wrapper.c', args.path);
include_dir_libhybrid = sprintf('-I%s', args.path);
include_dir_librk4 = sprintf('-I%s/librk4', args.path);
mex('-v', include_dir_libhybrid, include_dir_librk4, ...
'-DMATLAB_WRAPPER', ...
'-DMATLAB_SYSTEM_IDENTIFICATION', ...
sprintf('-DHYB_MODEL_SOURCE="\\"%s\\""', model_source), ...
sprintf('-DHYB_JUMP_LOGIC=%d', jump_logic), ...
source_librk4, source_libhybrid, source_mexwrapper, ...
'-output', args.modelname);
end