1

vpaMatLabでS式を評価するために使用できるコマンドについて簡単な質問があります。

私の教科書には次のように書かれています。

「数値などの関数を使用する場合は注意が必要sqrtです。デフォルトでは倍精度浮動小数点数になります。vpa正しい評価を行うには、このような入力を記号文字列として渡す必要がありますvpa('sqrt(5)/pi')。」

ここでの専門用語はよくわかりません。vpa(input)ほとんどの入力で、入力するか入力するかにかかわらず、まったく同じ答えが得られるのに、vpa('input')平方根では得られないのはなぜですか?たとえば、vpa(sin(pi/4))またはを入力vpa('sin(pi/4)')するとまったく同じ答えが得られますが、上記の「giveproblem」をと入力するとvpa(sqrt(5)/pi)、と入力したときと同じ答えが得られませんvpa('sqrt(5)/pi')

誰かが私の本が上でしたことよりもう少し詳細にこれを説明することができれば、私は非常に感謝するでしょう!

4

4 に答える 4

11

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
于 2012-06-03T20:25:24.393 に答える
5

私は MatLab の専門家ではありませんが、引用符がなければ、次の結果sqrt(5)/piに渡していvpa()ます。

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

引用符を使用すると、式 sqrt(5)/pi(未評価で正確な形式) を に渡し、vpa()MatLab にsqrt(5)/pi可変精度で計算するように指示します。

于 2012-06-03T18:51:45.610 に答える
1

数値から記号への変換に関する最新のドキュメントに答えがあります。

sym は、浮動小数点入力の丸め誤差を修正して正確なシンボリック形式を返そうとします。具体的には、sym は、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)vpasqrt(5)/pi

于 2016-01-25T13:49:40.540 に答える
1

まったく同じ答えが得られた場合、そもそも可変精度演算は必要ありませんでした。

ただし、sin(pi/4)正確に である必要がありますがsqrt(2)/2、これは不合理です。異なる精度からまったく同じ答えを得るべきではありません。おそらく、結果の表示方法 (および四捨五入) を確認する必要があります。

于 2012-06-03T18:55:45.043 に答える