2012-06-22[n年前へ]
■続々々 エクセルのワークシートをC++言語プログラムに変換してみよう!
エクセルで(反復計算を用いた)循環参照が行われている計算シートと同じ計算を、C++言語で行うためのC++ソースコードを自動生成するRubyスクリプトを少しだけ更新してみました(github)。
追加したのは、計算した結果を表示する機能と、無駄な数値代入計算をさせないようにしたという部分です。
使い方は、とっても簡単。たとえば、
ruby xls2cpp.rb sample.xls > sample.cppという風にしてXLSファイルからC++ソースコードを生成し(参考:githubのsample.cppなど)、後は、
cl /EHsc /Ox sample.cppとでもし…つまり最適化をバッチリかけてやったならば、計算がバッチリ速くなるかも!?しれません。(エクセルの方が最適化されていて速かったり…とかいうこともありそうですが)
というわけで、エクセルで(たとえば偏微分方程式を離散化して解く)コードをチョチョイと感覚的にプロトタイピングした上で、後はC++コードに変換し・最適化をかけまくる…という、「エクセルプロトタイピング+最適化C++コード自動生成」シミュレーションをしてみるのはいかがでしょう?
2012-11-18[n年前へ]
■「黒パンツを覆う白生地中の光収支方程式」問題をエクセルで解いてみよう!?
検証!「夏目アナの脇汗事故はなぜ起こったか?」ー灰色の服が汗染みに弱い理由では、脇汗をかいた時、着衣の外見がどのような色になるかを考えてみました。
今日は、別の着衣の「外見色」問題、「白生地で覆われた黒パンツは一体どんな風に見えるのか?」という(いわゆるひとつの)「黒パンツを覆う白生地中の光収支方程式」問題を、表計算ソフトであるエクセルを使って解いてみることにします。
「白い生地」は光を散乱/拡散させる素材です。 簡単のために、白生地が完全に光を散乱/拡散させるものと近似すると、生地中の微小領域(部分)を考えれば、その領域は周囲に等方に光を発するということになります。 逆に言うと、「白生地の各領域は周りから発せられる光を受ける」ということです。 そんな風に考えると、(下図に描いたように)白生地の各領域の輝度は、「周囲の輝度の平均」を用いた形の式で表されることもわかります。つまり、この「黒パンツを覆う白生地中の光収支(輸送)方程式」は熱伝導方程式などを解いたのと同じやり方、エクセルで「反復計算(循環参照計算)」を使えば解くことができるのです(下図参照)。
それでは、実際にエクセルを使って「白生地で覆われた黒パンツは一体どんな風に見えるのか?」問題、すなわち、「黒パンツを覆う白生地中の光収支方程式」問題を解いてみることにします。(参考までに、今回作ったエクセルのファイルはここに置いておきます)
まずは、エクセルに『体の上の「黒パンツ」』を示す「反射率分布」を白黒(1,0)で造ってみます(上図のA1からQ16までの領域)。
そして、その下に(B19からQ34までの領域)に「(黒パンツを覆う)白生地」を作ります。
白生地の各領域には "=(上+下+左+右)/6 + 自分×反射率/6+1/6" といったような式を入力します。
そして「反復再計算」を実行すると「白生地で覆われた黒パンツは一体どんな風に見えるのか?」をエクセルが計算してくれるわけです。
また、「数値の大小が色を表すような書式」にしておけば、計算結果をそのまま濃淡のイメージとして眺めることもできます。
さて、体の上に「黒パンツ」があるとして(上図の右上部分)、その「黒パンツ」を覆う白生地が(外見上)どんな輝度に見えるかの計算結果を示したのが、上図の右下部分です。 (白=1, 黒=0)という色で示した計算結果を眺めてみると、白生地越しの黒パンツはずいぶん「ぼやけた姿」となって見える、ということがわかります。 単純な計算ですが「確かにそんな感じ」という結果になりました。
下着が透けてしまう・それとも大丈夫(透けない)といった「着こなし」の問題に悩んだときは、その問題を表計算ソフト・エクセルを使って「実際に解いてみる」という解決策はいかがでしょうか?
2014-08-22[n年前へ]
■Excelで”-1^2″の計算結果が1で、”0-1^2″は-1になるヒミツ!?
Excelで”-1^2″の計算結果が1で、”0-1^2″は-1になるヒミツ!?を書きました。この話題、遙か昔から定番ですが、とても面白いと思います。
このようなExcelの演算子解釈ルール(優先順位ルール)は、どのようにして生まれたのでしょう?「それは、きっとExcelに先行して発売されていた表計算ソフトのVisicalcやLotus 1-2-3にならったに違いない!」と言われることも多いのですが、残念ながらそうではありません。Visicalcの演算子解釈順は、単純に左から右へと並ぶ”並び順”で解釈されますし、Lotus 1-2-3は…
2020-01-22[n年前へ]
■「エクセルの計算順序」から「コンピュータの歴史」を感じよう!
-2020年になった今、1950-1980の時代を振り返る-
-1^2の計算結果は-1になる!?「エクセルの計算順序」の謎
オフィス作業の多くがMicrosoft Excel(エクセル)上で行うのが当たり前となっています。そのエクセルでシートを開き、”= 0 - 1^2”, “= -1^2 + 0”という2式をセルに入力すると、どんな計算結果が出力されるでしょうか?
「どちらも-1になるはず」と答える人が多いかもしれませんが、実際に式をセルに入力すると、”=0 - 1^2→ -1”, “=-1^2+0→1”という結果になります(図1(a))。だからといって、「エクセルの計算バグ!?」と考えてはいけません。なぜなら、これは伝統正しいエクセルの仕様だからです。
同じ“-”でも二項演算子の”-”と単項演算子の”-”がある?
「どちらも-1になるはず」という答は、2式をそれぞれ0 –(1^2)と-(1^2)+0という順番に暗算から得られたはずです。…けれど、エクセルが行う計算順は、それとは違う0 –( 1^2)と(-1)^2+0という順番です。その結果、 -1と1という計算結果をエクセルは得るのです。
「減算よりべき乗の演算の方が優先されるべきだから、エクセルの計算順はやはりおかしくない?」と思う人もいるかもしれません。しかし、エクセルも、2つの値間でべき乗計算を行う”^”は、減算を行う“-”より優先する仕様になっています。
この2式には、”-” ”^” ”+”という演算子が登場します。そのうちの、”^”と”+”についてはすべて、左右の2値を使い演算を行う2項演算子です。ところが、”-”については、”= 0 - 1^2”では(被演算子が左右にある)2項演算子ですが、“= -1^2 + 0”については、(被演算子が左右の片方にしかない)演算で使う値が一個の単項演算子(Unary operator)として、エクセルの計算が行われます(図1(b))。
“= -1^2 + 0”の”-”は、”-”の右側にある1を符号反転させる演算子で、エクセルが採用する演算子優先順では、単項演算子は二項演算子に優先します(図1(c))。その結果として、-1^2+0は (-1)^2+0 として計算されて、1という値が出力されるのです。
コンピュータを広めた表計算ソフトが生まれた時代の計算順を調査しよう!
エクセルの演算順序が、一般的な代数式の計算順序と異なる仕様になった理由はわかりません。「エクセルが開発された当時、標準的に使われていたLotus 1-2-3との互換性を考えたのではないか?」とも思いたくなりますが、そうでもありません。
なぜなら、Lotus 1-2-3では、エクセルと異なる-1^2=1という計算結果になるからです。また、1985年発売のエクセルの開発チームは、Lotus 1-2-3(1983年発売) に先行して1982年発売のMultiPlanも開発しましたが、Multiplanでもやはり-1^2=-1と計算していたからです。
エクセルやMultiplanが発売当時を調べてみると、面白いことがわかります。表計算ソフトという形態を作り出したVisiCalcも、当時の表計算ソフトの用途と重なるところも多かったデータベースソフトdBaseでも、ビジネスプログラミング言語のCOBOLも、多くのソフトでエクセルと同じ演算結果を出力します(図2、図3)。 そんな時代背景を踏まえれば、エクセルが「単項演算子―は2項演算子^に優先する」という仕様にしたということも、いたって自然にも思えてきます。
セル間の計算順序には「2つの方法」が使われている
「セル間の演算を簡単にできる」のが、今ではエクセルに代表される表計算ソフトウェアです。だから、エクセル等が計算を行う際には、セル内の演算順だけでなく、セル間の計算順序もきちんと決まっていて、エクセルでは、2つの異なるセル間の計算方法が使われています。
「依存関係ごとに、値が定まるものから先に」の計算順
通常使われているセル間の計算順は、「セル間の依存関係を(ツリー構造で)辿り、値が定まっている“源流“から計算を順に行っていく」というものです。たとえば、セルB2に”=10-B3”、そしてセルB3に”6”という文字が入力されていたら、まずは「セルB2の前に、セルB3を定義する」という依存関係を持つグループの中で順番を生成した上で、セルB3を表す変数に値6を設定し、そしてB3で10-6という演算を行って、結果の4を格納するのです。もしも、ユーザーがどこかのセルを書き換えた時には、そのセルが属する依存関係のグループ内のみで、上流から下流に向かって計算が行われます。
アルファベット順+Zの法則(左→右、上→下)の計算順
もうひとつのセル間計算順は、「通常の方法が使えない場合」に使われます。具体的には、自己参照(循環参照)が行われている場合、言い換えれば「依存関係を辿っていくと、いつの間にか自分に辿り着いてしまい、無限ループに陥る場合」に使われます。計算をするのに、自分(自セル)自身の値を入力(右辺値)として使う状況があるの?と感じられるかもしれません。けれど、方程式を解く必要がある場合など、自己を参照するような数式に対する計算ができると便利なことも多いのです。
たとえば、x ==(2 -3 y) / 4, y == (5 – 6 x) / 7という一次連立方程式を解きたい場合、セルB1とB2をxと yだとした上で、それぞれに =(2 -3*B2)/4と =(5 - 6*B1)/7という式を入れてみます。すると、「循環参照が行われています・・・」という警告が出るので、設定を「反復計算を使う(計算回数はとりあえず100)」と変えて、反復計算を実行させる(F9を押す)と、x(B1)=-0.1, y(B2)=0.8と連立方程式の計算結果が求まります。
反復計算を行う場合には、循環参照が行われている部分に対し、アルファベット順で前方のシートから、そして同じシート内では左から右へ・上から下への順で(A1からA行を左から右へ、次はB行を左から右へ…と)計算が行われます。そして、最大反復回数に達するか、各セルでの計算結果の変化値が所定の値を下回るまで、この計算が繰り返されるのです。
循環参照による反復計算は、普通とは言えないかもしれません。とはいえ、方程式を解いたりする場合などには必須になることも多い計算手法です(*この方法では、必ずしも計算が収束するわけではありません)。
表計算ソフトが生まれた頃は、反復計算方式が使われていた
表計算ソフトが登場したての’80前半、すべての表計算ソフトが、どのような計算であっても、反復計算方式を使っていました。もう少し正確に言えば、シートに含まれるセルに対して(Zの法則など)所定の順番で計算を行い、値が変わらなくなるまでユーザが手動で計算を繰り返していました。
「値が変わらなくなるまで再計算を行う」必要がなぜあるかというと、他のセルを参照する計算式が使われている場合、セルの並び順によっては「参照先を辿る回数」の再計算を行わなければ、最源流のセル値が最下流のセルまで反映されないからです(図4)。そのため、初期の表計算ソフトを使う際には、セルの値を見ながらユーザが計算を繰り返さなければならなかったのです(図5)。
最源流のセルから下流へと「依存関係に沿って計算していく方式」が一般的に用いられるようになってから、各セルに対し1回の計算だけで結果が得られるという、現在の表計算ソフトの形態に落ち着いたのです。
表計算の計算方法を提案する「幻の基本特許」が存在していたが…
「依存関係を踏まえ、上流セルから計算を行う」という表計算ソフトの土台ともなっている演算手法ですが、実は「幻の基本特許」があります。
今の表計算ソフトの原型となったVisiCalcが登場する1979年より10年も前の1969年、LANPARというデータ操作言語が米国人Rene PardoとRemy Landaにより開発されます。LANPARが採用した変数間の演算順序は、automatic forward referencing (natural order calculation)と呼ばれ、「値が定義されているものから先に計算を行う」という表計算の計算順序に関する基本アルゴリズムと言えるものでした。
申請から13年を経て成立した特許で、さらに6年後に訴訟開始
PardoとLandaは、1970年に計算手法に関する特許申請を行いましたが、「技術の内容説明が不足」という理由で申請は却下されます。しかし、彼らは特許成立に向けた活動を続け、「プログラミングに関わる一般知識を持つ通常の人であれば、特許で公開された内容から技術を再現できる」とする一般の3名のプログラミング経験者による宣誓書を提出することで、特許申請から13年を経た1983年、米国特許4,398,249号としてようやく認めさせます(図6)。
そして、すでに表計算ソフトが必需品となっていた1989年、Pardoらは、「1ヶ月以内に少なくとも2名の特許侵害者を訴える」という条件付きで、パテント・トロール企業として有名なRefacに特許権利の5%を譲渡します。Refacは、デジタル時計の表示に関する特許、「時と分表示の間にあるコロンを点滅させる」というフラッシュ・コロン特許で、日本企業を中心に100億円以上の特許使用料を得た企業です。
そんな経緯を受けて、Refacは表計算ソフトを販売していた6社、Lotus(Lotus 1-2-3), Microsoft(Excel), Borland(Quattro), Ashton-Tate(Full Impact), Computer Associates(SuperCalc), Informix(Wingz)に対して、膨大な特許使用料を請求する訴訟を起こします。権利期間17年にわたる特許使用料として、膨大な金額を請求する訴訟です。
「特許内容は十分」と宣誓したプログラミング経験者、実は…
「表計算ソフトの基本特許は、膨大な特許使用料を生み出した」という結末を迎えたかというと…そうではありませんでした。その訴訟の結果は「大どんでん返し」で終わります。
1989年に始まる審判で、「Pardoらの特許申請には不正があり、権利無効である」とLotusが主張したのです。どういうことかというと、「特許内容は十分詳細である」と証言したプログラミング経験者というのが、実はLANPERの開発経験を持つ関係者で、その事実を特許商標局に対して隠していたというのです。「特許申請に対して全く前提知識を持たない人であっても、技術内容を理解できる」という意見を述べる宣誓であるはずが、実はそうではないものを提出していたことを「不正」と判断されたのです。そして、1996年、表計算ソフトの演算手法に関する基本特許とも言える米国特許4,398,249号は、「権利を行使できない幻の特許」と決定されたのでした。
表計算ソフトの演算順…そこには「面白い歴史」が詰まってた
個人でコンピュータを使えるようになった20世紀の後半も、あるいはPCがあたりまえの道具になった21世紀の今現在も、その価値や原動力となっているのが表計算ソフトです。そんな表計算ソフトの演算(計算)順を今回は調査してみました。意外なほど、たくさんのエッセンス、とても興味深いコンピュータの歴史がそこには詰まっていました。