JavaScriptの数値計算ライブラリkonpeitoを作りました

アルゴリズム
スポンサーリンク

はじめに

こんにちは~!

なたでと言います。本日は数値計算ライブラリを作りましたので、紹介をしたいと思います。先に言っておきますが、このライブラリはMaximaのような数式を変形するようなライブラリや、3DCG専用の高速数値計算用ライブラリではございません。申し訳ございません。

動作環境は、UMD版とES6のモジュール版を用意しています。存在しないメソッドがあれば補完する互換性向上用の機能を持っていますので、UMD版であればIE11でも動作するかと思います。

数値計算ライブラリを試してみる

機能とかの話より先に手を動かしたい方へのご紹介です。

雰囲気を知りたい

  1. ライブラリのUMDを読み込んでいるサイト」を開いてください
  2. コンソールを開いて以下のような入力をしてみて下さい。
""+konpeito.BigInteger.create(123).pow(456)
""+konpeito.BigDecimal.create(0.0).acos()
""+konpeito.Fraction.create("1 / 3").mul(3)
""+konpeito.Complex.create("1 + j").mul("2 - 3j")
""+konpeito.Matrix.create("[1 2;3 4;5 6]").svd().U
""+konpeito.Matrix.create("[1+j 2-3j -3 -4]").fft()

簡単ではありますが、使い方や雰囲気がなんとなくお分かりになったかと思います。

どんな機能があるか知りたい

利用できる関数をdocファイルにしていますので、チラ見してみて下さい。

早く使ってみたい

使い方は分かったから、早く自分のサイトで使ってみたいという方に向けて紹介します。

  1. GitHubのリリースから最新の「Source code (zip)」をダウンロードする
  2. 中から以下のファイルを2つ取り出す
    1. ./konpeito/build/konpeito.umd.min.js → ファイル名を変更して konpeito.js とする
    2. ./konpeito/build/index.d.ts → ファイル名を変更して konpeito.d.ts とする
  3.  適当なhtmlファイルを編集して以下の行を追加する
    • <script src="konpeito.js" charset="utf-8"></script>
  4. 利用したいjsファイル内に以下の記述を行う
    • /// <reference path="./konpeito.d.ts" />
  5. 後はVSCodeでjsファイルを編集する

本格的に導入してみたい

README.md を参照してください。

数値計算ライブラリの解説

使い方や雰囲気がなんとなくわかったかと思います。ここからは、もう少しつっこんで、このライブラリの説明をしていきたいと思います。

konpeitoで扱える型

種類

konpeitoの型は大きく分けて5つあります。

クラス名 機能の説明
BigInteger 任意精度の整数を扱うクラス。巨大な素数を扱うこともできる。
BigDecimal 任意精度の浮動小数を扱うクラス。三角関数や指数関数を扱うことができる。
Fraction 分数を扱うクラス。巨大な数値を誤差無しで四則演算できる。
Complex 複素数を扱うクラス。確率用の関数を利用できる。
Matrix 複素行列を扱うクラス。統計分析や信号分析などの関数を利用できる。

BigDecimalとFractionは、内部的にはBigIntegerを利用しています。そのため巨大な数値を扱っても桁落ちしないようになっています。(BigDecimalは精度の設定が可能)

Complexは内部では、ビルトインのdouble型を利用しています。さらに、Matrixは、内部的にはComplexを利用しています。そのため、BigIntegerやBigDecimal、Fractionのような任意精度の計算は不可能です。ただ、ビルトインの型は高速動作するため、確率や統計処理用の関数も豊富に実装しています。

使い方

モジュールを読み込むと、konpeitoというグローバルオブジェクトが作成されます。そこに、上記のクラス名を付けることでクラスを利用することが出来ます。

  • konpeito.BigInteger
  • konpeito.BigDecimal
  • konpeito.Fraction
  • konpeito.Complex
  • konpeito.Matrix

データを作成する場合は、以下のように作成します。

  • newを付ける
    • new konpeito.Matrix("[1 2 3;4 5 6]")
  • createメソッドを使用する
    • konpeito.Matrix.create("[1 2 3;4 5 6]")

どうしても1行が長くなってします。そのため、createメソッドを好きな変数に代入して使うのが楽だと思います。

const BigInteger = konpeito.BigInteger;
const $ = BigInteger.create;

console.log($("-1234567890").mul("987654321098765432109876543210").toString());
> -1219326311248285321124828532111263526900

console.log($("7").pow("50").toString());
> 1798465042647412146620280340569649349251249

計算にはメソッドチェーンのみを対応しています。

例えば、(1/3 + 0.333…) * 10 といった計算は以下のようになります。

const Fraction = konpeito.Fraction;
const $ = Fraction.create;

console.log($("1/3").add("0.(3)").mul(10).toString());
> 20 / 3

利用できる関数は、例外もありますが、基本的にどの型でも利用できるように統一化されています。

関数の利用方法は、docファイルを参照してください。

機能比較

konpeitoが用意している各クラスの機能比較表です。

BigInteger BigDecimal Fraction Complex Matrix
整数
多倍長整数 × × ×
浮動小数 × ×
任意精度浮動小数 × × × ×
分数 × × × ×
多倍長分数 × × × ×
複素数 × × ×
行列 × × × ×
素数
乱数 ×
四則演算
ビット演算
指数対数 ×
三角関数 × ×
双曲線関数
× ×
確率用関数 × × ×
統計用関数 × × × ×
線型代数用関数 × × × ×
信号処理用関数 × × × ×

konpeitoが用意している専用計算ツール

専用計算ツールとは

konpeitoには、内蔵の型を利用して実装した「拡張機能」が用意されています。まだいくつかの機能しか実装されていませんが、現在、以下の機能が利用できます。

  • データ分析(Data-Analysis
    • 主成分分析(Principal-Component-Analysis
    • 重回帰分析(Multiple-Regression-Analysis

主成分分析

利用する場合は、konpeito.DataAnalysis.runPrincipalComponentAnalysisをご利用ください。

使い方は、docファイル及び、主成分分析のtestファイルを参照してみて下さい。

重回帰分析

利用する場合は、konpeito.DataAnalysis.runMultipleRegressionAnalysisをご利用ください。

使い方は、docファイル及び、重回帰分析のtestファイルを参照してみて下さい。

使用すると、エクセルの回帰分析と同等の戻りを返します。一部の例をここに記載します。

const x = "[5.5 12;4.5 9;4.1 8;3.5 6;2.5 5;2.3 6;2.7 5;2.8 4]";
const y = "[73; 59; 56; 31; 28; 31; 30; 25]";
const result = MultipleRegressionAnalysis.runMultipleRegressionAnalysis({ samples : x, target : y });

// result は以下の結果がかえります。

const ans = {
	"q": 2,
	"n": 8,
	"predicted_values": [
		[
			75.83447377714992
		],
		[
			56.64404909058803
		],
		[
			49.934729825181
		],
		[
			37.45362440402614
		],
		[
			27.931705809641535
		],
		[
			31.82842574607099
		],
		[
			28.869238919300727
		],
		[
			24.503752428041672
		]
	],
	"sY": 277.7047059862264,
	"sy": 289.484375,
	"multiple_R": 0.9794427501279707,
	"R_square": 0.9593081007782419,
	"adjusted_R_square": 0.9430313410895387,
	"ANOVA": {
		"regression": {
			"df": 2,
			"SS": 2221.637647889811,
			"MS": 1110.8188239449055
		},
		"residual": {
			"df": 5,
			"SS": 94.23735211018895,
			"MS": 18.84747042203779
		},
		"total": {
			"df": 7,
			"SS": 2315.875,
			"MS": 330.8392857142857
		},
		"F": 58.93728967713661,
		"significance_F": 0.00033401802256727287
	},
	"Ve": 18.84747042203779,
	"standard_error": 4.34136734474725,
	"AIC": 50.4340171754824,
	"regression_table": {
		"intercept": {
			"coefficient": -7.958723291541588,
			"standard_error": 5.444484810635138,
			"t_stat": -1.4617954808130225,
			"p_value": 0.2036463862692668,
			"lower_95": -21.95421705015804,
			"upper_95": 6.036770467074863
		},
		"parameters": [
			{
				"coefficient": 4.6876655482959535,
				"standard_error": 4.033171035431498,
				"t_stat": 1.1622778967503997,
				"p_value": 0.2975793071675239,
				"lower_95": -5.6799306553987225,
				"upper_95": 15.05526175199063
			},
			{
				"coefficient": 4.834253046088648,
				"standard_error": 1.7238464783002552,
				"t_stat": 2.8043408197551973,
				"p_value": 0.03779957152493174,
				"lower_95": 0.40296460154439817,
				"upper_95": 9.265541490632899
			}
		]
	}
};

konpeitoの利用者ターゲット

本ライブラリは機能が豊富のため、ばりばり数値計算したいという方向けのように思えますが、基本としては、ちょっとした数値計算をJavaScriptでやりたい方や、数学を勉強したい方をターゲットかなと思っています。

この理由は、konpeitoはスパース行列を対応していなかったり、対称行列でしか固有行列を求められなかったり、正直、これメインを数値解析で利用するというのは難しいのではないかと思います。ただ、何らかの計算済みの結果をGUIに表示する際に少し加工したい。あるいは、ちょっとした計算(でも専用の関数がないと計算できない)を手元のブラウザですぐに実行したいという方には向いているのではと思います。

他の数値計算ライブラリとの比較

konpeito以外にも数学ライブラリはたくさんみかけます。そんな数学ライブラリと、konpeitoとを比較してみました。どれが一番良いかということはなく、どれも一長一短あるかと思います。

比較表

GitHub 使い方 種類 minify ライセンス
BigInteger.js docs 多倍長整数 31KB Unlicense
bignumber.js docs 多倍長整数 19KB MIT
decimal.js docs 任意精度浮動小数 31KB MIT
Fraction.js docs 分数(多倍長不可) 19KB MIT or GPL Ver 2
mathjs docs 統合環境 552KB Apache Ver 2
konpeito docs 統合環境 176KB MIT

使い方の例

  • BigInteger.js
const result = bigInt("1234").pow("10");
const str = result.toString(10);
console.log(str);
  • bignumber.js
const result = BigNumber("1234").pow("10");
const str = result.toString(10);
console.log(str);
  • konpeito(BigInteger)
const result = konpeito.BigInteger("1234").pow("10");
const str = result.toString(10);
console.log(str);
  • decimal.js
Decimal.set({ precision: 34, rounding: 4 });
const result = (new Decimal("1234")).pow("10");
const str = result.toFixed();
console.log(str);
  • math.js BigNumber
console.log("math.js BigNumber");
math.config({
	number: "BigNumber",
	precision: 34 
});
const result = math.chain("1234").pow("10");
const str = result.toString();
console.log(str);
console.log(math.PI.toString());
  • konpeito(BigDecimal)
console.log("konpeito BigDecimal");
konpeito.BigDecimal.setDefaultContext(new konpeito.MathContext(34, konpeito.RoundingMode.HALF_EVEN));
const result = konpeito.BigDecimal.create("1234").pow("10");
const str = result.toPlainString();
console.log(str);
console.log(konpeito.BigDecimal.PI.toString());

こんな感じです。

機能比較の結果

konpeito

色々な計算したいが、1つのモジュールだけで済ましたい場合は有用化と思います。

マニアックなところですが、konpeitoでは、Infinity-InfinityNaNが扱えるのですが、他のライブラリだと扱えない場合があります。これらの値を利用する場合は、konpeitoの利用が良いでしょう。

他社製品

それぞれ特定の機能しか利用しないのであれば、専用のライブラリのほうがファイルサイズの面などからよいかもしれません。

機能が多いmathjsですが、通常利用する分はよいとおもいますが、関数一覧を見る通り、確率や統計のための関数などが十分ではない可能性があります。

おわりに

以上、紹介を終わりたいと思います!

最後まで読んでいただきありがとうございます。またライブラリを更新した場合はこの記事も更新を続けていきたいと思います!

皆さんもよろしければ使ってみて下さい!では!

付録

名前の由来

以下のような由来からきています。

  • コンペイトウが好き
  • コンペイトウの色々な色が、BigInteger, BigDecimal, Fraction, Complex, Matrix といった各機能を表しており、色々な機能が1つになっている。
  • 計算するの「compute」をもじって「konpeito」になった。

開発の背景

これまで何度かライブラリの開発の記事を記載してきました。その中でも、以下のライブラリがkonpeitoの元となったライブラリになっています。

JScript/HTML5 用自作ライブラリ Senko の紹介

上記に記事で背景を書いてはいますが、就職してWindowsで簡単に実行できるバッチ環境JScriptに手を出し、JScriptの勉強のために2013年からライブラリを作り始めました。

一番最初に作ったのは、BigIntegerとなります。その後、BigDecimal、Randomを実装し、Complex、Matrix、Fractionの順番に設計実装をしていきました。

最初は、NetBeansを利用していたのですが、VSCodeに乗り換え、Node.jsのライブラリ化へ繋げていきました。

JavaScript開発環境をNetBeansからVisual Studio Codeに切り替えた話

その後は、ES6用のライブラリを作るという目標に切り替えて、英語化、JSDoc、minify、型定義などを調査し、npmに登録することができました。色々勉強になってよかったです。

このあたりも記事にしているので、もの好きの方は見てみるとよいかもしれません。

初めてJavaScript、ES2015(ES6)でちゃんとしたライブラリを作ったときの話

数学の知識について

学生時代にMATLABを利用して、音声音響信号処理と機械学習、統計を組み合わせた研究を行っていました。そのときに学んだことを再学習するために、改めてライブラリとして作ってみたいと思ったのが、konpeitoの開発契機になります。

「他のライブラリへプルリクエストする」とかもありますが、数学の勉強やJavaScriptのライブラリ作りを勉強したいという気持ちが気力となっているので、自分で一から作ることとしています。多分他人のライブラリにリクエストするとなるとやる気がおきず、ここまで作れなかったと思います。プログラミングが好きな方は分かりますよね!

参考になった本

本ライブラリを作るにあたって利用した本などを紹介します。少し古い本ですがとても良い本なので是非買ってみるとよいと思います。

 

コメント

タイトルとURLをコピーしました