2015.1.5

前へ
次へ
ホームページトップへ戻る

MYCPU80でCP/Mを!
超巨大基板の8080互換HCMOS・CPUでCP/Mを走らせてしまおうという、なんとも狂気なプロジェクトです!


[第94回]


●倍精度の最良近似式

前回の最後のところで倍精度の最良近似式をEXCELで計算するのは無理、と書きました。
その説明をするために過去記事を読み直してみましたら、最良近似式をEXCELで求めるところの説明がありません。
なんとなくそんな気がして、ずっと気になっていたのですよねえ。

最良近似式の求め方については、[第40回]のsin関数から始まって、そのあとチェビシェフの近似式から最良近似式へと説明を進めてきまして、[第66回]でEXCELを使って連立方程式を解くというところまで書いたあと、その次の回からは倍精度実数演算プログラムについてのお話に移ってしまい、そのままずっと今日まで来てしまいました。
EXCELを使って最良近似式を求める実際の計算過程について説明をするつもりだったのですけれど、なにしろ倍精度実数演算プログラムをMYCPU80に組み込むところがかなりホネだったものですから、最良近似式どころではなくなってしまい、そのうちつい書くきっかけをなくしてしまいました。
最良近似式の求め方につきましては、せっかくやっとのことでその方法を理解できたことでもありますので、私自身の備忘録としても、ぜひ書いておきたいと思っております。
ですので、そのうち忘れてしまわないうちに、なんとか整理して書きたいと思います。

しかし今はEXCELでの具体的な解法についてはちょっと置くことにしまして、過去記事を引用しつつ、最良近似式の求め方について簡単におさらいをしたいと思います
最良近似式を求めるための考え方については[第62回]で説明をしています。
そこでのポイントは、まず最初に計算のもとになる近似式を用意します。
チェビシェフの近似式が適当です。
そこで最良近似式の特徴をつかんで計算をおこないます。
ある関数とその最良近似式との差のグラフは、その式の区間内に極大値と極小値があって、かつそれは交互にあらわれることと、その絶対値が等しいこと、通常区間の始点、終点でも極大値(最大値)または極小値(最小値)を取ることがその特徴です(と定義します)。

sinXの17次までの最良近似式を、
sin(x)=ax+bx+cx+dx+ex+fx11+gx13+hx15+ix17
と書くことにしますと、各項の係数a,b,c,d,e,f,g,h,iを計算によって求めることで最良近似式が定まります。
しかし各係数をいきなり求めることはできません。
[第62回]で説明をしている考え方で連立方程式を繰り返し解きながら最良近似式に至ります。
そのとき連立方程式を組むのに必要な条件が上で書いた極大値、極小値の定義です。

[第59回]のグラフを見ていただきますとそのことが理解できると思います。
2番目のグラフで系列1がチェビシェフの(誤差の)グラフです。
極大、極小、極大、極小、極大、と交互に繰り返しています。
この形が必要なのです。
チェビシェフの式のグラフでは極大値、極小値の絶対値は等しくありませんが、それを等しいものだと強引に仮定してそのときの各xの値を式にあてはめて、連立方程式を作ってそれを解くことで、最良近似式に近づいた式を求めることができます。

ところが前回のチェビシェフの17次の式の誤差には、極大値も極小値もありません。
ずっと誤差0できて途中からマイナスの誤差が大きくなってそこで終ってしまいます。
ただ1つの最小値しかありません。
これではどう工夫してみても、連立方程式を組むことはできません。
おそらくは、ここにEXCELの計算精度が関係しているのだと思います。
もしも仮にEXCELの計算精度が15桁ではなくて倍の30桁だったとすれば、おそらく誤差がずっと0ということにはならないだろうと思います。
そこではやっとチェビシェフの式の特徴が現れて、誤差のグラフは[第59回]のグラフのような極大、極小をもったものになると考えられます(その場合には項の数だけ極大、極小が現れることが期待されます)。

そういうことですから、EXCELで倍精度関数の最良近似式を求めることはできない、ということになります。
せっかくEXCELを使えば連立方程式を簡単に解くことができる、と喜んだのですけれどねえ。
残念です。
それならば次善の策としてC++ではどうか、と思いついてさぐってみたのですけれど。
C++の計算精度も15桁でした。
なんでも倍長倍精度とかというようなルーチンを組込むことで多倍精度の演算もできるようになる、という情報も読みましたが、それが一般に公開されているものかどうかについては、深くさぐってはおりません。

仮にそのようなことが可能だったとしましても、今そこにつっこんでしまいますと、またまたMYCPU80用のCP/M互換DOSの完成が遅れてしまいます。
現在ZB3BASICに組み込んでおります倍精度関数のプログラムはあまりみっともよいものではありませんが、まあ今時8ビットのBASICで倍精度関数の演算を使うなどという用途はまず考えられないと思いますから、こんなこともできるのですよ、くらいの位置づけでもよいのでは、と考えてとりあえずは倍精度関数プログラムについては現行のままでいくことにいたしました。

しかし倍長倍精度の計算というものもちょいと興味がありますので、いずれ暇をみつけて(いつのことだか)、C++で倍長倍精度の演算をさせるための工夫もしてみたいと思います。
おお。
別の方法も思いつきました。
C++は既存の倍精度演算を利用して多倍精度の計算プログラムを作るしかありません。
しかしZB3BASICなら、私が自分で開発してきたプログラムですから、どういうようにでもいじくることができます。
現行の倍精度の計算をしているレジスタの桁数を倍にするように書き換えれば、倍長倍精度の計算が自前でできてしまうではありませんか!
いや、さすがにそれをMYCPU80でやるのはおそらくあまりに計算時間がかかりすぎることになると思います。
やるなら、ZBKボードのBASICでしょうね。
CPUは20MHzのKL5C80A12ですから、そこそこの計算時間でやってくれますでしょう。
むむ。
そうすると、ZBKBASICで連立方程式を解くことになるか。
ま、それも面白いでしょう。
時間があれば、ですけれど。

MYCPU80でCP/Mを![第94回]
2015.1.5upload

前へ
次へ
ホームページトップへ戻る