查看: 6004|回复: 4|关注: 0

[已解决] 已知函数值,想反过去求自变量,但函数本身却不是显式

[复制链接]

新手

24 麦片

财富积分


050


34

主题

162

帖子

1

最佳答案
  • 关注者: 2
本帖最后由 larlyii 于 2016-2-21 16:56 编辑

吴老师您好!

有一个函数,如下图

函数表达式

函数表达式


如果给定函数值y=0.5,想反过去求自变量,代码如下:
  1. syms x Sigma
  2. f = 1/(sqrt(2*pi)*Sigma) * exp(-(x-1)^2/(2*Sigma^2)) * log2(1 + exp(-2*x/Sigma^2));
  3. y = int(f, x, -100, 100); % 这里积分限变为[-100,100]只是因为从-inf到inf积分的话会出现NaN,这个函数本身在正负100外已经很小了,忽略不计

  4. z = 0.5 - y;
  5. SigmaSym = solve(z);
  6. SigmaNum = eval(SigmaSym);
复制代码


但运行如下的代码时出现warning:不能得到显示的符号表达式,只能返回一个近似数值
Warning: Cannot solve symbolically. Returning a numeric approximation instead.

但得到的解SigmaSym = -2.6501037966944329815445620214977e212463804,居然是10的2亿多次方,再经过eval之后得到的SigmaNum=-Inf,明显不对。
注:这是在R2015a中运行的结果,如果在一些低版本中运行上面的代码,可能还会直接报error。

既然solve函数不行,那么fzero函数也不行。0.5肯定在函数在值域内,因为该函数的值域在[0,1],并且我已经知道当Sigma为0.9787时,y=0.5,验证如下:
  1. g = subs(f, Sigma, 0.9787);
  2. gHandle = str2func(['@(x) ', char(vectorize(g))]);
  3. f2 = integral(gHandle, -100, 100); % 低版本MATLAB用quad函数,<span style="line-height: 1.5;">这里积分限变为[-100,100]只是因为从-inf到inf积分的话会出现NaN,这个函数本身在正负100外已经很小了,忽略不计
复制代码
运行可得f2 = 0.5,所以可知一定存在一个Sigma,使得函数值y为0.5

后来想到用数值积分integral(低版本MATLAB用quad函数替代符号积分int,但integral函数只能根据自变量Sigma求y,不能反过来根据y求Sigma。

后来搜到你发的一篇帖子,也和上述问题不同。
https://www.ilovematlab.cn/forum.php?mod=viewthread&tid=74289

能想到的比较暴力的方法就是把自变量Sigma定义在一定范围内,比如1:0.01:2,求得对应的y,再反过来查找表。等差数列的公差越小,查找表越精确。但这显然不是我想要的方法

请问有没有什么解决方法呢?







回复主题 已获打赏: 0 积分

举报

书籍作者

364 麦片

财富积分



12

主题

974

帖子

75

最佳答案
  • 关注者: 65
发表于 2016-2-29 17:20:18 | 显示全部楼层 |此回复为最佳答案
最近比较忙,现在才看到,抱歉。可以用integral+fzero这么做:
  1. f = @(Sigma)integral(@(x)1/(sqrt(2*pi)*Sigma) * exp(-(x-1).^2/(2*Sigma^2)) .* log2(1 + exp(-2*x/Sigma^2)),-100,100);
  2. >> sig = fzero(@(sigma)f(sigma)-0.5,1)
  3. sig =
  4.    0.978694124615701
  5. >> f(sig)
  6. ans =
  7.    0.500000000000000
复制代码
回复此楼 已获打赏: 0 积分

举报

新手

24 麦片

财富积分


050


34

主题

162

帖子

1

最佳答案
  • 关注者: 2
 楼主| 发表于 2016-3-1 05:53:04 | 显示全部楼层
吴鹏 发表于 2016-2-29 17:20
最近比较忙,现在才看到,抱歉。可以用integral+fzero这么做:

原来integral函数可以对含有待定系数的表达式求积分呀(比如问题中对x求积分,Sigma是待定系数),积分之后就是Sigma的函数了。问题的关键在于MATLAB的help(对应于在command window中输入doc inregral)中并没有说明integral函数可以这样调用,在函数本身的m文件中的注释信息(对应在command window输入help integral)也没有说明可以这样调用,所以看完help后我默认integral函数不能这样调用,所以才发这个帖子来请教你。之前也遇到过另一种情况:某个函数的m文件中的注释和help窗口中的信息不同,导致自己在调用的时候也没能完全灵活使用。不知这些情况算不算MathWorks公司在维护help文档时的小小bug呀
回复此楼 已获打赏: 0 积分

举报

书籍作者

364 麦片

财富积分



12

主题

974

帖子

75

最佳答案
  • 关注者: 65
发表于 2016-3-3 11:50:54 | 显示全部楼层
larlyii 发表于 2016-3-1 05:53
原来integral函数可以对含有待定系数的表达式求积分呀(比如问题中对x求积分,Sigma是待定系数),积分之 ...

其实这更应该算是匿名函数的使用技巧,匿名函数的用法很灵活和强大,楼主可以多体会体会。
回复此楼 已获打赏: 0 积分

举报

新手

24 麦片

财富积分


050


34

主题

162

帖子

1

最佳答案
  • 关注者: 2
 楼主| 发表于 2016-3-3 19:06:37 | 显示全部楼层
吴鹏 发表于 2016-3-3 11:50
其实这更应该算是匿名函数的使用技巧,匿名函数的用法很灵活和强大,楼主可以多体会体会。 ...

谢谢吴老师哈!这个问题纠结了很久,总算解决了。万分感激!!!
回复此楼 已获打赏: 0 积分

举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

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