关于matlab-finverse的踩坑记录

任务:有一个分段函数,求解其中一段的反函数,该段对应的公式已知

这段是单增的,原函数:
在这里插入图片描述
将原函数编辑入matlab,调用finverse求解:

syms a b r; %定义变量
a=0.25;
b=0.2;
maxv=1.+a;

g(r)=r-(a/(b-a)^2)*((b-sqrt(b^2+(a-b)*(r+b-1)))^2); %函数公式
fplot(g,[0.8,maxv]); %绘制
m = finverse(g, r) %求解反函数
fplot(m,[0.8,maxv]); %绘制

得到反函数公式:
在这里插入图片描述
反函数绘制:
在这里插入图片描述
就很奇怪啊,单增函数的反函数一定是单增的呀,应该是关于y=x对称的结果。
后来发现原函数在分段函数的这段范围里 虽然是单增的,但其实总体画出来并不是的:(matlab对于求解反函数结果并不唯一的已经不提示了)
在这里插入图片描述
所以matlab求解的其实是1.5-2.5的那部分,而不是我想要的前面单增的部分。
我试了设置自变量r的范围,让它只保留单增的部分:

assume(r < 1+a);
assumeAlso(r > 1-b);

但是没有用。

后来解决方法:

一、更改公式

我本身知道这是二次贝塞尔曲线,联想二次函数求解的两个结果,把公式改了一下,也就是图示这里改成了减号。在这里插入图片描述
ok,好运的解决了:
在这里插入图片描述
验证:

fg=compose(g,g_inverse);%测试再次带入后是否为线性
fplot(fg,[0.8,maxv]); 

反函数再代入原函数,结果是线性图,就表示正确了。

二、solve求解方程

不用finverse求反函数,直接用solve去求解函数,这样适用于逆向得到单值的情况:

syms r;
a=0.25;
b=0.2;
eqn = r-(a/(b-a)^2)*((b-sqrt(b^2+(a-b)*(r+b-1)))^2) == 0.8; %待求解方程式 结果为0.8时r为多少
S = solve(eqn,r)

如果原函数不是单调的,S求出来可能是多值。
如果for调用这个函数,应该也能绘出曲线。

三、反向绘制后拟合

把r代入原函数,求出两列数组:自变量和因变量。
然后交换,用matlab的拟合函数去拟合得到公式。
牺牲精度但应该可以解决复杂公式的问题。

四、查表法和正向逼近法

如果公式复杂,但是函数内变量单一,可以正向调用函数得到一系列结果,都保存下来。需要反向调用的时候去查表就可以了。
如果不考虑速度的话,还可以用正向逼近法,相当于对于每个f(r),依次尝试r直到足够接近:

syms r

a=0.25;
b=0.2;
g(r)=(r-(a/(b-a)^2)*((b-sqrt(b^2+(a-b)*(r+b-1)))^2));
Longitudinal = (1-b):0.00001:(1+a); 
lateral = zeros(1,size(Longitudinal ,2)); 
for i = 1:1:size(Longitudinal ,2)
    for temp=(1-b):0.001:(1+a)%一次次尝试
        if g(temp) - Longitudinal(i) < 10^-4 %接近目标值时保存
            lateral(i) = temp;
        end
    end  
end
fplot(g,[(1-b),(1+a)]);
plot(Longitudinal,lateral);

运行速度贼慢,还可以改成二分法逼近,更快一些。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值