如何在 MATLAB 中的函数中有序列?

How to have sequence in a function in MATLAB?

下面是一段代码,在没有 function/function 句柄的情况下也能正常工作。但是,我必须编写一个函数,以便我可以在 MATLAB 中使用“lsqcurvefit”的优化函数并优化参数 constant(1) 和 constant(2)。

L=zeros(n,length(S)); % Height of elements
L(:,1)=Linitial; % Height of elements for day zero
for jj=1:length(S)
   if jj==1
       continue
   end
    for j=1:n % n is 101 (previously defined...)
    
     L(j,jj) = @(constant, i_dt) L(j,jj-1) - (i_dt(j,jj).*constant(1).*((L(j,jj-1)./hs)-1)^constant(2)); %*****
     
    end
end

height_pred = @(constant,i_dt) sum(L); %heigh_pred(1) is known and previously defined
options = optimoptions('lsqcurvefit','FinDiffType','central',...
    'TolFun',1e-10);
constant = lsqcurvefit(height_pred,constant0,i_dt,height_meas,lb,ub,options);

当我 运行 上面的代码时,我收到错误“从 function_handle 转换为双精度是不可能的”对于带有 5 颗星的行 (*****)。

如果我删除函数句柄,而是在我的代码末尾编写一个函数,如下所示:

L=zeros(n,length(S)); % Height of elements
L(:,1)=Linitial; % Height of elements for day zero
for jj=1:length(S)

      for j=1:n % n is 101 (previously defined...)
         L(j,jj) = Nelfun(j,jj);
      end
end

height_pred = @(constant,i_dt) sum(L); %heigh_pred(1) is known and previously defined
options = optimoptions('lsqcurvefit','FinDiffType','central',...
    'TolFun',1e-10);
constant = lsqcurvefit(height_pred,constant0,i_dt,height_meas,lb,ub,options);

function L = Nelfun(constant,i_dt)
for jj=1:145
   if jj==1
       L(:,1)=0.0187600000000000;
       continue
   end
      for j=1:101
         L(j,jj-1);
         L(j,jj) = L(j,jj-1) - (i_dt(j,jj).*constant(1).*((L(j,jj-1)./hs)-1)^constant(2)); %*****
      end
end
end

我收到错误

"Index exceeds matrix dimensions" for line with (*****). 

矩阵的大小 i_dt 是 (101,145),L 是 (101,145),height_meas(1,145),height_pred(1,145)。

jj==1 的 L(j,jj) 是已知的,但随后应该针对 L(:,2) 到 L(:,145) 进行计算和优化。

              ***

感谢 Praveen,“索引超出矩阵维度”问题已解决,但现在我收到错误

"Error using snls (line 183)
Finite difference Jacobian at initial point contains Inf or NaN values. lsqcurvefit cannot continue." 

以下代码:

lb = [0.000000000001,0.05]; ub = [1,50]; constant0 = [1.06e-09,15.2];

height_pred = @(constant,i_dt) sum(Nelfun(constant,i_dt)); 

options = optimoptions('lsqcurvefit','FinDiffType','central',...
    'TolFun',1e-10);
constant = lsqcurvefit(height_pred,constant0,i_dt,height_meas,lb,ub,options);

function L = Nelfun(constant,i_dt)
L=zeros(size(i_dt));
n=101; % number of nodes
ei=2.05613504572765; 
e0=ei.*ones(n,1);
Hsolid=0.613847219422639; 
hs = Hsolid./(n-1);
for JJ=1:size(i_dt,2)
   if JJ==1
     for j=1:n
         Linitial0=hs.*(1+e0);
         Linitial0(1)=0;
     end
     L(:,JJ) = Linitial0;
     continue
   end
     for J=1:size(i_dt,1)
         L(J,JJ) = L(J,JJ-1) - (i_dt(J,JJ).*constant(1).*((L(J,JJ-1)./hs)-1)^constant(2));
     end
end
end

在第一种情况下,您无法创建函数句柄数组。你可以使用元胞数组,但我不明白你为什么需要它。

让我们处理你的第二个案例。

%I don't know what is hs, I assume it a scalar
hs=myhs;
%call the Nelfun in your function handle
height_pred = @(constant,i_dt) Nelfun(constant,i_dt,hs);


options = optimoptions('lsqcurvefit','FinDiffType','central',...
    'TolFun',1e-10);
% Constant0 should be 2 element array
constant0=[0,0];
constant = lsqcurvefit(height_pred,constant0,i_dt,height_meas,lb,ub,options);

function L = Nelfun(constant,i_dt,hs)% why hs is not passed
L=zeros(size(i_dt)); % Always initialize before filling it up
for jj=1:size(i_dt,2) %use adaptive indexing
   if jj==1
       L(:,jj)=0.0187600000000000;
       continue
   end
      for j=1:size(i_dt,1) %use adaptive indexing
         L(j,jj) = L(j,jj-1) - (i_dt(j,jj).*constant(1).*((L(j,jj-1)./hs)-1)^constant(2));
      end
   
end