查看: 1651|回复: 10|关注: 0

[已解决] 不能转化为显式的函数 多个函数值 求 自变量

[复制链接]

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
eq.gif
现在有很多b值,需要求解对应的a值,我利用了下面的代码,可以求出结果,但效率有点低(大约需要30s),请问大家,这个有优化的方法吗?
先定义一个函数

  1. function y=kine2222(b)
  2. syms a;
  3. y1=solve(b-(a+(1-a)*log(1-a)),a);
  4. y=eval(y1);

复制代码


再使用arrayfun

  1. b=[1:1:100];
  2. arrayfun(@(b)kine2222(b),b)
复制代码

论坛优秀回答者

权威

9166 麦片

财富积分



11

主题

1万

帖子

1995

最佳答案
  • 关注者: 546
发表于 2019-2-6 23:30:17 | 显示全部楼层
  1. f=@(a,b)  a*(a-1)*log(1-a)-b;
  2. arrayfun(@(b) fsolve(@(a) f(a,b),-1,optimset('display','off')),1:100)
复制代码

论坛优秀回答者

权威

3873 麦片

财富积分



3

主题

4086

帖子

862

最佳答案
  • 关注者: 183
发表于 2019-2-7 00:06:49 | 显示全部楼层 |此回复为最佳答案
fun=@(x)  x+(1-x).*log(1-x);
x1=-40:0.001:0;
y1=fun(x1);
x=spline(y1,x1,1:100)

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
 楼主| 发表于 2019-2-7 09:32:05 | 显示全部楼层

谢谢回复,好厉害,运算时间降低到了0.446943 秒,效率提高了67倍!
虽然有点小错误~~~~  改为

  1. f=@(a,b) a+(1-a)*log(1-a)-b;
  2. arrayfun(@(b) fsolve(@(a) f(a,b),-1,optimset('display','off')),1:100)
复制代码

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
 楼主| 发表于 2019-2-7 09:37:03 | 显示全部楼层
maple1314168 发表于 2019-2-7 00:06
fun=@(x)  x+(1-x).*log(1-x);
x1=-40:0.001:0;
y1=fun(x1);

哇,好厉害!!膜拜大神!!这个运行时间仅用了0.072099 秒,虽然暂时还没看懂。
奇怪的是,直接copy的加号显示是红字,需要修改后运行!!!

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
 楼主| 发表于 2019-2-7 09:47:54 | 显示全部楼层
大概查了一下,
fun=@(x)  x+(1-x).*log(1-x);   %用匿名函数,建立fun和x的函数关系
x1=-40:0.001:0;   %给定预先估计的x的解的范围
y1=fun(x1);         
x=spline(y1,x1,1:100)  
%spline是插值用,用法是spline(y1,x1,yspan),先根据上面的x1的精确范围,计算对应的y1值,获得了x1~y1的曲线,再用插值法获得yspan范围y的值对应的x的值
感觉这个方法很妙~

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
 楼主| 发表于 2019-2-7 09:55:45 | 显示全部楼层
https://www.ilovematlab.cn/thread-265783-1-1.html
又看了几个帖子认识到:
fsolve 是数值求解,solve是符号求解。数值求解应该就是最小化目标吧,符号求解就是变形方程吧。
solve一般解线性方程,而fsolve一般解非线性方程。这里的非线性方程多半都是复杂的方程吧。
看来对于复杂的求解,数值求解效率要高很多,解法也更灵活。

论坛优秀回答者

权威

3873 麦片

财富积分



3

主题

4086

帖子

862

最佳答案
  • 关注者: 183
发表于 2019-2-7 09:56:15 | 显示全部楼层
romanticjune 发表于 2019-2-7 09:47
大概查了一下,
fun=@(x)  x+(1-x).*log(1-x);   %用匿名函数,建立fun和x的函数关系
x1=-40:0.001:0;   % ...

对啊。上面的+错误,可能是中文格式。
matlab的fzero中也有这方法,反插值。
对一元方程比较有效。

新手

14 麦片

财富积分


050


11

主题

37

帖子

0

最佳答案
 楼主| 发表于 2019-2-7 12:00:20 | 显示全部楼层
maple1314168 发表于 2019-2-7 09:56
对啊。上面的+错误,可能是中文格式。
matlab的fzero中也有这方法,反插值。
对一元方程比较有效。 ...

又遇到了一个小问题,当解-log(1-x)方程时,y较大接近x=1,如
y=[ 1.5514*10^7    1.7222*10^7    1.9091*10^7    2.1133*10^7   2.3362*10^7    2.5791*10^7]
fun=@(x) -log(1-x)
x1=0:0.001:0.999999;
y1=fun(x1);
x=spline(y1,x1,y)
计算结果是:
1.3333*10^18    1.8235*10^18    2.4839*10^18    3.3692*10^18    4.5517*10^18    6.1242*10^18
但这是不正确的,正确结果均为1。
请问对于这种接近极限的情况,是不是用这个方法就不好用了?

论坛优秀回答者

权威

9166 麦片

财富积分



11

主题

1万

帖子

1995

最佳答案
  • 关注者: 546
发表于 2019-2-10 12:16:34 | 显示全部楼层
romanticjune 发表于 2019-2-7 12:00
又遇到了一个小问题,当解-log(1-x)方程时,y较大接近x=1,如
y=[ 1.5514*10^7    1.7222*10^7    1.909 ...

换换思路
  1. syms x
  2. f(x)=-log(1-x)
  3. y=[ 1.5514*10^7    1.7222*10^7    1.9091*10^7    2.1133*10^7   2.3362*10^7    2.5791*10^7]
  4. arrayfun(@(k) vpa(solve(y(k)==f(x))),1:numel(y))
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /3 下一条

快速回复 返回顶部 返回列表