我试图用不同的方式解决这个等式,但没有运气:
找到两个函数的点数。
f(x) = sin(x)
y = a
在给定的a。在这种情况下,我们可以说a = 0.15
sin(x) = ax
= 0.15x
x = sin(x)/0.15
???
任何人都可以帮助解决这个问题吗?
这就是确切的问题:
编写一个读取值a的C程序,并写出等式sin(x) = a*x
注意:此等式肯定有一个解决方案:x = 0
。然而,对于a
的低值,表示等式y = a*x
的线足够接近水平线以多次穿过正弦波。您的程序应计算并打印根数及其值。
提示:假设您要求解等式f(x) = 0
,其中f(x)
是连续函数。进一步假设您可以找到两个值xlow
和xhigh
,以便f(xlow) < 0
和f(xhigh) > 0
和函数f(x)
仅在这些值之间穿过x轴一次值。您可以继续使用所谓的“二进制搜索”技术,如下所示:
- 将解x估计为x =(xlow + xhigh)/ 2.0
- 如果| f(x)| &LT; epsilon然后打印x作为解决方案并退出;其他
- 如果f(x)< 0然后替换xlow = x else替换xhigh = x
- 转到(1)
醇>
使用epsilon = 0.001
答案 0 :(得分:1)
您可以继续使用所谓的“二元搜索”技术
这是解决方案的关键。实际上它是的解决方案。让我画两个函数:
f(x) g(x)
/ --
/ --
/ --
/ --
/--
-*
--/
-- /
-- /
^ ^
| |
xlow xhigh
您有xlow
和xhigh
作为f(x)
越过g(x)
的估算值。在您的问题中,f(x) = ax
和g(x) = sin(x)
。
首先,让我们看看为什么xlow
和xhigh
做出了很好的估计。如果您注意到,我们xlow
已f(x) < g(x)
,xhigh
f(x) > g(x)
我们f(x) == g(x)
。由于函数是连续的,因此在xlow
之间的某处有一点。
现在让我们看一下xhigh
和 f(x) g(x)
/ --
/ --
/ --
/ --
/--
-*
--/
-- /
-- /
^ ^ ^
| | |
xlow xmid xhigh
之间的中间点:
xmid
现在在f(x) > g(x)
,我们有f(xhigh) > g(xhigh)
f(xmid) > g(xmid)
f(xlow) < g(xlow)
(在此示例中)。所以:
xmid
从xlow
到f(x) - g(x)
之间,函数变更大 - 船(换句话说,xlow
更改其符号),然后答案肯定在{{1}之间}和xmid
(请注意xmid
和xhigh
之间仍然可能存在偶数个解,但我们现在还不能说明。)
因此,如果我们分配xhigh = xmid
,我们会:
f(x) g(x)
/--
-*
--/
-- /
-- /
^ ^
| |
xlow xhigh
但这和以前一样!除了我们将解决方案的可能位置缩小一半。重复我们:
f(x) g(x)
/--
-*
--/
-- /
-- /
^ ^ ^
| | |
xlow xmid xhigh
f(xhigh) < g(xhigh)
f(xmid) > g(xmid)
f(xlow) > g(xlow)
这一次,f(x) - g(x)
和xmid
之间的xhigh
变化,我们会xlow = xmid
切掉我们不是感兴趣的。我们得到:
f(x) g(x)
/--
-*
--/
^ ^
| |
xlow xhigh
同样,同样的问题,除了我们缩小了解决方案可能减半的范围。
在while循环中重复这一点,|f(xmid) - g(xmid)|
几乎为零(比如小于0.000001(或1e-6)(也要注意绝对值))。在这种情况下,我们停止搜索,我们说那个特定的xmid
就是答案。 (参见here我们为什么不检查是否平等,但是接近)。
还有一个问题。根据您的特定功能,可能会有许多横截面。我们如何找到xlow
和xhigh
?好吧,我们希望范围[xlow, xhigh]
只包含一个解决方案。因此,我们可以逐步找到这些范围并找到它们之间的横截面。
假设a > 0
(和x > 0
的解决方案),这就是图表的样子:
----- f(x) = ax
_ _ __*__ _ g(x) = sin(x)
/ \ /_*___----- / \ /
/ *____---*- \ / \ /
|---- | | | | | |
| | | | | |
\ / \ / \ /
\_/ \_/ \_/
让我们看看解决方案的位置。当然,它不在sin(x) < 0
的位置。然后在[2kπ, 2kπ + π/2]
和[2kπ + π/2, 2kπ + π]
上,可以分别成为一个解决方案。初始[0, π / 2]
可能有也可能没有解决方案,具体取决于a
。因此,最安全的方法是枚举所有此类范围,为f(x) - g(x)
和xlow
计算xhigh
并查看其符号。如果标志没有改变,则没有解决方案,我们可以继续前进。如果确实发生了变化,我们会执行上面的二进制搜索。
算法什么时候结束?我们知道g(x) = sin(x) <= 1
我们知道a > 0
,f(x) = ax
总是在增加。所以当你有f(xlow) > 1
时,肯定没有更多的解决方案。
算法将是:
Main Algorithm:
for k = 0,1,...
xlow = 2kπ
xhigh = 2kπ + π/2
binary_search(xlow, xhigh)
xlow = 2kπ + π/2
xhigh = 2kπ + π
binary_search(xlow, xhigh)
binary_search:
if axlow-sin(xlow) and axhigh-sin(xhigh) have the same sign
return no result in this range
do
xmid = (xhigh + xlow) / 2
diff = axmid - sin(axmid)
if diff and axlow-sin(xlow) have the same sign
xlow = xmid
else
xhigh = xmid
while abs(diff) > epsilon
return xmid
对于a < 0
的情况,解决方案类似(范围更改为sin
周期的另一半)。顺便说一句,对于您在上面找到的每个x
,-x
也是一个解决方案!
答案 1 :(得分:0)
显然,只有
的解决方案-1 <= ax <= 1
差函数h(x)= sin(x)-ax的单调性在导数h'(x)= cos(x)-a的根之间的所有区间上是相同的,并且它们也是此函数的局部最大值和最小值。所以使用点
arccos(a), 2*pi-arccos(a), 2*pi+arccos(a), 4*pi-arccos(a), 4*pi+arccos(a), ...
只要它们小于1 / abs(a)来定义搜索间隔。根据Shahbaz的答案,二分法,或者更好的伊利诺斯式的falsi法的变体,在每一个里面使用。
答案 2 :(得分:-1)
没有任何优化的粗暴方法(因此是一种天真的方法)将在x上运行for循环,x从0运行到2 * PI,PI = 22.0 / 7.0,并且如果得到abs,则循环增量为0.001 (sin(x) - a * x)&lt; epsilon,epsilon所说的等于某些kow值,如0.001(取决于你的粒度),你得到它!这将解决你的等式sin(x)= a * x