surface fitting using a self-defined function

6 ビュー (過去 30 日間)
Erkang
Erkang 2023 年 6 月 22 日
編集済み: Stephen23 2023 年 6 月 22 日
I am trying to use a self-defined function to fit a surface. This self-defined function is a zernike polynomial function. It's almost working. but I got the error messege saying "Expression zernike_surf_fit(xy, a, b, c, d, e) is not a valid MATLAB expression, has non-scalar coefficients, or cannot be evaluated:"
main function is:
[X, Y] = meshgrid(linspace(-0.8, 0.8, 10), linspace(-0.8, 0.8, 10));
xy=[(X(:)-5.5)/5.5 (Y(:)-5.5)/5.5];
ft = fittype('zernike_surf_fit(xy, a, b, c, d, e)',...
'independent', {'xy'}, 'dependent', {'Z'},...
'coefficients',{'a','b','c','d','e'});
Error using fittype/testCustomModelEvaluation
Expression zernike_surf_fit(xy, a, b, c, d, e) is not a valid MATLAB expression, has non-scalar coefficients, or cannot be evaluated:
Error in fittype expression ==> zernike_surf_fit(xy, a, b, c, d, e)
??? Undefined function 'zernike_surf_fit' for input arguments of type 'double'.

Error in fittype>iCreateFittype (line 373)
testCustomModelEvaluation( obj );

Error in fittype (line 330)
obj = iCreateFittype( obj, varargin{:} );

Caused by:
Error using fittype/evaluate>I_ERROR_FCN_
Error in fittype expression ==> zernike_surf_fit(xy, a, b, c, d, e)
??? Undefined function 'zernike_surf_fit' for input arguments of type 'double'.
the zernike_surf_fit function is saved under the same file. It looks like below:
function [Z] = zernike_surf_fit(xy,a,b,c,d,e)
Z = zeros(size(xy, 1),1);
X = reshape(xy(:,1),[sqrt(length(xy(:,1))),sqrt(length(xy(:,1)))]);
Y = reshape(xy(:,2),[sqrt(length(xy(:,2))),sqrt(length(xy(:,2)))]);
%[X,Y] = meshgrid(x,y);
[theta,r] = cart2pol(X,Y);
idx = r<=1;
p = 1:5;
z = nan(size(X));
C=[a b c d e];
y = zernfun2(p,r(idx),theta(idx));
z_sum=[];
for k = 1:length(p)
z(idx) = C(k)*y(:,k);
if k==1
z_sum=z;
else
z_sum=z_sum+z;
end
end
Z_temp=reshape(z_sum,[sqrt(length(xy(:,1)))*sqrt(length(xy(:,1))),1]);
Z=Z_temp;
end
The zernike function here can generate zernike surface perfectly. So I think the only problem is the variable a b c d e.
I am really appriciate your help.
  2 件のコメント
Torsten
Torsten 2023 年 6 月 22 日
I suggest you try to call "zernike_surf_fit" with reasonable values for a,...,e and see what it returns for Z. MATLAB does not like the output.
Erkang
Erkang 2023 年 6 月 22 日
Yeah if I sed the a,..,e all to a constant value. it returns a 1D array to Z, which is what I expecting. But it just cannot do any surface fitting if I use all constants. It wroks now. I just copied the code in the comment section by Matt. Thanks a lot, Torsten.

サインインしてコメントする。

採用された回答

Matt J
Matt J 2023 年 6 月 22 日
編集済み: Matt J 2023 年 6 月 22 日
Your model function is not supposed to assume that the xy samples are drawn from a Cartesian grid lattice.
ft = fittype(@(a,b,c,d,e, x,y)zernike_surf_model([x,y], [a, b, c, d, e]),...
'independent', {'x','y'}, 'dependent', {'Z'},...
'coefficients',{'a','b','c','d','e'})
ft =
General model: ft(a,b,c,d,e,x,y) = zernike_surf_model([x,y],[a,b,c,d,e])
function [Z] = zernike_surf_model(xy,C)
X = xy(:,1);
Y = xy(:,2);
[theta,r] = cart2pol(X,Y);
idx = r<=1;
Z = nan(size(X));
Z(idx)=zernfun2(1:numel(C),r(idx),theta(idx)) * C(:);
end
  1 件のコメント
Erkang
Erkang 2023 年 6 月 22 日
編集済み: Stephen23 2023 年 6 月 22 日
Damn Matt, that is so concise and works perfectly. Thanks you so much.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeZernike Polynomials についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by