Repository navigation
Expand file tree
/
Copy pathFormLaplacian.m
More file actions
143 lines (121 loc) · 4.18 KB
/
Copy pathFormLaplacian.m
File metadata and controls
143 lines (121 loc) · 4.18 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
function [L_rbf,cnta,interp_struct] = FormLaplacian(Xd,rbf,drbf,d2rbf,tree,sz,ell)
%%Compute differential operators without an overlap parameter.
%The approach is to first compute a weight at the center, then
%compute its local L-Lebesgue function. For each subsequent point in
%stencil, compute the same, compare against center, and one
%ends up being worse than the center, reject that one and move onto the
%next one. We'll also check native space norms to ensure the weights are
%not too oscillatory.
Np = length(Xd);
row_index = zeros(sz,Np);
col_index = row_index;
wghts_lap = row_index;
%eps = zeros(Np,1);
ind_list = 1:Np; %Maintain list of global indices
iter = 1;
cnta = 1;
tarray = ones(1,sz);
s_dim = size(Xd,2);
recurrence = @(N) jacobi_recurrence(N,0,0);
a = total_degree_indices(s_dim,ell);
npoly = size(a,1);
estimated_num_stencils = floor(0.05*Np);
interp_struct = cell(estimated_num_stencils,12);
tX = tree.X;
%figure
while iter <= ind_list(end)
[je,~] = knnsearch(tree,Xd(iter,:),'k',sz);
je = je';
p = tX(je,1:s_dim);
nd = sz;
rd = sqrt(max(bsxfun(@plus,sum(p.*p,2),sum(p.*p,2)') - 2*(p*p'),0));
interp_struct{cnta,1} = Xd(iter,:);
interp_struct{cnta,2} = je;
interp_struct{cnta,3} = p;
%% Local augmented RBF interpolation matrix;
Ar = rbf(1,rd);
w2 = rd(1,nd);
cm = mean(p);
%pc = (p - repmat(cm,[nd,1]))/w2;
v = mpoly_eval(p,a,recurrence);
if s_dim==2
lp = mpoly_eval(p,a,recurrence,[2,0]) + mpoly_eval(p,a,recurrence,[0,2]);
elseif s_dim==3
lp = mpoly_eval(p,a,recurrence,[2,0,0])...
+ mpoly_eval(p,a,recurrence,[0,2,0])...
+ mpoly_eval(p,a,recurrence,[0,0,2]);
end
A = [[Ar v];[v.' zeros(npoly,npoly)]];
%% Decompose the matrix in LUP style
[la,ua,pa] = lu(A);
interp_struct{cnta,4} = la;
interp_struct{cnta,5} = ua;
interp_struct{cnta,6} = pa;
interp_struct{cnta,7} = npoly;
interp_struct{cnta,8} = ell;
interp_struct{cnta,9} = cm;
interp_struct{cnta,10} = w2;
%% Compute all rhs vals at once for BLAS3 efficiency.
D = drbf(1,rd);
B = [d2rbf(1,rd) + (s_dim-1)*D,lp];
%% Compute all weights and throw out a few.
full_weights = ((B/ua)/la)*pa;
%% Compute norms of center weights
lit = full_weights(1,:);
nsnorm1 = abs(lit*A*lit');
lebnorm1 = norm(lit,1);
wghts_lap(:,je(1)) = lit(1:nd);
row_index(:,je(1)) = je(1).*tarray;
col_index(:,je(1)) = je;
%% Keep as many weights as we safely can for this stencil
%%Keep track of which ones we computed weights for
it_list = zeros(1,nd);
it_list(1) = 1;
it_cnt = 2;
for it=2:nd
%% Compute weights
lit = full_weights(it,:);
%% Compute norm of weights
lebnorm = norm(lit,1);
nsnorm = abs(lit*A*lit');
%% compare against norm of stencil center and skip loop iteration
if nsnorm > nsnorm1 || lebnorm> lebnorm1
continue;
end
it_list(it_cnt)= it;
t1 = je(it);
g = ismember(t1,ind_list);
if g~=0
wghts_lap(:,t1) = lit(1:nd);
row_index(:,t1) = t1.*tarray;
col_index(:,t1) = je;
else
it_list(it_cnt) = 0;
end
it_cnt = it_cnt+1;
end
it_list = nonzeros(it_list);
%% Modify the index list to not include the indices for the nodes we've
% already computed the weights.
t1 = sort(je(it_list));
interp_struct{cnta,11} = t1;
interp_struct{cnta,12} = tX(t1,:);
for ii=1:length(t1)
ind_list(find(ind_list == t1(ii),1,'first'))= [];
end
if isempty(ind_list)
break;
else
iter = ind_list(1);
cnta = cnta+1;
end
end
%% Build diff mat
L_rbf = sparse(row_index(:),col_index(:),wghts_lap(:),Np,length(tX));
%% build kd-tree on stencil centers and pack back into interp
X_stencil = cell2mat(interp_struct(:,1));
stencil_tree = KDTreeSearcher(X_stencil);
interp_struct{cnta+1,1} = stencil_tree;
interp_struct{cnta+1,2} = recurrence;
interp_struct{cnta+1,3} = a;
end