XLPack API: C/C++ 使用例
Cプログラム例 (例題(1), Visual C)
Visual C (Visual Studio (Windows版)) を使用した例です. 行列を列優先(VBAやFortranと同じ, 通常のC/C++の格納順番とは行と列が反対)で格納していることに注意してください.
aとbに1次元配列を使います(リファレンスマニュアルは下のClangの例のように可変長2次元配列で表記していますがVisual Cの場合には読み替えてください).
#include <stdio.h>
#include "cnumlib.h"
int main(void)
{
double a[3][3] = {
{ 0.2, -0.32, -0.8 },
{ -0.11, 0.81, -0.92 },
{ -0.93, 0.37, -0.29 } };
double b[] = { -0.3727, 0.4319, -1.4247 };
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;
dgesv(n, nrhs, lda, (double *)a, ipiv, ldb, b, &info);
printf("x = %f %f %f\n", b[0], b[1], b[2]);
printf("info = %d\n", info);
return 0;
}
実行結果
x = 0.860000 0.640000 0.510000
info = 0
Cプログラム例 (例題(1), Clang)
Clang ではC99の可変長配列が使えるのでaとbには2次元配列を使います.
#include <stdio.h>
#include "cnumlib.h"
int main(void)
{
double a[3][3] = {
{ 0.2, -0.32, -0.8 },
{ -0.11, 0.81, -0.92 },
{ -0.93, 0.37, -0.29 } };
double b[] = { -0.3727, 0.4319, -1.4247 };
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;
dgesv(n, nrhs, lda, a, ipiv, ldb, (double (*)[ldb])b, &info);
printf("x = %f %f %f\n", b[0], b[1], b[2]);
printf("info = %d\n", info);
return 0;
}
Cプログラム例 (例題(1), LAPACKE 行優先)
LAPACKEでは第1パラメータで行優先の配列を使うことを指定できます. これにより行列の記述を数学表記と同じにすることができます. 内部処理としては, 計算開始前に配列の転置を行い, 計算終了後に再び転置をします. ldb = 1 となっていることに注意してください. これは, aだけでなくbも転置処理を行う仕様になっており, bとしては横ベクトルの入力を期待されているからです.
#include <stdio.h>
#include "lapacke.h"
int main(void)
{
double a[3][3] = {
{ 0.2, -0.11, -0.93 },
{ -0.32, 0.81, 0.37 },
{ -0.8, -0.92, -0.29 } };
double b[] = { -0.3727, 0.4319, -1.4247 };
int n = 3, nrhs = 1, lda = 3, ldb = 1, ipiv[3], info;
info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, nrhs, (double *)a, lda, ipiv, b, ldb);
printf("x = %f %f %f\n", b[0], b[1], b[2]);
printf("info = %d\n", info);
return 0;
}
C++プログラム例 (例題(1))
ヘッダーファイルは cnumlib (XLPack Liteでは cnumlib_lite) を使うことができます(info引数に注意). 行列はClangの場合でも一次元配列に入れます.
#include <iostream>
#include "cnumlib"
using namespace std;
int main(void)
{
double a[3][3] = {
{ 0.2, -0.32, -0.8 },
{ -0.11, 0.81, -0.92 },
{ -0.93, 0.37, -0.29 } };
double b[] = { -0.3727, 0.4319, -1.4247 };
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;
dgesv(n, nrhs, lda, (double *)a, ipiv, ldb, b, info);
cout << "x = " << b[0] << ", " << b[1] << ", " << b[2] << endl;
cout << "info = " << info << endl;
return 0;
}
Cプログラム例 (例題(2))
例題(2)ではf(x)の積分をqk15を使って求めます. qk15はf(x)を定義する外部関数を必要とします. 外部関数はCで作成することができ, qk15は必要なときにそれを呼び出します.
#include <stdio.h>
#include "cnumlib.h"
double f(double x)
{
return 1/(1 + x*x);
}
void test_qk15()
{
double a, b, result, abserr, resabs, resasc;
a = 0; b = 4;
qk15(f, a, b, &result, &abserr, &resabs, &resasc);
printf("result = %g, abserr = %g\n", result, abserr);
}
実行結果
result = 1.32582, abserr = 0.00148272