メインコンテンツ

vpa

可変精度の演算 (任意精度の演算)

説明

yVpa = vpa(y) は、有効桁数 d 以上の可変精度演算 (任意精度浮動小数点数) を使用して入力 y の個々の要素を評価します。ここで、ddigits 関数の値です。digits の既定値は 32 です。

yVpa = vpa(y,d) は、digits の値の代わりに、d 以上の有効桁数を使用します。

yVpa = vpa(___,BoostPrecision=tf) は、y が倍精度の場合に、可変精度のシンボリック数への変換において y の精度を引き上げるかどうかを指定します。既定では、vpa に倍精度入力を渡すと、この関数は変換時に精度を引き上げようとします。倍精度入力の元のビット パターンを保持するには、BoostPrecisionfalse に設定します。このオプションは、前述の構文にある任意の入力引数の組み合わせに加えて使用できます。 (R2026a 以降)

すべて折りたたむ

可変精度浮動小数点演算を使用してシンボリック入力を評価します。既定では、vpa は有効桁数 32 桁まで値を計算します。

π を有効桁数 32 桁まで評価します。

p = sym(pi);
pVpa = vpa(p)
pVpa = 3.1415926535897932384626433832795

シンボリック式を評価します。

syms x
a = sym(1/3);
f = a*sin(2*p*x);
fVpa = vpa(f)
fVpa = 0.33333333333333333333333333333333sin(6.283185307179586476925286766559x)

可変精度演算を使用してシンボリック ベクトルまたはシンボリック行列の要素を評価します。

V = [x/p a^3];
VVpa = vpa(V)
VVpa = (0.31830988618379067153776752674503x0.037037037037037037037037037037037)
M = [sin(p) cos(p/5); exp(p*x) x/log(p)];
MVpa = vpa(M)
MVpa = 

(00.80901699437494742410229341718282e3.1415926535897932384626433832795x0.87356852683023186835397746476334x)

既定では、vpa は有効桁数 32 桁までの入力を評価します。関数 digits を使用して有効桁数を変更できます。

有効桁数 7 桁を使用してシンボリック式 100001/10001 を近似します。digits を使用して有効桁数を設定し、digits の元の値は保存しておきます。vpa 関数は有効桁数 5 桁のみを返します。これは、後続の桁がゼロであることを意味する場合があります。

digitsOld = digits(7);
y = sym(100001)/10001;
yVpa = vpa(y)
yVpa = 9.9991

より高精度の値 25 を使用して、後続の桁がゼロかどうかチェックします。この結果は、繰り返されている小数部の後続の桁が実際にはゼロであることを示しています。

digits(25)
yVpa = vpa(y)
yVpa = 9.999100089991000899910009

または、digitsvpa の 1 回の呼び出しでオーバーライドするには、2 番目の引数を指定して精度を変更します。

2 番目の引数を指定して、有効桁数 100 桁まで π を求めます。

pVpa = vpa(sym(pi),100)
pVpa = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

計算を続けるため、元の精度値に戻します。

digits(digitsOld)

シンボリックな結果は正確ですが、使いやすい形式ではない場合があります。vpa を使用して、正確なシンボリックな結果を数値的に近似できます。

solve を使用して、高次多項式の根を求めます。関数 solve では、高次多項式をシンボリックに解くことも、root を使用して根を表現することもできません。

syms x
y = solve(x^4 - x + 1, x)
y = 

(root(z4-z+1,z,1)root(z4-z+1,z,2)root(z4-z+1,z,3)root(z4-z+1,z,4))

vpa を使用して根を数値的に近似します。

yVpa = vpa(y)
yVpa = 

(0.72713608449119683997667565867496-0.43001428832971577641651985839602i0.72713608449119683997667565867496+0.43001428832971577641651985839602i-0.72713608449119683997667565867496-0.93409928946052943963903028710582i-0.72713608449119683997667565867496+0.93409928946052943963903028710582i)

digits 関数は、可変精度演算で使用する最小有効桁数を指定します。代わりに、vpa(y,d) 構文を使用して、入力 y を有効桁数が少なくとも d 桁になるように変換することもできます。内部的には、vpa は指定されたよりも多くの桁数を使用します。この追加の桁数は、"ガード桁" と呼ばれます。この桁数によって、その後の計算が丸め誤差から守られるためです。

有効桁数 4 桁を使用して π を近似します。

pi_4digits = vpa(sym(pi),4)
pi_4digits = 3.142

次に、前の結果を使用して、π を有効桁数 6 桁で近似します。この結果は、vpa 関数による π の最初の変換時に 4 桁よりも多くの桁数がガード桁として使用されたことを示しています。

pi_6digits = vpa(pi_4digits,6)
pi_6digits = 3.14159

倍精度形式では 64 ビットのメモリを使用して数値を格納するため、数値精度に限りがあります。倍精度入力に対して vpa を呼び出すとき、vpa が元の倍精度値よりも多くの桁数を返すとしても、倍精度表現の一般的な有効桁数である 16 桁を超える失われた精度は vpa では一般に復元できません。ただし、vpa では pqpπq(pq)122q、および 10q の形式の演算の精度を認識して引き上げることができるアルゴリズムを使用しています。ここで、p および q は適度なサイズの整数です。

まず、log 関数を含む倍精度評価の精度は vpa で引き上げられないことを示します。倍精度結果とそれと同じシンボリックな結果に対して vpa を呼び出します。

yDouble = log(3);
ySym = log(sym(3));
yDoubleToVpa = vpa(yDouble)
yDoubleToVpa = 1.0986122886681097821082175869378
ySymToVpa = vpa(ySym)
ySymToVpa = 1.0986122886681096913952452369225
d = yDoubleToVpa - ySymToVpa
d = 0.000000000000000090712972350015300422166375941649

予想どおり、小数第 16 位を超える結果が倍精度の結果とシンボリックの結果で相違しています。

倍精度の結果とシンボリック厳密解の結果に対する vpa 呼び出しの差を求めることで、vpapqpπq(pq)122q、および 10q の形式の式の精度を引き上げることを示します。ここで、p および q は適度なサイズの整数です。差は 0.0 で、vpa が倍精度入力で低下した精度を復元することを示します。

d = vpa(1/3) - vpa(1/sym(3))
d = 0.0
d = vpa(pi) - vpa(sym(pi))
d = 0.0
d = vpa(1/sqrt(2)) - vpa(1/sqrt(sym(2)))
d = 0.0
d = vpa(2^66) - vpa(2^sym(66))
d = 0.0
d = vpa(10^25) - vpa(10^sym(25))
d = 0.0

R2026a 以降では、pqpπq(pq)122q、および 10q の形式の倍精度の式について、BoostPrecision オプションを false として指定することで、精度を引き上げずに vpa を使用することを選択できます。たとえば、小数第 16 位を超える失われた精度は復元せずに、double 表現のビット パターンを保持して倍精度値 1/3 を可変精度に変換します。この結果は、シンボリック厳密解の結果に対して vpa を呼び出した場合と等しくなりません。

yDoubleToVpa = vpa(1/3,BoostPrecision=false)
yDoubleToVpa = 0.33333333333333331482961625624739
ySymToVpa = vpa(1/sym(3))
ySymToVpa = 0.33333333333333333333333333333333
d = yDoubleToVpa - ySymToVpa
d = -0.000000000000000018503717077085942340393891746679

異なる精度の数値に対して演算を実行するとき、結果に表示されない誤差が含まれることがあります。

たとえば、1/10 を 6 桁の精度と 5 桁の精度で評価します。

a = vpa(1/10,6)
a = 0.1
b = vpa(1/10,5)
b = 0.1

表示される ab の値は同じに見えますが、それぞれ有効桁数 6 桁と 5 桁を超えて格納される桁が異なるため、これらの 2 つの変数は厳密には等しくありません。差 a - b を計算して等価性をチェックします。

roundoff = a - b
roundoff = 0.0000000000000053290705182007513940334320068359
digits
 
Digits = 32
 

a - b の結果はゼロになりません。理由は、a は 6 桁まで正確で b は 5 桁まで正確ですが、差の計算に digits で設定される既定の 32 桁の精度が使用されているためです。

ab の異なる値を表示するには、それらの元の値を有効桁数 32 桁に変換します。

a_32digits = vpa(a,32)
a_32digits = 0.099999999999999644728632119949907
b_32digits = vpa(b,32)
b_32digits = 0.099999999999994315658113919198513

それらの変換後の値の差を計算します。

roundoff = a_32digits - b_32digits
roundoff = 0.0000000000000053290705182007513940334320068359

vpa を使用して、数値 111111111111111111 を有効桁数 32 桁で近似します。この結果は 16 桁を超える部分が正確でありません。MATLAB で数値を入力すると、最も近い表現可能な倍精度値に変換され、入力した数値と厳密には等しくならないことがあるためです。

xVpa = vpa(111111111111111111)
xVpa = 111111111111111104.0

数値を正確に表現するには、string 入力を使用します。この場合、vpa は数値 111111111111111111 を有効桁数 32 桁まで正確に近似します。

xVpa = vpa("111111111111111111")
xVpa = 111111111111111111.0

R2022b 以降

sin([ππ2π2π3]X) を表すシンボリック式 S を作成します。ここで、X は 2 行 1 列のシンボリック行列変数です。

syms X [2 1] matrix
S = sin(hilb(2)*pi*X)
S = 

sin(Σ1X)where  Σ1=(ππ2π2π3)

可変精度演算を使用して式を評価します。

SVpa = vpa(S)
SVpa = 

(sin(3.1415926535897932384626433832795X1+1.5707963267948966192313216916398X2)sin(1.5707963267948966192313216916398X1+1.0471975511965977461542144610932X2))

R2026a 以降

倍精度数をシンボリック数に変換するとき、vpa は既定では精度を引き上げようとするため、意図しない結果になることがあります。具体的には、倍精度数の最下位桁が vpa で丸め誤差と解釈される場合があります。

たとえば、2 つの隣接する倍精度数について考えます。1 と 1 の後の次に大きい倍精度数です。

x = 1;
y = 1 + eps;

これらの 2 つの数を vpa を使用して変換すると、変換後の数値は等しくなり、それらの差はゼロになります。この場合、y の最下位ビットが vpa で丸め誤差として扱われるため保持されません。

d = vpa(y) - vpa(x)
d = 0.0

ただし、倍精度表現では、これらの 2 つの数値はビット パターンが異なります。これは 16 進数形式で確認できます。

x_hexStr = num2hex(x)
x_hexStr = 
'3ff0000000000000'
y_hexStr = num2hex(y)
y_hexStr = 
'3ff0000000000001'

倍精度入力を vpa で変換するときにビット パターンを保持するには、BoostPrecision オプションを false として指定します。これで、変換後の数値の差が eps に近くなります。

d = vpa(y,BoostPrecision=false) - vpa(x,BoostPrecision=false)
d = 0.00000000000000022204460492503130808472633361816
format longE
eps
ans = 
     2.220446049250313e-16

vpadouble の数値のビット パターンを保持していますが、まだ既定の有効桁数 32 桁を使用しており、double の数値の有効桁数を超える追加の桁を埋めようとします。変換後の数値の差を eps と等しくする場合は、vpa の演算の有効桁数を 16 に設定することもできます。

digits(16)
d = vpa(y,BoostPrecision=false) - vpa(x,BoostPrecision=false)
d = 0.0000000000000002220446049250313

最後に、vpa で使用する精度を 32 桁に戻し、出力表示形式を既定に戻します。

digits(32)
format default

入力引数

すべて折りたたむ

評価する入力。数値または string のスカラー、ベクトル、行列、多次元配列、あるいはシンボリック数、シンボリック ベクトル、シンボリック行列、シンボリック多次元配列、シンボリック式、シンボリック関数、シンボリック文字ベクトル、シンボリック行列変数として指定します。

  • MATLAB® で数値を入力すると、最も近い表現可能な倍精度値に変換され、入力した数値と厳密には等しくならないことがあります。数値を正確に表現する場合は、y を string 入力として指定することもできます。

  • y を単精度数として指定すると、vpa はまず倍精度に変換してから、その数値を可変精度に変換します。

データ型: double | single | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | char | string | sym | symfun | symmatrix
複素数のサポート: あり

有効桁数。正の整数スカラーとして指定します。この引数を指定しない場合、vpa で使用される有効桁数は digits 関数によって決定されます。

d が整数でない場合、vparound 関数を使用して最も近い整数に丸めます。

R2026a 以降

倍精度入力の精度を引き上げるオプション。数値または logical の 1 (true) または 0 (false) として指定します。既定では、y が倍精度の場合、vpa は可変精度のシンボリック数に変換するときに y の精度を引き上げようとします。倍精度入力の元のビット パターンを保持するには、この引数を false として指定します。

y が倍精度でない場合、この引数は効果をもちません。

出力引数

すべて折りたたむ

可変精度の出力。シンボリック数、シンボリック ベクトル、シンボリック行列、シンボリック多次元配列、シンボリック式またはシンボリック関数で返されます。

  • ほぼすべての入力データ型 (symsymmatrixstringdoublesingleint64 など) に対して、vpa はデータ型 sym として出力を返します。

  • 入力が symfun 型のシンボリック関数の場合、vpa はデータ型 symfun として出力を返します。たとえば、syms f(x); f(x) = pi*x; g = vpa(f)symfun 型として出力 g を返します。

  • 入力が g = vpa(f(x)) のような sym 型の評価されたシンボリック関数の場合、vpa はデータ型 sym として出力を返します。

データ型: sym | symfun

ヒント

  • vpa は分数の指数を浮動小数点に変換しません。たとえば、vpa(a^sym(2/5))a^(2/5) を返します。

  • vpa は、内部的には digits によって指定される桁数よりも多くの桁数を使用します。この追加の桁数は、その後の計算を丸め誤差から守ります。例については、vpa でのガード桁使用による精度の維持を参照してください。

  • vpa1/32^(-5)sin(pi/4) などの数値入力に対して呼び出すと、まず式が 64 ビット (約 16 桁) の精度の倍精度数として評価されます。その後、vpa により、指定の有効桁数まで精度が引き上げられます。より正確な結果を得るには、代わりに sym を使用してシンボリック入力を定義します。たとえば、exp(1) を有効桁数 32 桁で近似するには、vpa(exp(sym(1))) を使用します。

  • 既定では、vpap/qpπ/q(p/q)1/22q、および 10q という形式に一致する数値入力の精度を引き上げます。ここで、p および q は適度なサイズの整数です。詳細については、一般的な倍精度入力の精度の維持を参照してください。

  • 可変精度演算は、以下の点において IEEE® の浮動小数点規格 754 と異なります。

    • 計算の中で、ゼロ除算はエラーをスローします。

    • 指数範囲は事前定義されたどの IEEE モードよりも広いです。vpa はおよそ 10^(-323228496) までアンダーフローします。

    • 非正規化された数値は実装されていません。

    • ゼロは符号が付きません。

    • 結果の仮数内の "2" 進数の数は、可変精度演算と IEEE の事前定義された型とで異なることがあります。

    • NaN がただ 1 つ存在します。クワイエットとシグナリングの NaN の違いは識別されません。

    • 浮動小数点数の例外は使用できません。

バージョン履歴

R2006a より前に導入

すべて展開する