1
+ function options = rbfcreate(x , y , varargin )
2
+ % RBFCREATE Creates an RBF interpolation
3
+ % OPTIONS = RBFSET(X, Y, 'NAME1',VALUE1,'NAME2',VALUE2,...) creates an
4
+ % radial base function interpolation
5
+ %
6
+ % RBFCREATE with no input arguments displays all property names and their
7
+ % possible values.
8
+ %
9
+ % RBFCREATE PROPERTIES
10
+ %
11
+
12
+ %
13
+ % Alex Chirokov, alex.chirokov@gmail.com
14
+ % 16 Feb 2006
15
+ tic ;
16
+ % Print out possible values of properties.
17
+ if (nargin == 0 ) & (nargout == 0 )
18
+ fprintf(' x: [ dim by n matrix of coordinates for the nodes ]\n ' );
19
+ fprintf(' y: [ 1 by n vector of values at nodes ]\n ' );
20
+ fprintf(' RBFFunction: [ gaussian | thinplate | cubic | multiquadrics | {linear} ]\n ' );
21
+ fprintf(' RBFConstant: [ positive scalar ]\n ' );
22
+ fprintf(' RBFSmooth: [ positive scalar {0} ]\n ' );
23
+ fprintf(' Stats: [ on | {off} ]\n ' );
24
+ fprintf(' \n ' );
25
+ return ;
26
+ end
27
+ Names = [
28
+ ' RBFFunction '
29
+ ' RBFConstant '
30
+ ' RBFSmooth '
31
+ ' Stats '
32
+ ];
33
+ [m ,n ] = size(Names );
34
+ names = lower(Names );
35
+
36
+ options = [];
37
+ for j = 1 : m
38
+ options.(deblank(Names(j ,: ))) = [];
39
+ end
40
+
41
+ % **************************************************************************
42
+ % Check input arrays
43
+ % **************************************************************************
44
+ [nXDim nXCount ]=size(x );
45
+ [nYDim nYCount ]=size(y );
46
+
47
+ if (nXCount ~= nYCount )
48
+ error(sprintf(' x and y should have the same number of rows' ));
49
+ end ;
50
+
51
+ if (nYDim ~= 1 )
52
+ error(sprintf(' y should be n by 1 vector' ));
53
+ end ;
54
+
55
+ options.(' x' ) = x ;
56
+ options.(' y' ) = y ;
57
+ % **************************************************************************
58
+ % Default values
59
+ % **************************************************************************
60
+ options.(' RBFFunction' ) = ' linear' ;
61
+ options.(' RBFConstant' ) = (prod(max(x ' )-min(x ' ))/nXCount )^(1 / nXDim ); % approx. average distance between the nodes
62
+ options.(' RBFSmooth' ) = 0 ;
63
+ options.(' Stats' ) = ' off' ;
64
+
65
+ % **************************************************************************
66
+ % Argument parsing code: similar to ODESET.m
67
+ % **************************************************************************
68
+
69
+ i = 1 ;
70
+ % A finite state machine to parse name-value pairs.
71
+ if rem(nargin - 2 ,2 ) ~= 0
72
+ error(' Arguments must occur in name-value pairs.' );
73
+ end
74
+ expectval = 0 ; % start expecting a name, not a value
75
+ while i <= nargin - 2
76
+ arg = varargin{i };
77
+
78
+ if ~expectval
79
+ if ~isstr(arg )
80
+ error(sprintf(' Expected argument %d to be a string property name.' , i ));
81
+ end
82
+
83
+ lowArg = lower(arg );
84
+ j = strmatch(lowArg ,names );
85
+ if isempty(j ) % if no matches
86
+ error(sprintf(' Unrecognized property name ''%s'' .' , arg ));
87
+ elseif length(j ) > 1 % if more than one match
88
+ % Check for any exact matches (in case any names are subsets of others)
89
+ k = strmatch(lowArg ,names ,' exact' );
90
+ if length(k ) == 1
91
+ j = k ;
92
+ else
93
+ msg = sprintf(' Ambiguous property name ''%s'' ' , arg );
94
+ msg = [msg ' (' deblank(Names(j(1 ),: ))];
95
+ for k = j(2 : length(j ))'
96
+ msg = [msg ' , ' deblank(Names(k ,: ))];
97
+ end
98
+ msg = sprintf(' %s ).' , msg );
99
+ error(msg );
100
+ end
101
+ end
102
+ expectval = 1 ; % we expect a value next
103
+
104
+ else
105
+ options.(deblank(Names(j ,: ))) = arg ;
106
+ expectval = 0 ;
107
+ end
108
+ i = i + 1 ;
109
+ end
110
+
111
+ if expectval
112
+ error(sprintf(' Expected value for property ''%s'' .' , arg ));
113
+ end
114
+
115
+
116
+ % **************************************************************************
117
+ % Creating RBF Interpolatin
118
+ % **************************************************************************
119
+
120
+ switch lower(options.(' RBFFunction' ))
121
+ case ' linear'
122
+ options.(' rbfphi' ) = @rbfphi_linear ;
123
+ case ' cubic'
124
+ options.(' rbfphi' ) = @rbfphi_cubic ;
125
+ case ' multiquadric'
126
+ options.(' rbfphi' ) = @rbfphi_multiquadrics ;
127
+ case ' thinplate'
128
+ options.(' rbfphi' ) = @rbfphi_thinplate ;
129
+ case ' gaussian'
130
+ options.(' rbfphi' ) = @rbfphi_gaussian ;
131
+ otherwise
132
+ options.(' rbfphi' ) = @rbfphi_linear ;
133
+ end
134
+
135
+ phi = options.(' rbfphi' );
136
+
137
+ A= rbfAssemble(x , phi , options.(' RBFConstant' ), options.(' RBFSmooth' ));
138
+
139
+ b= [y ' ; zeros(nXDim + 1 , 1 )];
140
+
141
+ % inverse
142
+ rbfcoeff= A \ b ;
143
+
144
+ % SVD
145
+ % [U,S,V] = svd(A);
146
+ %
147
+ % for i=1:1:nXCount+1
148
+ % if (S(i,i)>0) S(i,i)=1/S(i,i); end;
149
+ % end;
150
+ % rbfcoeff = V*S'*U*b;
151
+
152
+
153
+ options.(' rbfcoeff' ) = rbfcoeff ;
154
+
155
+
156
+ if (strcmp(options.(' Stats' ),' on' ))
157
+ fprintf(' %d point RBF interpolation was created in %e sec\n ' , length(y ), toc );
158
+ fprintf(' \n ' );
159
+ end ;
160
+
161
+ function [A ]=rbfAssemble(x , phi , const , smooth )
162
+ [dim n ]=size(x );
163
+ A= zeros(n ,n );
164
+ for i= 1 : n
165
+ for j= 1 : i
166
+ r= norm(x(: ,i )-x(: ,j ));
167
+ temp= feval(phi ,r , const );
168
+ A(i ,j )=temp ;
169
+ A(j ,i )=temp ;
170
+ end
171
+ A(i ,i ) = A(i ,i ) - smooth ;
172
+ end
173
+ % Polynomial part
174
+ P= [ones(n ,1 ) x ' ];
175
+ A = [ A P
176
+ P ' zeros(dim + 1 ,dim + 1 )];
177
+
178
+ % **************************************************************************
179
+ % Radial Base Functions
180
+ % **************************************************************************
181
+ function u = rbfphi_linear(r , const )
182
+ u= r ;
183
+
184
+ function u = rbfphi_cubic(r , const )
185
+ u= r .* r .* r ;
186
+
187
+ function u = rbfphi_gaussian(r , const )
188
+ u= exp(-0.5 * r .* r /(const * const ));
189
+
190
+ function u = rbfphi_multiquadrics(r , const )
191
+ u= sqrt(1 + r .* r /(const * const ));
192
+
193
+ function u = rbfphi_thinplate(r , const )
194
+ u= r .* r .* log(r + 1 );
0 commit comments