XLPack API: C/C++ example programs

C example program (Example (1), Visual C)

This is the example using Visual C (Visual Studio (Windows version)). Note that matrices are stored in column-major order (same with VBA and Fortran, rows and columns are opposite to the C/C++ storage order).
One dimensional array is used for a and b (In the reference manual, the variable length two dimensional array is used like Clang example below. However, please read with replacing it to one dimensional array in the case of 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;
}

Result

x = 0.860000  0.640000  0.510000
info = 0

C example program (Example (1), Clang)

Two dimensional arrays are used for both a and b since Clang suports the variable length array which is standardized in C99.

#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 example program (Example (1), LAPACKE Row-major)

It is possible to specify to use the row-major order array by the first parameter of LAPACKE routine. Using this feature, a matrix can be coded in the same order with mathematical notation. Internally, arrays are transposed before computation and transposed again after computation. Note that ldb = 1. This is because the horizontal vector is expected as the input b since not only a but also b is transposed.

#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++ example program (Example (1))

cnumlib (cnumlib_lite for XLPack Lite) header file can be used (note that "info" argument is used instead of "&info"). One dimensional array is used for matrices even if Clang is used to compile.

#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 example program (Example (2))

In Example (2), the integral of f(x) is computed using qk15. qk15 requires the external function defining f(x). It can be coded in C and qk15 will call it when necessary.

#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

result = 1.32582, abserr = 0.00148272