# 15. Calling XLPack functions from C/C++

### Introduction

C/C++ program can call numerical calculation modules of XLPack (or XLPack Lite) through XLPack API (C interface). Please refer to the reference manual for the detail of specifications of C API functions. Please also refer to the sample programs included in the XLPack SDK. Only the major technical points of using API are described here.

### Solving system of linear equations by C/C++ program

Example: Solve the following system of linear equations.

```  Ax = b
( 10  -7   0 )       ( 7 )
where, A = ( -3   2   6 ),  b = ( 4 )
(  5  -1   5 )       ( 6 )```

The following C program solves the above equations (Visual C is used).

``````#include <stdio.h>
#include "cnumlib.h"

int main(void)
{
double a[9] = { 10.0, -3.0, 5.0, -7.0, 2.0, -1.0, 0.0, 6.0, 5.0 };
double b[3] = { 7.0, 4.0, 6.0 };
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;

dgesv(n, nrhs, lda, a, ipiv, ldb, b, &info);
printf("info = %d\n", info);
printf("x = %f  %f  %f\n", b[0], b[1], b[2]);
return 0;
}``````

• The header file cnumlib.h ( cnumlib_lite.h for XLPack Lite) is used
• XLPack.lib (XLPack_32.lib for 32 bit programs) must be linked (XLPack_Lite.lib (XLPack_Lite_32.lib for 32 bit programs) for XLPack Lite)
• A matrix must be stored in one-dimensional array in column major order (same as VBA and Fortran). If it is stored in the two-dimensional array, use type casting.

Result

``````info = 0
x = 0.000000  -1.000000  1.000000``````

Variable-length two-dimensional array is used for the matrix instead of one-dimensional array for Clang compiler (Windows LLVM Clang and macOS Xcode) which supports C99 standard. In that case, the program is as follows.

``````#include <stdio.h>
#include "cnumlib.h"

int main(void)
{
double a[3][3], b[3];
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[10], info;

a[0][0] = 10.0; a[1][0] = -7.0; a[2][0] = 0.0;
a[0][1] = -3.0; a[1][1] = 2.0;  a[2][1] = 6.0;
a[0][2] = 5.0;  a[1][2] = -1.0; a[2][2] = 5.0;
b[0] = 7.0;
b[1] = 4.0;
b[2] = 6.0;

dgesv(n, nrhs, lda, a, ipiv, ldb, (double (*)[ldb])b, &info);
printf("info = %d\n", info);
printf("x = %f  %f  %f\n", b[0], b[1], b[2]);
return 0;
}``````

Please note that the notation of matrix in the reference manual follows the latter (Clang, variable-length two-dimensional array). Please replace it to the one-dimensional array in the case of Visual C.
Example – “double a[][lda]” in the manual must be read as “double a[]”.

Please note the following points in the case of C++.

• cnumlib (cnumlib_lite for XLPack Lite) may be used as the header file
• Same library as C language must be linked
• A matrix must be stored in one-dimensional array even in the case of Clang (or use type cast)

### Complex number in C/C++ program

Please note the following points when using complex numbers.

• A data type of complex number is written as doublecomplex in the manual. However, _Dcomplex (Visual C), double _Complex (Clang) or complex<double> (C++) is used for an actual program
• To make up for lack of complex operators in Visual C, complex arithmetic functions in category A4 are provided
• XLPack functions which return complex function value are not supported in C++ (such as zdotu, cgam, etc.). For those functions, the alternative subroutines are provided (such as zdotu_sub, cgam_sub, etc.)

Example: Solve the following complex system of linear equations.

```  Ax = b
(  1.66+0.6i   0.44-0.11i    0.82-0.56i )       (  0.9774-0.6426i )
where, A = (  0.47+i      1.23-0.47i   -1.72+0.07i ),  b = ( -0.0860+1.3628i )
( -1.32-0.61i  1.42-0.4i     1.62+0.41i )       ( -0.6599-0.6625i ) ```

The following C program solves the above complex equations (Visual C is used).

``````#include <stdio.h>
#include <complex.h>
#include "cnumlib.h"

int main(void)
{
_Dcomplex a[9] = {
cmplx(1.66, 0.6), cmplx(0.47, 1.0), cmplx(-1.32, -0.61),
cmplx(0.44, -0.11), cmplx(1.23, -0.47), cmplx(1.42, -0.4),
cmplx(0.82, -0.56), cmplx(-1.72, 0.07), cmplx(1.62, 0.41) };
_Dcomplex b[3] = {
cmplx(0.9774, -0.6426), cmplx(-0.086, 1.3628), cmplx(-0.6599, -0.6625) };
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;

zgesv(n, nrhs, lda, a, ipiv, ldb, b, &info);
printf("info = %d\n", info);
printf("x = ");
printf("(%f, %f) ", creal(b[0]), cimag(b[0]));
printf("(%f, %f) ", creal(b[1]), cimag(b[1]));
printf("(%f, %f)\n", creal(b[2]), cimag(b[2]));
return 0;
}``````

Result

``````info = 0
x = (0.590000, -0.280000) (-0.200000, -0.040000) (0.240000, -0.490000)``````

The following is the equivalent C++ program.

``````#include <iostream>
#include <complex>
#include "cnumlib"

using namespace std;

int main(void)
{
complex<double> a[3][3], b[3], i(0.0, 1.0);
int n = 3, nrhs = 1, lda = 3, ldb = 3, ipiv[3], info;

a[0][0] = 1.66+0.6*i;   a[1][0] = 0.44-0.11*i; a[2][0] = 0.82-0.56*i;
a[0][1] = 0.47+i;       a[1][1] = 1.23-0.47*i; a[2][1] = -1.72+0.07*i;
a[0][2] = -1.32-0.61*i; a[1][2] = 1.42-0.4*i;  a[2][2] = 1.62+0.41*i;
b[0] = 0.9774-0.6426*i;
b[1] = -0.086+1.3628*i;
b[2] = -0.6599-0.6625*i;

zgesv(n, nrhs, lda, (complex<double> *)a, ipiv, ldb, b, info);
cout << "info = " << info << endl;
cout << "x = " << b[0] << " " << b[1]  << " "  << b[2] << endl;
return 0;
}``````

Result

``````info = 0
x = (0.59,-0.28) (-0.2,-0.04) (0.24,-0.49)``````
Top