LLLLLL林 2024-05-25 12:24 采纳率: 0%
浏览 11
已结题

Matlab求解微分方程,求大家帮忙纠错

求解微分方程-Uxx-Uyy+Ux+20yUy+U=f,我已经写出了代码,但误差太大,始终检查不出错误。
思路是:fish2d是用来求解-Uxx-Uyy=f类型的快速泊松方程求解器,因此方程化为-Uxx-Uyy=f-Ux-20yUy-U。用初值u0=0代入右端来迭代,每次求解时调用fish2d函数,真解已知。

以下为代码(其实是matlab):

  1. 主函数
clc,clear,close all
a=0;
b=1;
c=0;
d=1;
N1=31;
N2=31;
h1=(b-a)/N1;
h2=(d-c)/N2;
x=a+[1:N1-1]*h1;
y=c+[1:N2-1]*h2;
[X,Y]=meshgrid(x,y);

%准备矩阵
e1=ones(N1-1,1);
e2=ones(N2-1,1);
e3=ones((N1-1)*(N2-1),1);
I1=spdiags(e1,0,N1-1,N1-1);
I2=spdiags(e2,0,N2-1,N2-1);
I=spdiags(e3,0,(N1-1)*(N2-1),(N1-1)*(N2-1));
K3=spdiags([-e1,e1],[-1,1],N1-1,N1-1);
K4=spdiags([-e2,e2],[-1,1],N2-1,N2-1);

%A、B、C、D用以生成系数矩阵
C=kron(K3,I2);
C=C/(2*h1);     %u_x系数矩阵
D=kron(I1,K4);
D=D/(2*h2);     %u_y系数矩阵
for i=1:N2-1
    k=i;
    while k<=(N1-1)*(N2-1)
        D(:,k)=D(:,k)*20*y(i);  %a2(x,y)=20y。将矩阵每一列*20*所在列数
        k=k+(N2-1);
    end
end

%右端项f,代入真解解出
f=zeros(N1-1,N2-1);
for i=1:N1-1
    for j=1:N2-1
        f(i,j)=20*y(j)*(10*x(i)*y(j)*exp(x(i)^(9/2))*(x(i)- 1) + 10*x(i)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1)) - 20*x(i)*exp(x(i)^(9/2))*(x(i)- 1)...
               - 20*y(j)*exp(x(i)^(9/2))*(y(j) - 1) + 10*x(i)*y(j)*exp(x(i)^(9/2))*(y(j)- 1) + 10*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j)- 1)...
               - 90*x(i)^(9/2)*y(j)*exp(x(i)^(9/2))*(y(j) - 1) + 10*x(i)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1) - (405*x(i)^8*y(j)*exp(x(i)^(9/2))...
               *(x(i)-1)*(y(j)-1))/2-(495*x(i)^(7/2)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j)-1))/2+ 45*x(i)^(9/2)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1);
    end
end
f=reshape(f',(N1-1)*(N2-1),1);%reshape按列取值

% 求解
u0=zeros((N1-1)*(N2-1),1);
k=1;
while k<=2
    u1=fish2d(f-(C+D+I)*u0);
    u0=u1;
    k=k+1;
end
%画图
u1=reshape(u1,N2-1,N1-1);
mesh(X,Y,u1);
title('数值解');
figure
u_true=10*X.*Y.*(1-X).*(1-Y).*exp(X.^4.5);
mesh(X,Y,u_true);
title('真解');
figure
mesh(X,Y,u_true-u1);
title('误差');

2.fish2d函数

function u = fish2d(f)
% Poisson solver in 2D based on matlab fft
% square geometry, homogeneous Dirichlet boundary conditions
% requires uniform mesh (2^k-1)^2 interior nodes 
%
% C. T. Kelley, January 6, 1994
%
% This code comes with no guarantee or warranty of any kind.
%
% Solves - u_xx - u_yy = f
%
% Requires sintv.m and isintv.m
%
% function u = fish2d(f)
%
%
global fish_lal fish_ual ua;
n=length(f);
m=sqrt(n);
hh=.5/(m+1);
h2=(m+1)*(m+1);
e=ones(m,1);
%
% Don't compute eigenvalues, factor tridiagonal matrices
% or allocate space for the 2-D representation of the solution
% more than once. Note the use of global variables to store
% fish_ual, fish_lal, and ua.
%
if exist('fish_ual')==1
    [f1, f2]=size(fish_ual);
    m1=sqrt(f1);
else
    m1=m;
end
if (exist('fish_ual') == 0) | (m1 ~= m)
%
% allocate room for ua, the 2D representation of the solution
%
    ua=zeros(m,m);
%
% set up diagonal of system using eigenvalues of 1D operator
%
    x=1:m; x=pi*hh*x'; lam=sin(x); lam=h2*(2*ones(m,1) + 4*lam.*lam);
    en=h2*ones(n,1); fn=en; gn=en; dx=zeros(n,1);
    for i=1:m
        fn(i*m)=0;
        gn((i-1)*m+1)=0;
        dx((i-1)*m+1:i*m)=lam(i)*ones(m,1);
    end
    al=spdiags([-fn, dx, -gn], [-1,0,1], n,n);
%
% factor the tridiagonal matrix for solution in the x direction
%
    [fish_lal,fish_ual]=lu(al);
end
%
% Map f into a rectangular array.
% Take sine transform in y direction.
%
ua(:)=f;
ua=sintv(ua).';
%
% Solve in the x direction
%
ua(:)=fish_ual\(fish_lal\ua(:));
%
% Take inverse transform.
%
ua=isintv((ua.'));
%
% Map uz into a linear array.
%
u=ua(:);

function u=sintv(z)
% sine transform, assume that size(z)=[nx,ny]=[2^k-1,ny]
%
% C. T. Kelley, May 1994
%
% This code comes with no guarantee or warranty of any kind.
%
[nx,ny]=size(z);
ww=-4*fft([zeros(ny,1), z']',2*nx+2);
u=imag(ww(2:nx+1,:));

function u=isintv(z)
% inverse sine transform, assume that size(z)=[nx,ny]=[2^k-1,ny]
% 
% C. T. Kelley, May 1994
%
% This code comes with no guarantee or warranty of any kind.
%
[nx,ny]=size(z);
ww=ifft([zeros(ny,1), z']',2*nx+2);
u=imag(ww(2:nx+1,:));
  • 写回答

16条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-25 12:24
    关注
    获得0.60元问题酬金

    引自免费微信小程序:皆我百晓生

    在MATLAB中处理病态矩阵的求逆问题,通常可以采用正规方程法(Normal Equation)或者迭代方法(例如:高斯-塞德尔迭代、共轭梯度法等)。但是,对于特定的数学模型,比如你在做鱼类资源评估中的Fisheries 2D (FISH2D)模型分析时,可能需要用到更专业的预优化技术。

    FISH2D是一个用于模拟二维鱼类种群动态的工具,它主要用于渔业管理决策支持。由于其专业性,相关的预优化处理可能会涉及到模型参数调整或者选择合适的数值稳定算法。然而,在MATLAB中直接调用FISH2D的文档和教程确实相对较少,因为这通常是渔业科学领域的研究人员使用的软件。但我们可以探讨一下一般性的预优化策略和应对病态矩阵的方法。

    首先,确保你已经正确安装了FISH2D,并且你的MATLAB环境已经配置好了与之交互的路径。如果你没有安装FISH2D,你需要从官方网站下载并安装。然后按照官方文档的指示设置MATLAB环境变量,使得MATLAB能找到FISH2D的库文件。

    对于病态矩阵,一个常见的做法是使用Tikhonov正则化,这是一种通过添加一个小的常数到对角线项来改善矩阵条件数的方法。下面是一个使用Tikhonov正则化的例子:

    function [invM] = regularizedInverse(M, epsilon)
        % M: 病态矩阵
        % epsilon: 正则化参数
    
        % 计算M的迹(所有对角元素之和)
        trace_M = trace(M);
    
        % 添加正则化项到对角线上
        M_reg = M + epsilon * eye(size(M)) .* trace_M;
    
        % 计算正则化后的矩阵的逆
        invM = inv(M_reg);
    end
    
    % 使用示例:
    A = gallery('prolate',3); % 创建一个病态矩阵
    epsilon = 1e-6; % 设置正则化参数
    inv_A = regularizedInverse(A, epsilon);
    

    在这个例子中,我们创建了一个病态矩阵A,然后使用Tikhonov正则化对其进行处理。epsilon是正则化参数,可以根据实际情况调整。然后我们计算正则化后矩阵的逆,存储在inv_A中。

    至于如何将这个技巧应用到FISH2D模型中,你可能需要在模型的某个关键步骤处调用上述函数。具体在哪里调用取决于模型的具体结构和你的研究目标。建议你在阅读FISH2D的源码或参考文献的基础上,尝试将这个正则化技巧融入你的模型分析流程。

    如果你有具体的模型代码片段或遇到具体的问题,提供更多的上下文信息,我可以给你更详细的指导。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月2日
  • 修改了问题 5月29日
  • 修改了问题 5月29日
  • 修改了问题 5月25日
  • 展开全部

悬赏问题

  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
  • ¥15 请各位帮我看看是哪里出了问题
  • ¥15 vs2019的js智能提示
  • ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了
  • ¥15 uniapp的h5项目写一个抽奖动画