MatLab的 - 可变精度算术(MatLab - variable precision arith

2019-10-16 19:15发布

我有一个关于在一个简短的问题vpa命令一个可以使用MATLAB来计算符号表达式。

我的课本说以下内容:

“你需要当您使用功能,如要小心sqrt的数字,在双精度浮点数默认的结果你需要这样的输入传给。 vpa为正确评价一个象征性的字符串: vpa('sqrt(5)/pi') “。

我不太了解这里的行话。 为什么对于大多数输入我得到确切同样的答案我是否型vpa(input)vpa('input')而不是平方根? 举例来说,如果I型vpa(sin(pi/4))vpa('sin(pi/4)')我得到完全相同的答案,但如果I型以上的给定问题vpa(sqrt(5)/pi)我没有得到同样的答案,当我键入vpa('sqrt(5)/pi')

如果有人能在一个比我的书上面做一点更详细的解释,我将不胜感激!

Answer 1:

我不是专家MatLab的,但不包括引号,你传递的结果 sqrt(5)/pivpa()

  vpa(sqrt(5)/pi)
= vpa(0.7117625434171772)

与报价,你传递表达 sqrt(5)/pi (未计算的和在确切形式)转换成vpa()然后告诉MATLAB来计算sqrt(5)/pi具有可变精度。



Answer 2:

从未假定若干像VPA(SIN(PI / 4))是精确至全精度,因为MATLAB通常计算呼叫使用浮点运算VPA内的数,所以只精确到大约16位。

然而,似乎是正确的在这里。 例如,我们知道,

sin(pi/4) == sqrt(2)/2

让我们测试的结果。 我将使用100位的精度,比较两个VPA和我自己的HPF工具。

>> vpa(sin(pi/4),100)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864

>> vpa(sqrt(sym(2))/2,100)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864

>> sqrt(hpf(2,100))/2
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864

>> sin(hpf('pi',100)/4)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864

所以,我的猜测是解析器已经认识到了输入的东西符号工具箱可以更准确地计算。 正如我之前说的,不过要小心。 什么是罪(PI / 12)?

>> vpa(sin(pi/12),100)
ans =
0.25881904510252073947640383266843855381011962890625

>> vpa('sin(pi/12)',100)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655

>> vpa(sin(sym('pi')/12),100)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655

>> sin(hpf('pi',100)/12)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655

看到,在第一种情况下,解析器没有拯救我们。 在别人,我被迫MATLAB计算正确的值。 事实上,比特的努力将给予我们罪(PI / 12)的值,如SQRT(2)*(SQRT(3) - 1)/ 4。

>> DefaultNumberOfDigits 100
>> (sqrt(hpf(3)) - 1)*sqrt(hpf(2))/4
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655

问题是,不信任的解析器来这里救你。

编辑:作为荷银的评论的考验,我谨指出,MATLAB是在这里做一些有趣的东西。 看到VPA能够返回正确的前100位圆周率,即使通过PI作为双精度数。 由于PI(double类型)是不是16十进制数字正确的过去,有事情有鬼。

>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

>> vpa('pi',100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

vpa('pi',100) - vpa(pi,100)
ans =
0.0

由于该事实的测试,让我们来看看什么HPF发现。 HPF实际接管IEEE 754值,为存储在双,然后将其转换为HPF数。

>> hpf(pi,100)
ans =
3.141592653589793115997963468544185161590576171875

>> hpf('pi',100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

>> hpf('pi',100) - hpf(pi,100)
ans =
0.0000000000000001224646799147353177226065932275001058209749445923078164062862089986280348253421170679821480800000000

所以很明显,MATLAB能够识别PI的东西不仅仅是它会通过在作为双精度值更。

EDIT2:

事实上,有点戏告诉我这里发生了什么。 VPA是很棘手的,不是解析器。 考虑分数7/13。 如果我们把它做成了一倍,然后打印出存储在其盛开的浮点值,我们看到它是不是真正准确。 这是符合市场预期。

>> sprintf('%.100f',7/13)
ans =
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000

7/13是重复的十进制值。 下面是正确的数字:

>> vpa('7/13',100)
ans =
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385

现在,假设我们尝试创建相同的编号。 在这里,我将在ASA双通7/13,但我犯了一个错误在底部十进制数字

>> sprintf('%.100f',0.538461538461538461777777777)
ans =
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000

在这里,我们看到VPA捕获并纠正“错误”我做了,承认我在传递实际上是相同的值相同,当我在7/13过去了。

>> vpa(0.538461538461538461777777777,100)
ans =
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385

当然,如果我的价值作为一个字符串传递,然后VPA得到它错了。

>> vpa('0.538461538461538461777777777',100)
ans =
0.538461538461538461777777777

这就解释了为什么VPA是能够赶上并正确计算VPA(罪(π/ 4),100),出充分的精度要求。 罪(PI / 4)被计算为一个双,但随后VPA将其视为一个数字,是相同的sqrt(2)/ 2的双精度版本。

要小心,当然。 例如,VPA是不是足够聪明,抓住这个简单的PI的转变。

>> vpa(pi + 1,100)
ans =
4.141592653589793115997963468544185161590576171875

>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068


Answer 3:

如果你得到确切的相同的答案,你不需要可变精度算术开始。

然而, sin(pi/4)应该是完全sqrt(2)/2 ,这是不合理的。 你不应该得到完全不同的精度相同的答案。 也许你应该检查你如何显示(和四舍五入)的结果。



Answer 4:

最新的文档数字来象征性的转换有答案。

符号试图校正浮点输入的舍入误差,返回的确切符号形式。 具体而言,符号校正舍入误差在匹配形式P / Q,Pπ/ Q,(P / Q)^(1/2),2 ^ q和10 ^ q,其中p和q是适度的该数值输入尺度的整数。

因此, sin(pi/4)2^(1/2)/2(1/2)^(1/2)因此vpa命令识别它。 然而, sqrt(5)/pi是不根据本文档所识别的输入形式。



文章来源: MatLab - variable precision arithmetic