【问题标题】:Can someone explain how to graph this sum in MATLAB using contourf?有人可以解释如何在 MATLAB 中使用 contourf 绘制这个总和吗?
【发布时间】:2013-01-09 00:26:08
【问题描述】:

我将首先说明,是的,这是作业(我在 stackoverflow 上的第一个作业问题!)。但我不想让你帮我解决,我只是想要一些指导!

有问题的等式是这样的:

我被告知取 N = 50, phi1 = 300, phi2 = 400, 0

所以我做的第一件事就是设置这些变量,并使用 x = linspace(0,1) 和 y = linspace(0,1) 来制作正确的向量。

问题是编写一个名为 potential.m 的 MATLAB 脚本文件,该文件计算 phi(x,y) 并使用内置函数 contourf 绘制与 x 和 y 的填充等值线图(参见MATLAB 中的帮助命令示例)。确保正确标记图形。 (提示:域的顶部和底部应该在 400 度左右,而左侧和右侧应该在 300 度左右)。

但是,以前,我使用 x 或 y 作为常数来计算 phi。如果两者都是变量,我应该如何计算它?我是否保持 x 稳定,同时遍历 y 向量中的每个数字,将其分配给矩阵,在一次又一次地遍历 y 的每个值后将 x 递增到其向量中的下一个数字?然后做同样的过程,但是慢慢地增加 y?

如果是这样,我一直在使用一个循环,每次循环遍历所有 100 个值时都会递增到下一行。如果我这样做,我最终会得到一个有 200 行和 100 列的巨大矩阵。我将如何在 linspace 函数中使用它?

如果正确,这就是我找到矩阵的方式:

clear
clc
format compact
x = linspace(0,1);
y = linspace(0,1);
N = 50;
phi1 = 300;
phi2 = 400;
phi = 0;
sum = 0;
for j = 1:100
    for i = 1:100
        for n = 1:N
            sum = sum + ((2/(n*pi))*(((phi2-phi1)*(cos(n*pi)-1))/((exp(n*pi))-(exp(-n*pi))))*((1-(exp(-n*pi)))*(exp(n*pi*y(i)))+((exp(n*pi))-1)*(exp(-n*pi*y(i))))*sin(n*pi*x(j)));
        end
        phi(j,i) = phi1 - sum;
    end
end
for j = 1:100
    for i = 1:100
        for n = 1:N
            sum = sum + ((2/(n*pi))*(((phi2-phi1)*(cos(n*pi)-1))/((exp(n*pi))-(exp(-n*pi))))*((1-(exp(-n*pi)))*(exp(n*pi*y(j)))+((exp(n*pi))-1)*(exp(-n*pi*y(j))))*sin(n*pi*x(i)));
        end
        phi(j+100,i) = phi1 - sum;
    end
end

这是contourf的定义。我想我必须使用 contourf(X,Y,Z):

contourf(X,Y,Z)、contourf(X,Y,Z,n) 和 contourf(X,Y,Z,v) 使用 X 和 Y 绘制 Z 的填充等值线图以确定 x 和y 轴限制。当 X 和 Y 是矩阵时,它们的大小必须与 Z 相同,并且必须单调递增。

这是新代码:

N = 50;
phi1 = 300;
phi2 = 400;
[x, y, n] = meshgrid(linspace(0,1),linspace(0,1),1:N)
f = phi1-((2./(n.*pi)).*(((phi2-phi1).*(cos(n.*pi)-1))./((exp(n.*pi))-(exp(-n.*pi)))).*((1-(exp(-1.*n.*pi))).*(exp(n.*pi.*y))+((exp(n.*pi))-1).*(exp(-1.*n.*pi.*y))).*sin(n.*pi.*x));
g = sum(f,3);
[x1,y1] = meshgrid(linspace(0,1),linspace(0,1));
contourf(x1,y1,g)

【问题讨论】:

    标签: matlab plot vectorization graphing


    【解决方案1】:

    矢量化代码。例如你可以写f(x,y,n)

     [x y n] = meshgrid(-1:0.1:1,-1:0.1:1,1:10);
     f=exp(x.^2-y.^2).*n ;
    

    f 是一个 3D 矩阵,现在只是 sum 在正确的维度上...

     g=sum(f,3);
    

    为了使用contourf,我们只取x,y的二维部分:

     [x1 y1] = meshgrid(-1:0.1:1,-1:0.1:1);    
     contourf(x1,y1,g)
    

    【讨论】:

    • 所以我了解网格网格,以及它如何使两个矩阵的每个组合变得快速。但我不确定如何将我的总和放入格式中以便像这样使用它。我有 sum = sum + blah 循环,然后必须做 phi1 - sum。你们向我展示的方式似乎比我的做法容易得多,但我不确定如何使我的问题适应你们的方法。
    • 所以等一下,我是否按照所说的那样进行循环,但是我使用 x 和 y 作为 meshgrid 的结果,并使用点运算符使等式中执行的操作发生在每个一次矩阵的单个部分?
    • 我在原始帖子的末尾添加了我尝试过的内容,但没有成功。你觉得你能告诉我哪里出错了吗?
    • 查看我编辑的答案,还有什么没用?顺便说一句,不要使用sum这个词作为你的变量,你正在覆盖matlab的一个重要功能......
    • 我尝试按照您之前答案的格式制作一个程序,并将其放在上面的原始帖子底部。它给了我错误,因为我做错了。所以 3D 矩阵是第一维和第二维中的 x 和 y 值,以及我想要的第三维中的实际值。所以我做 phi = sum(f,3)?我查找了如何在一维中对 3D 矩阵求和,我发现 sum 函数可以用作 sum(matrix,dimension)。除非我误解了一切,这是最有可能的。顺便谢谢你的帮助!事情正在变得清晰。
    【解决方案2】:

    您的代码需要这么长时间来计算phi 矩阵的原因是您没有pre-allocate the array。发生大小错误是因为 phi 不是 100x100。但与其修复这些问题,还有更好的方法......

    MATLAB 是一个 MATrix LABoratory,所以这种类型的方程很容易使用矩阵运算来计算。提示:

    1. 不要循环遍历xy 的值、行或列,而是构造矩阵来表示所有可能的输入组合。请查看meshgrid

    2. 您仍然需要一个循环来对 n = 1:N 求和。但是对于每个 n 值,您可以一次计算所有 x 和 y 的方程(使用提示 1 中的矩阵)。完成这项工作的关键是使用element-by-element operators,例如.*./

    像这样使用矩阵运算是 Matlab 方式。学习并爱上它。 (并且在使用大多数其他没有它们的语言时会感到沮丧。)

    祝你作业顺利!

    【讨论】:

    • 这是一个愚蠢的问题,但如果我像这样预先分配托盘,我的矩阵会保持那么大,即使在插入值之后?如果我尝试做controuf,它也会通过所有这些零吗?令我印象深刻的是,它将计算该数组的时间缩短了 2/3!太疯狂了。我很难理解如何为此目的使用 meshgrid 函数。你认为你能很快解释清楚吗?很难阅读和理解它在做什么,因为它有点超出我的编程水平。
    • 200 x 100 元素的矩阵并不大。它只需要大约 160 KB 内存...按照@Shoelzer 的建议对您的代码进行矢量化
    • @TheTreeMan natan 的回答是使用网格网格的一个很好的例子。
    猜你喜欢
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 2012-04-19
    • 2021-01-06
    相关资源
    最近更新 更多