-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathevaldiag_bifd.m
More file actions
129 lines (102 loc) · 3.11 KB
/
evaldiag_bifd.m
File metadata and controls
129 lines (102 loc) · 3.11 KB
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
124
125
126
127
128
129
function evalarray = evaldiag_bifd(evalarg, bifdobj, sLfd, tLfd)
%EVALDIAG_BIFD evaluates a bi-functional data object BIFD
% with both argument values in array EVALARG.
% SLfd and TLfd are either integers giving the order of derivative,
% or linear differential operators to be applied before evaluation.
% Their defaults are 0, meaning that the function itself is evaluated.
% last modified 20 July 2006
% check that at least three arguments are present
if nargin < 2
error('There are less than two arguments.');
end
% exchange order if BIFD is the first argument
if isa_bifd(evalarg)
temp = bifdobj;
bifdobj = evalarg;
evalarg = temp;
end
% check EVALARG
sizeevalarg = size(evalarg);
if sizeevalarg(1) > 1 && sizeevalarg(2) > 1
error('Argument EVALARG is not a vector.');
end
evalarg = evalarg(:);
% set default differential operators
if nargin < 4
tLfd = int2Lfd(0);
end
if nargin < 3
sLfd = int2Lfd(0);
end
if ~isa_bifd(bifdobj)
error('Argument BIFD is not a bivariate functional data object.');
end
n = length(evalarg);
% extract the two bases
sbasisobj = getsbasis(bifdobj);
tbasisobj = gettbasis(bifdobj);
% check that the bases have the same range
ranges = getbasisrange(sbasisobj);
ranget = getbasisrange(tbasisobj);
if any(ranges ~= ranget)
error('The ranges are not identical.');
end
% check the differential operators
sLfd = int2Lfd(sLfd);
tLfd = int2Lfd(tLfd);
if ~isa_Lfd(sLfd)
error ('SLFD is not a linear differential operator object.');
end
if ~isa_Lfd(tLfd)
error ('TLFD is not a linear differential operator object.');
end
% compute the basis matrix for SBASISOBJ
snderiv = getnderiv(sLfd);
if snderiv > 0 && ~strcmp(class(sLfd), 'double')
derivwtmat = eval_basis(evalarg, sbasisobj, sLfd);
for j = 1:snderiv
if any(abs(derivwtmat(:,j))) > 1e-7
sbasismat <- sbasismat + ...
(derivwtmat(:,j)*onerow) .* ...
eval_basis(evalarg, sbasisobj, j-1);
end
end
end
% compute the basis matrix for tBASISOBJ
tnderiv = getnderiv(tLfd);
if tnderiv > 0 && ~strcmp(class(tLfd), 'double')
derivwtmat = eval_basis(evalarg, tbasisobj, tLfd);
for j = 1:tnderiv
if any(abs(derivwtmat(:,j))) > 1e-7
tbasismat <- tbasismat + ...
(derivwtmat(:,j)*onerow) .* ...
eval_basis(evalarg, tbasisobj, j-1);
end
end
end
% Extract the coefficient matrix
coef = getcoef(bifdobj);
coefd = size(coef);
ndim = length(coefd);
switch ndim
case 2
evalarray = diag(sbasismat * coef * tbasismat');
case 3
ncurves = coefd(3);
evalarray = zeros(n,ncurves);
for i=1:ncurves
evalarray(:,i) = diag(sbasismat * coef(:,:,i) * tbasismat');
end
case 4
ncurves = coefd(3);
nvar = coefd(4);
evalarray = zeros(n,ncurves,nvar);
for i = 1:ncurves
for j = 1:nvar
evalarray(:,i,j) = ...
diag(sbasismat * coef(:,:,i,j) * tbasismat');
end
end
otherwise
error('coefficient array of improper dimension');
end