- ベストアンサー
R言語での極小値の指数形式での出力に関する質問
- R言語での極小値の指数形式での出力に関して質問です。
- 入力する値をaとすると、計算する式は1 - exp(-exp(a))となります。
- aが小さい数になると、結果が0となってしまうため、極小数を指数表示する方法について教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
expm1 なんてのもあるか?
その他の回答 (3)
- ki073
- ベストアンサー率77% (491/634)
なぜa=-40のときに答えは0.0になるか分かりましたか? Rの計算は倍精度の浮動小数点演算で計算されますので有効桁数が15桁程度です。 -exp(-exp( a ))を計算しますと1.00000と0が続き、18桁目に0でない数字が現れます。有効桁数15桁だと1.0になるわけです。 もっと有効桁数をとれれば計算は可能です。Rではできるのかどうか分かりません。 Rubyではかなり大きな桁数をとることができ、手間はかかりますがこんな式で計算できます。有効桁数を100桁にした例です。 require "bigdecimal" require "bigdecimal/math" include BigMath prec=100 # 有効桁数 a=-40 b=BigDecimal.new("1.0", prec)-exp(-exp(BigDecimal.new(a.to_s,prec), prec),prec) puts b.to_f 答えは4.24835425529159e-18 となります。 Rも統計計算やグラフ作成に使っていますが、データ構造が複雑でとてもついていけません。 Rubyで前処理をしてそこからRを呼び出して統計計算やグラフ作成をしています。 ANo.2の理由ですが、ヒントはテイラー展開です。
お礼
回答ありがとうございます。 内部演算桁数が十分でなく、計算途中で0に丸められているのかな。。。というのが現在の理解です。 >もっと有効桁数をとれれば計算は可能です。Rではできるのかどうか分かりません。 出力用に有効桁数を変えることはできるようですが、Rの内部演算桁数に関しては今も調べている状態です。 >Rubyではかなり大きな桁数をとることができ、手間はかかりますがこんな式で計算できます。 普段はC++も使っているので、C++上で計算させようかなとも思っていました。なるべくR上で簡潔に済ませたいのですが。 >ANo.2の理由ですが、ヒントはテイラー展開です。 早速調べ始めましたが、なかなか難しそうですね。。。
- f272
- ベストアンサー率46% (8467/18126)
それくらいaが小さいときなら 1 - exp(-exp( a )) = exp( a ) で十分と思う。
お礼
実際にR上で計算させると 1 - exp(-exp( a )) exp( a ) は非常に近い値になりますね。 exp(-40)も4.24835425529159e-18と値が返されます。 ただ、なぜ 1 - exp(-exp( a )) = exp( a ) と言えるのか理由が思いつきません。もしよければ簡単に説明してもらえないでしょうか?
- Tacosan
- ベストアンサー率23% (3656/15482)
計算精度は?
補足
resultの値はe-100くらいになることを想定しています。 ですのでその桁を切り捨て、丸め込みを行わないよう計算させたいのですが。。。 これで答えになっているでしょうか?
お礼
expm1初めて知りました。 説明を読んで、ただexp(a)-1というだけかと思いましたが、小さい数字を扱う場合(今回のよう場合)に正確な値を算出してくれるようですね。 (a <- -4 の場合) (exp使用) > 1 - exp(- exp(-4)) [1] 0.01814893 (expm1使用) > - expm1(- exp(-4)) [1] 0.01814893 (a <- -38 の場合) (exp使用) > 1 - exp(- exp(-38)) [1] 0 (expm1使用) > - expm1(- exp(-38)) [1] 3.139133e-17 のようにすることで特にオプションを設定することなく求める値を得ることが出来ました。(元の式を変えているのでちょっと不思議な感じですが。。。)