arrayfun 中的统一输出错误中的非标量。怎么修?

Non-scalar in Uniform output error in arrayfun. How to fix?

我不确定在这种情况下它是什么意思。我尝试将“'uniformoutput',false”添加到 arrayfun 的末尾,但后来它对“+”运算符说 "Undefined operator '+' for input arguments of type 'cell'." 感到不安 我将其更改为“.+”但出现解析错误:( 哪里做错了?

这是损坏部分和错误的图片。完整代码如下,以防有人想尝试 运行 或复制损坏的部分。

完整代码:

    function gbp2(zi,zf)

global beam xlist ylist wi qi Ri wf qf Rf Psii Psif x n
beam = struct('E',[],'lambda',[],'w',[],'R',[],'q',[],'a',[]);

E = 1;                              % electric field
lambda = 1064*10^-9;                % wavelength
k = 2*pi/lambda;                    % wave number
wi = 10^-3;                         % initial waist width (minimum spot size)
zr = (pi*wi^2)/lambda;              % Rayleigh range
Ri = zi + zr^2/zi;
qi = 1/(1/Ri-1i*lambda/(pi*wi^2));  % initial complex beam parameter
Psii = atan(real(qi)/imag(qi));     % Gouy phase
mat = [1 zf; 0 1];                  % transformation matrix
A = mat(1,1); B = mat(1,2); C = mat(2,1); D = mat(2,2);
qf = (A*qi + B)/(C*qi + D);
wf = sqrt(-lambda/pi*(1/imag(1/qf)));
Rf = 1/real(1/qf);

u = @(z, coor, mode, w, R, Psi) (2/pi)^(1/4)*sqrt(exp(1i*(2*mode+1)*Psi)/(2^mode*factorial(mode)*w))*...
            hermiteH(mode,sqrt(2)*coor/w)*exp(-coor^2*(1/w^2+1i*k/(2*R))-1i*k*z);

% -------------------- ERROR IN THIS PIECE (below) ----------------------------
xlist = containers.Map('KeyType','double','ValueType','any');
ylist = containers.Map('KeyType','double','ValueType','any');

    function pts(z, w, R, Psi)
        xlist(z) = -2*w:10^-4:2*w;
        ylist(z) = zeros(1,size(xlist(z),2));
        for mode = 0:2:10
            ylist(z) = ylist(z) + arrayfun(@(coor) u(z, coor, mode, w, R, Psi),xlist(z),'uniformoutput',false);
        end
    end

pts(zi,wi,Ri,Psii)
pts(zf,wf,Rf,Psif)
plot(xlist(zi),ylist(zi),xlist(zf),ylist(zf)) end

我尝试编写一个类似但更简单的函数,它似乎工作得很好:

function test(zi, zf)

u = @(z,coor,mode) z*mode + integral(@(coor)coor,0,1);
xlist = containers.Map('KeyType','double','ValueType','any');
ylist = containers.Map('KeyType','double','ValueType','any');

    function pts(z)
        xlist(z) = -5:5;
        ylist(z) = zeros(1,size(xlist(z),2));
        for mode = 0:2:10
            ylist(z) = ylist(z) + arrayfun(@(coor) u(z,coor,mode),xlist(z));
        end
    end

pts(zi)
pts(zf)
plot(xlist(zi),ylist(zi),xlist(zf),ylist(zf))

end

所以我不确定我的代码有什么问题。

错误消息为您提供了重要提示:

Undefined operator '+' for input arguments of type 'cell'.

Error in gbp2/pts (line 36)
                   ylist(z) = ylist(z) + arrayfun(@(coor) u(z, coor, mode, w, R,
                   Psi),xlist(z).','uniformoutput',false);

来自 arrayfun and the 'UniformOutput' 选项的文档:

Requests that the arrayfun function combine the outputs into cell arrays B1,...,Bm. The outputs of function func can be of any size or type.

的确,如果你检查一下,这一行的输出是一个元胞数组:

arrayfun(@(coor) u(z, coor, mode, w, R, Psi),xlist(z),'uniformoutput',false)

您不能直接对元胞数组中的值求和。以下是您可以执行此操作的几种方法之一:

v = arrayfun(@(coor) u(z, coor, mode, w, R, Psi),xlist(z),'uniformoutput',false);
ylist(z) = ylist(z) + [v{:}];

但是,我完全不明白您为什么需要使用 'UniformOutput' 选项甚至是慢速 arrayfun。只需根据 coor:

向量化您的函数
u = @(z, coor, mode, w, R, Psi)(2/pi)^(1/4)*sqrt(exp(1i*(2*mode+1)*Psi)/(2^mode*factorial(mode)*w))*...
        hermiteH(mode,sqrt(2)*coor/w).*exp(-coor.^2*(1/w^2+1i*k/(2*R))-1i*k*z);

现在

ylist(z) = ylist(z) + u(z, xlist(z), mode, w, R, Psi);


一些额外的建议:Don't use global variables – they're inefficient 并且几乎总是有更好的解决方案。如果 pts 是一个嵌套函数,那么您缺少 gbp2 主函数的结束 end。重命名变量 mode 可能是个好主意,这样它就不会重载同名的内置函数。 Psif 未定义。而zeros(1,size(xlist(z),2))可以简单写成zeros(size(xlist(z))).