Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 计算4^x模2和x3C0;对于大x_Matlab_Math_Trigonometry_Modulo_Largenumber - Fatal编程技术网

Matlab 计算4^x模2和x3C0;对于大x

Matlab 计算4^x模2和x3C0;对于大x,matlab,math,trigonometry,modulo,largenumber,Matlab,Math,Trigonometry,Modulo,Largenumber,我需要在Matlab中用x>1000计算sin(4^x),基本上是sin(4^x mod 2π),因为sin函数中的值变得非常大,Matlab返回无限的4^1000。我如何有效地计算这个? 我更喜欢避免使用大型数据类型 我认为转换成sin(n*π+z)可能是一个可能的解决方案。我首先将问题重新定义如下:计算4^1000模2pi。所以我们把问题一分为二 使用一些数学技巧: (a+2pi*K)*(b+2pi)=ab+2pi*(垃圾) 因此,您可以将其自身乘以4多次,并在每个阶段计算mod 2pi。当

我需要在Matlab中用x>1000计算sin(4^x),基本上是
sin(4^x mod 2π)
,因为sin函数中的值变得非常大,Matlab返回无限的
4^1000
。我如何有效地计算这个? 我更喜欢避免使用大型数据类型


我认为转换成sin(n*π+z)可能是一个可能的解决方案。

我首先将问题重新定义如下:计算4^1000模2pi。所以我们把问题一分为二

使用一些数学技巧:

(a+2pi*K)*(b+2pi)=ab+2pi*(垃圾)


因此,您可以将其自身乘以4多次,并在每个阶段计算mod 2pi。当然,真正要问的问题是这件事的精确性。这需要仔细的数学分析。它可能完全是废话,也可能不是废话。

根据帕维尔关于mod的提示,我在mathwors.com上找到了一个用于高功率的mod函数。 无法计算4^4000模2π。因为它只处理整数作为模,而不处理小数


这句话不再正确了:
sin(4^x)
sin(bidmod(4,x,2*pi))
你需要小心,因为会丢失精度。正弦函数是周期性的,但4^1000是一个大数字。因此,我们有效地减去2*pi的倍数,将参数移动到区间[0,2*pi]

4^1000大约是1e600,这是一个非常大的数字。因此我将使用我的计算工具进行计算。(事实上,当我编写HPF时,我明确的目标之一是能够计算像sin(1e400)这样的数字。即使你是为了好玩而做一些事情,正确地做仍然是有意义的。)在这种情况下,既然我知道我们感兴趣的幂大约是1e600,那么我将以超过600位的精度进行计算,预计减法对消会损失600位。这是一个巨大的减法对消问题。想想看。模运算实际上是两个nu之间的差异前600位左右的相同成员数

X = hpf(4,1000);
X^1000
ans =
114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029376
不超过这个数字的2*pi的最近倍数是多少?我们可以通过简单的运算得到

twopi = 2*hpf('pi',1000);
twopi*floor(X^1000/twopi)
ans = 114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029372.6669043995793459614134256945369645075601351114240611660953769955068077703667306957296141306508448454625087552917109594896080531977700026110164492454168360842816021326434091264082935824243423723923797225539436621445702083718252029147608535630355342037150034246754736376698525786226858661984354538762888998045417518871508690623462425811535266975472894356742618714099283198893793280003764002738670747
如你所见,前600位数字是一样的。现在,当我们减去这两个数字

X^1000 - twopi*floor(X^1000/twopi)
ans =
3.333095600420654038586574305463035492439864888575938833904623004493192229633269304270385869349155154537491244708289040510391946802229997388983550754583163915718397867356590873591706417575657627607620277446056337855429791628174797085239146436964465796284996575324526362330147421377314133801564546123711100195458248112849130937653757418846473302452710564325738128590071680110620671999623599726132925263826
这就是为什么我把它称为一个巨大的减法消除问题。这两个数字在许多数字上是相同的。即使有1000位的准确度,我们也丢失了许多数字。当你减去这两个数字时,即使我们有1000位的结果,现在只有最高阶的400位有意义

HPF当然能够计算trig函数。但正如我们上面所示,我们应该只相信结果的大约前400位数字。(在某些问题上,sin函数的局部形状可能会导致我们丢失更多的数字。)

那么,我是对的,我们不能相信所有这些数字吗?我会做同样的计算,每1000位精度计算一次,然后第二次计算2000位。计算绝对差,然后取log10。2000位结果将是我们的参考,与1000位结果相比,基本上是精确的

double(log10(abs(sin(hpf(4,[1000 0])^1000) - sin(hpf(4,[2000 0])^1000))))
ans =
      -397.45
啊。所以,在我们开始计算的1000位精度中,我们损失了602位。结果中的最后602位不是零,但仍然是垃圾。这正如我所预料的。只是因为你的计算机报告了高精度,你需要知道什么时候不信任它

我们可以不借助高精度工具进行计算吗?请小心。例如,假设我们使用powermod类型的计算?因此,计算所需的功率,同时在每一步取模。因此,以双精度完成:

X = 1;
for i = 1:1000
  X = mod(X*4,2*pi);
end
sin(X)
ans =
         0.955296299215251
啊,但请记住,真正的答案是-0.19033458127208318385994396068455455709388

所以基本上没有什么重要的东西了。我们在计算中丢失了所有的信息。正如我所说的,小心是很重要的

在循环中的每一步之后,我们在模计算中都会有一点损失。但是我们将答案乘以4,这导致误差增加了4倍,然后又增加了4倍,以此类推。当然,在每一步之后,结果在数字的末尾会有一点损失。最终的结果是完全的crapola

让我们看看小功率的操作,只是为了让我们自己相信发生了什么。例如,这里,尝试20次功率。使用双精度

mod(4^20,2*pi)
ans =
          3.55938555711037
现在,在powermod计算中使用一个循环,在每一步后取mod。本质上,这会在每一步后丢弃2*pi的倍数

X = 1;
for i = 1:20
  X = mod(X*4,2*pi);
end
X
X =
          3.55938555711037
但这是正确的值吗?同样,我将使用hpf计算正确的值,显示该数字的前20位。(因为我总共用50位数字进行了计算,所以我绝对相信前20位。)

事实上,虽然双精度的结果与显示的最后一个数字一致,但在第五个有效数字之后,这些双精度结果实际上都是错误的。事实证明,我们仍然需要携带600多个精度数字才能生成任何有意义的结果

最后,为了彻底消灭这匹死马,我们可能会问,是否可以进行更好的powermod计算。也就是说,我们知道1000可以分解为二进制形式(使用dec2bin),如下所示:

我们能用一个重复的平方方案用更少的乘法来扩展大的幂,从而导致更少的累积误差吗?本质上,我们可以尝试计算

4^1000 = 4^8 * 4^32 * 4^64 * 4^128 * 4^256 * 4^512
但是,通过重复平方4,然后在每次运算后取mod来实现这一点。但是,这失败了,因为模运算只会删除2*pi的整数倍。毕竟,mod实际上是用于处理整数的。因此,看看会发生什么。我们可以将4^2表示为:

4^2 = 16 = 3.43362938564083 + 2*(2*pi)
我们能把余数平方,然后再取一次模吗?不行

mod(3.43362938564083^2,2*pi)
ans =
          5.50662545075664

mod(4^4,2*pi)
ans =
          4.67258771281655
我们可以理解当我们展开f时发生了什么
4^1000 = 4^8 * 4^32 * 4^64 * 4^128 * 4^256 * 4^512
4^2 = 16 = 3.43362938564083 + 2*(2*pi)
mod(3.43362938564083^2,2*pi)
ans =
          5.50662545075664

mod(4^4,2*pi)
ans =
          4.67258771281655
4^4 = (4^2)^2 = (3.43362938564083 + 2*(2*pi))^2