求问matlab下用循环建立符号数组的办法

RT,现在希望实现这样一个功能:需要创建一个较大的四维数组(50*50*50*50),每个元素都是类似sin((i+j+k+l)*pi*x)这种形式,其中x为符号,请问该用哪个指令?多谢。
顺带一提,输入完之后还要对这个数组做定积分,int命令会不会太慢?如果是的话,还请大大们提个建议的算法。

就这个问题自身而言,并不算困难,例如,用下面几行代码就可以:

N=5;
[i,j,k,l]=ndgrid(1:N,1:N,1:N,1:N);
syms x
y=sin((i+j+k+l)*pi*x);
I=int(y,0,0.5);

注意,这里我只是示范解决问题的基本思路,所以,把问题规模大幅度减小为N=5。

 

使用MATLAB的profiler可以分析执行这些代码所需的时间,以下是取N=5和10所对应的结果:

 

我另外尝试了N=20的情况,在我的机器上算了1个小时还没出来结果。具体情况和硬件配置、操作系统、MATLAB版本等因素都有关系,所以,这些只能作为一个参照。尽管如此,我们也可以想象,如果取N=500,即使现在最豪华配置的PC,计算时间只怕也要以天为单位(而且,很难保证是否会出现内存溢出等情况)。

 

通过上面的分析,基本上可以说,这种做法不可行。有没有可能通过对程序进行优化来解决呢?上面的代码使用了向量化的运算,照理说,已经是MATLAB最高效率的代码写法了。如果改写成显式循环的方法,代码如下:

N=5;
[i,j,k,l]=ndgrid(1:N,1:N,1:N,1:N);
syms x
y=sym(zeros(N,N,N,N));
n=i+j+k+l;
I=zeros(N,N,N,N);
for ii=1:N^4
    y(ii)=sin(n(ii)*pi*x);
    I(ii)=int(y(ii),0,0.5);
end

这段代码对于N=5和N=10的运行结果如下:

 

可见,使用循环的代码比起向量化代码,所需时间还要长很多。

 

那么,这个问题究竟还有没有更有效率的解法呢?

 

我认为,如果每个元素都是类似sin((i+j+k+l)*pi*x)这种形式,比较合理的做法应该是,把系数(i+j+k+l)看成一个常数,记作n,先对sin(n*pi*x)求定积分得到关于n的一般表达式,然后再把具体的系数代入,代码大致如下:

N=50;
syms x n
f=sin(n*pi*x);
I=int(f,0,0.5);
[i,j,k,l]=ndgrid(1:N,1:N,1:N,1:N);
I=inline(I);
I=I(i+j+k+l);

注意,最后两行先转换为inline函数再代入,而不是直接subs,二者效率差别十分巨大,可自行比较。

 

最后看一下结果。这里即使取N=50(如果N更大,所需内存较多),所需时间也很短,而前面的算法即使对于N=20已经基本上无法计算了:

上述代码在2007b上调试,在其他版本可能会有不同,特此提示。如果有疑问可继续追问。

追问

多谢多谢。这个问题其实我已经用另一个方法解决了。
虽然笨了点,但很有效。
syms x;
B=zeros(n,n,n,n);
A=sym(B);下面的循环打不下了,坑爹,但反正就是这样解决了问题。
另外,50*50*50*50的数组用matlab计算不太现实,关键是符号变量太大,把内存耗尽了,我问了问老师,他说取到20也能满足要求精度。
话说,QUADV指令效率高么?

追答

50*50*50*50的数组确实比较大,如果是double类型,需要50M的内存,但sym所需的内存要多的多,而且计算过程中要启动符号运算引擎(Maple或MuPad),相关的数据在运算引擎内也有相应的内存需求(很可能不少于MATLAB自身),只怕现在大多数的PC机还很难承受。

就你的问题自身而言,因为各元素存在通式,所以可以先用符号运算把积分的函数表达式求出来,然后使用inline函数直接计算,这样速度快而且精度有保证。可能的条件下尽量用这种方法。

quadv是基于纯数值计算的,效率应该还可以,要看具体的问题和做法。不过,可以肯定,效率肯定远远不如上面说的先符号后inline的方法,但比起直接用int计算效率会高。

温馨提示:内容为网友见解,仅供参考
无其他回答

求问matlab下用循环建立符号数组的办法
N=5;[i,j,k,l]=ndgrid(1:N,1:N,1:N,1:N);syms xy=sym(zeros(N,N,N,N));n=i+j+k+l;I=zeros(N,N,N,N);for ii=1:N^4 y(ii)=sin(n(ii)*pi*x); I(ii)=int(y(ii),0,0.5);end这段代码对于N=5和N=10的运行结果如下:可见,使用循环的代码比起向量化代...

求问matlab下用循环建立符号数组的办法
N=5;[i,j,k,l]=ndgrid(1:N,1:N,1:N,1:N);syms xy=sym(zeros(N,N,N,N));n=i+j+k+l;I=zeros(N,N,N,N);for ii=1:N^4 y(ii)=sin(n(ii)*pi*x); I(ii)=int(y(ii),0,0.5);end这段代码对于N=5和N=10的运行结果如下:可见,使用循环的代码比起向量化代...

matlab里想建立一个符号数组
>> n=input('请输入数组长度:n=');请输入数组长度:n=10>> A=sym(zeros(n,1));>> for i=1:n, A(i)=eval(sprintf('sym(''a%i'')',i));end>> whos Name Size Bytes Class A 10x1 706 sym object i 1x1 8 double array n 1x1 8 doub...

matlab如何将循环中得到的结果形成一个对应的数组,就是循环几次有几组 ...
把 z=[t',dis1'] 改成 z=[z,dis1']; 即可。虽然不是最好的做法,但对于题主现在的具体问题而言足够了。

matlab for循环如何创建出多个数组
matlab里索引不能是负的。也就是s{x}中x不能是负的,将x=-3:3 换成x=[-3:3]+4 即可。至于你想得到负的索引,你记一下就行

MATLAB 用循环生成数组
你好!for i=1:10 disp(ones(i,10-i))fprintf('\\n')end 希望我的回答对你有所帮助!!

matlab如何用for循环写x1+x2+x3的表达式?
matlab如何用for循环写x1+x2+x3的表达式?这个问题我们可以通过两个函数的转换来实现,即 y=x1+x2+x3 1、使用num2str()函数,将数字转换为字符数组,即 str = ['x',num2str(i)]2、使用str2sym()函数,将字符数组变量转换成符号函数表达式,即 y=str2sym(str)3、然后用for...

matlab循环语句中符号变量的设置求助,本人刚接触matlab,求大神指引
clear p=0;q=597.5078432583508e;syms m n;for i=1:15 [m,n]=solve('m^2+n^2=5.985078432583508e+02*sqrt(m^2+n^2)-n','(m-p)^2+(n-q)^2=25');p(i)=double(m);q(i)=double(n);怎么在此处把p q返回到一个数组变量中 end 和你源程序对照一下,运行试试看,符合你...

matlab循环问题 我想在for循环中调用子程序赋值,但是总是不行,求各位...
改后的代码如下,供参考(再次声明:这种实现方式非常糟糕,我只是帮你解决眼下的问题,绝对不意味着鼓励你继续编写这么乱的代码)。function zd508792902global u;global i ;t=0.01;for i=2:10;if (i-1)==1;u(i-1)=0;y(i-1)=0;x(i-1)=0;end ju end u function juglobal i;glob...

matlab数组循环赋值
首先,创建一个 3x3 零矩阵A。接着,采用嵌套循环遍历矩阵元素,执行计算或赋值操作。此处,每个元素值被设置为行号乘以列号。最终,使用 disp 函数展示更新后的矩阵 A。循环赋值灵活多变,根据具体需求修改循环体内代码,实现不同元素的赋值操作。此示例说明如何遍历与赋值数组元素。下面提供 MATLAB 数组...

相似回答