sigma665 发表于 2008-8-20 16:36:27

再问个关于求导方面的

x=2+a*t

y=x^2

要求y对x的导数,用数值方法求
对于一般的a,很容易

但是,当a=0时,x对t导数是0

y_diff_x=y_diff_t / x_diff_t
分母为0,结果无穷大了
如下:

t=-1:0.1:1;a=eps;
x=2+a*t;
y=x.^2;
y_diff_t=diff(y);
y_diff_x=y_diff_t /a;

正确的结果应该是4

这该怎么处理

ljelly 发表于 2008-8-20 16:41:24

回复 1# sigma665 的帖子

分开处理就可以了,当a=0,时单写一个判断的表达式
其余情况按你现在的编写就可以了

ljelly 发表于 2008-8-20 16:55:34

回复 3# waynebuaa 的帖子

你的求导,是要先对t求导,然后再求dy/dx
即dy/dt*dt/dx,再达到dy/dx的目的
中间出现了过零处理,也就是不连续了,当然要分开写

sigma665 发表于 2008-8-20 17:58:43

谢谢楼上所有

这里只是举了一个简单的例子
用手算的话,最后,分母的a约掉了
符号运算,也是如此

但是,由于表达式太复杂
符号运算效率太低,得到的表达式更是复杂

所以想通过数值方面的处理,得到希望的结果

sigma665 发表于 2008-8-22 13:42:45

知道了

由于y和x关系不变,所以无论a怎么变都对y-x关系无影响

所以选择一个a值
得到y和x对应关系
然后再用多项式拟合之,并对x求导
最后将x值代入即可



原始问题,表达式复杂,无法直接对x求导

messenger 发表于 2008-8-22 14:13:08

回复 5# sigma665 的帖子

忍不住说一句

不知道你倒底要干什么:L

sigma665 发表于 2008-8-23 17:10:24

回复 6# messenger 的帖子

我是想用数值的方法,避免出现1楼求导分母为0的情况

clear all;
clc
t=0:.1:1;
for i=1:length(t)
    y=3+t(i);
    x=2+t;
    z=x.^2+y.*x+log(x.*y)-1./x;
    sp=csapi(x,z);
    %fnplt(sp); hold on;
    dsp=fnder(sp,1);%微分
    zz(i,:)=fnval(dsp,x);
end
zz=diag(zz);如上:
每对应一个y值,有一个z
样条拟合z-x,微分
然后再将x代入,得到zz

由于x,y是同步的,zz的对角线才是希望的x=某值的原始表达式的微分值

不知道我的这个思路对不对
根据这个表达式,结果是对的

但是,我用另外一个复杂表达式,结果有出入
是否我举的这个例子是特例呢

[ 本帖最后由 sigma665 于 2008-8-23 17:11 编辑 ]

messenger 发表于 2008-8-23 20:46:21

回复 7# sigma665 的帖子

这个例子比以前那个例子好一些,以前的那个例子即不像复合函数求导,也不像简单函数求导。

不过,这个例子也有一些问题。下面两句

    y=3+t(i);
    x=2+t;

为什么y后面是t(i),而x后面是t?

这两个凑到一起,让人莫名其妙。

[ 本帖最后由 messenger 于 2008-8-23 20:59 编辑 ]

sigma665 发表于 2008-8-24 08:57:49

回复 8# messenger 的帖子

本来是双层循环
这样写可以提高下运算速度

将x y分开,就可以得到不同的y对应的一个导数值
然后取对角线值,这样,就相当于又把x y同步了

不这样做,最后得到的是一个数,而不是随t的变化
因为最后还要对t进行积分

不知道有没有说清楚,一会儿求导,一会儿积分的

messenger 发表于 2008-8-24 11:19:20

你又把我搞糊涂了,怎么会是双层循环?

你这么写,也不知道是不是正确表达了你的数学模型,

从你的matlab表达式在反推表达式的数学形式有点困难。

你能不能把你要求导的函数用数学表达式写出来?

如果写成数学表达式,你是的函数是不是?

然后,求?

原帖由 sigma665 于 2008-8-24 08:57 发表 http://forum.simwe.com/images/common/back.gif
本来是双层循环
这样写可以提高下运算速度

将x y分开,就可以得到不同的y对应的一个导数值
然后取对角线值,这样,就相当于又把x y同步了

不这样做,最后得到的是一个数,而不是随t的变化
因为最后还要对t进 ...

sigma665 发表于 2008-8-24 12:02:00

表达式就是那个

如图

对应每一个t,都有相应的x y值
双层循环,得到一个2维的z'值
而实际上,x y之间是同步的
所以有用的数据在对角线上


用x=2+t只是为了验证
因为这个可以用复合求导的方式解决,分母不为0

但是如果求表达式在x=2处的导数值,复合求导就不行了
所以用这种方法,先得到z-x的导数关系,然后将下代入

感谢你怎么耐心

[ 本帖最后由 sigma665 于 2008-8-24 12:10 编辑 ]

messenger 发表于 2008-8-24 14:48:46

回复 11# sigma665 的帖子

如果这样,那你这么求思路是对的。

只不过,你的结果可能受函数曲线形状的影响。

sigma665 发表于 2008-8-24 15:39:20

clear all;
clc
t=linspace(-1,1);
zz=zeros(length(t));
for ii=1:length(t)
y=3+t(ii);
x=2+t;
%z=x.^2+y.*(x.^2)+log(x+y)-1./x+sin(x.*y);
z(ii,:)=log(x+y);
sp=csapi(x,z(ii,:));
%fnplt(sp); hold on;
dsp=fnder(sp,1);%微分
%fnplt(dsp); hold on;
zz(ii,:)=fnval(dsp,x);

end
zz=diag(zz);%样条数值解
x=2+t;y=3+t;
%zzz=2*x+2*x.*y+1./(x+y)+1./x.^2+cos(x.*y).*y;
zzz=1./(x+y); %解析解


z=diag(z);
=diff_ctr(z',x(2)-x(1),1,x(1));%中心差分解
plot(x,zzz,'o',x,zz,dx,zx)

现在基本上我认为这种方法是对的
原先,我一直跟薛定宇书上的中心差分法做比较,有出入
现在发现,即使简单表达式,用中心差分法也有出入
所以,我怀疑是中心差分法的精度问题

附图:圆圈是解析解

messenger 发表于 2008-8-24 19:56:59

显然是你的复合函数求导错误。

当z=log(x+y)时,其对x的偏导显然为zzz=2./(x+y); %解析解,而不是zzz=1./(x+y);

当把zzz=2./(x+y);代入你的代码,其值与中心差分法的结果正好吻合。

sigma665 发表于 2008-8-25 08:43:21

>> syms x y
>> f=log(x+y)

f =

log(x+y)


>> diff(f,x)

ans =

1/(x+y)

对x求偏导没有错啊

我知道了,你是用复合求导得到的结果,
我是直接求的

复合求导,x y都是t的函数,相当于把x y联系起来了
我直接求导,x y之间没有关系

应该你是对的,x y本来就有关系,不能硬把他们拆开

[ 本帖最后由 sigma665 于 2008-8-25 10:33 编辑 ]

ck436ck436 发表于 2010-9-21 15:31:40

好像不对吧,这样子求导应该是乘法才对,不是除法吧?最终结果应该是零吧?
页: [1]
查看完整版本: 再问个关于求导方面的