vpa(sin(pi/4)) のような数値が完全な精度で正確であると想定しないでください。MATLAB は通常、浮動小数点演算を使用して vpa の呼び出し内で数値を計算するため、約 16 桁までしか正確ではありません。
しかし、ここでは正しいようです。たとえば、私たちはそれを知っています
sin(pi/4) == sqrt(2)/2
その結果をテストしましょう。vpa と自分の HPF ツールの両方を比較して、100 桁の精度を使用します。
>> 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
したがって、私の推測では、シンボリック ツールボックスがより正確に計算できるものとしてパーサーが入力を認識したと考えられます。さっきも言ったけど気をつけてね。sin(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 に正しい値を計算させました。実際、少し努力すれば、sin(pi/12) の値が sqrt(2)*(sqrt(3) - 1)/4 として得られます。
>> DefaultNumberOfDigits 100
>> (sqrt(hpf(3)) - 1)*sqrt(hpf(2))/4
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655
ポイントは、パーサーがここであなたを救うとは信じないということです。
編集: Amro のコメントのテストとして、MATLAB がここで興味深いことを行っていることを丁重に述べます。pi が倍精度数として渡された場合でも、vpa が正しい pi の最初の 100 桁を返すことができることを確認してください。pi (double として) は 10 進数の 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 値を double に格納して取得し、それを HPF 数値に変換します。
>> hpf(pi,100)
ans =
3.141592653589793115997963468544185161590576171875
>> hpf('pi',100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
>> hpf('pi',100) - hpf(pi,100)
ans =
0.0000000000000001224646799147353177226065932275001058209749445923078164062862089986280348253421170679821480800000000
明らかに、MATLAB は pi を、それが渡される倍精度値以上のものとして認識できます。
編集2:
実際、ここで何が起こっているのかは、ちょっとした遊びでわかります。VPA はトリッキーなものであり、パーサーではありません。分数 7/13 を考えてみましょう。これを double として構築し、完全に格納された浮動小数点値を出力すると、それが正確ではないことがわかります。これは予想通りです。
>> sprintf('%.100f',7/13)
ans =
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000
7/13 は繰り返し 10 進数値です。正しい数字は次のとおりです。
>> vpa('7/13',100)
ans =
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385
ここで、同じ数を作成しようとするとします。ここでは asa double で 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(sin(pi/4),100) をキャッチして正しく計算できる理由を説明しています。sin(pi/4) は double として計算されますが、vpa は sqrt(2)/2 の倍精度バージョンと同じ数値として認識します。
もちろん気をつけて。たとえば、vpa はこの単純な pi の変化を捉えるほどスマートではありません。
>> vpa(pi + 1,100)
ans =
4.141592653589793115997963468544185161590576171875
>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068