-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunction_wrapper.m
104 lines (96 loc) · 4.39 KB
/
function_wrapper.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
classdef function_wrapper < handle
%TAG Groups together some commmon attributes of trajectories
properties(GetAccess = 'public', SetAccess = 'protected')
description = [];
% name of the function
function_name = [];
% function used to calculate the value
function_handle = [];
% return value number to use
return_arg = 1;
% name of configurable parameters
parameters = {};
% values of the configurable parameters
parameter_values = {};
% other fixed arguments
other_args = {};
end
properties(GetAccess = 'private', SetAccess = 'private')
hash_ = [];
args_ = [];
end
methods
%% constructor
function inst = function_wrapper(desc, func, rarg, prop, varargin)
inst.description = desc;
inst.function_name = func;
if func(1) == '@'
inst.function_handle = eval(func);
else
inst.function_handle = str2func(func);
end
if nargin > 2
inst.return_arg = rarg;
end
if nargin > 3
inst.parameters = prop;
end
if nargin > 4
inst.other_args = varargin;
end
end
function val = hash_value(inst)
if isempty(inst.hash_)
% if this assertion fires the parameters have not been set
% yet
assert(length(inst.parameters) == length(inst.parameter_values));
inst.hash_ = hash_value({inst.function_name, inst.return_arg, inst.parameter_values{:}, inst.other_args{:}});
end
val = inst.hash_;
end
function set_parameters(inst, config)
inst.parameter_values = {};
for i = 1:length(inst.parameters)
inst.parameter_values = [inst.parameter_values, config.property(inst.parameters{i})];
end
end
function ret = apply(inst, varargin)
% check if parameters set have not been set
assert(length(inst.parameters) == length(inst.parameter_values));
switch inst.return_arg
case 1
ret = inst.function_handle(varargin{:}, inst.parameter_values{:}, inst.other_args{:});
case 2
[~, ret] = inst.function_handle(varargin{:}, inst.parameter_values{:}, inst.other_args{:});
case 3
[~, ~, ret] = inst.function_handle(varargin{:}, inst.parameter_values{:}, inst.other_args{:});
case 4
[~, ~, ~, ret] = inst.function_handle(varargin{:}, inst.parameter_values{:}, inst.other_args{:});
case 5
[~, ~, ~, ~, ret] = inst.function_handle(varargin{:}, inst.parameter_values{:}, inst.other_args{:});
otherwise
error('Too many return arguments');
end
end
%% This calls the function using 1 argument + N arguments that are appended
%% after the parameters set in the function object
function ret = apply1(inst, arg, varargin)
% check if parameters set have not been set
assert(length(inst.parameters) == length(inst.parameter_values));
switch inst.return_arg
case 1
ret = inst.function_handle(arg, inst.parameter_values{:}, varargin{:}, inst.other_args{:});
case 2
[~, ret] = inst.function_handle(arg, inst.parameter_values{:}, varargin{:}, inst.other_args{:});
case 3
[~, ~, ret] = inst.function_handle(arg, inst.parameter_values{:}, varargin{:}, inst.other_args{:});
case 4
[~, ~, ~, ret] = inst.function_handle(arg, inst.parameter_values{:}, varargin{:}, inst.other_args{:});
case 5
[~, ~, ~, ~, ret] = inst.function_handle(arg, inst.parameter_values{:}, varargin{:}, inst.other_args{:});
otherwise
error('Too many return arguments');
end
end
end
end