YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_lapack.c
Go to the documentation of this file.
1// Copyright (c) 2026 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <math.h>
6#include <stdio.h>
7#include <stdlib.h>
8
9#include "tests.h"
11
17static int utest_nearly_equal(double a, double b, double tol) {
18 return fabs(a - b) <= tol;
19}
20
21static void utest_check_identity_2x2(
22 double const a_col_major[4], double const inv_col_major[4],
23 double tol, char const * test_name) {
24
25 // C = A * A^{-1} in column-major layout
26 double c[4] = {
27 a_col_major[0] * inv_col_major[0] + a_col_major[2] * inv_col_major[1],
28 a_col_major[1] * inv_col_major[0] + a_col_major[3] * inv_col_major[1],
29 a_col_major[0] * inv_col_major[2] + a_col_major[2] * inv_col_major[3],
30 a_col_major[1] * inv_col_major[2] + a_col_major[3] * inv_col_major[3]
31 };
32
33 if (!utest_nearly_equal(c[0], 1.0, tol) ||
34 !utest_nearly_equal(c[1], 0.0, tol) ||
35 !utest_nearly_equal(c[2], 0.0, tol) ||
36 !utest_nearly_equal(c[3], 1.0, tol)) {
37 PUT_ERR_F("ERROR in %s: A*Ainv != I", test_name);
38 }
39}
40
41static void utest_symmetrise_from_upper_2x2(double a_col_major[4]) {
42
43 a_col_major[1] = a_col_major[2];
44}
45
46int main(void) {
47
48 puts("----- yac_lapack_interface basic tests -----");
49
50 {
51 // A = [[4,2],[1,3]], x_ref = [1,2], b = A*x_ref = [8,7]
52 double a[4] = {4.0, 1.0, 2.0, 3.0};
53 double b[2] = {8.0, 7.0};
54 lapack_int ipiv[2];
55
56 lapack_int info =
57 LAPACKE_dgesv(LAPACK_COL_MAJOR, 2, 1, a, 2, ipiv, b, 2);
58
59 if (info != 0) PUT_ERR_F("ERROR in LAPACKE_dgesv: info=%d", (int)info);
60
61 if (!utest_nearly_equal(b[0], 1.0, 1e-12) ||
62 !utest_nearly_equal(b[1], 2.0, 1e-12))
64 "ERROR in LAPACKE_dgesv: wrong solution [%1.16e, %1.16e]", b[0], b[1]);
65 }
66
67 {
68 double a_ref[4] = {4.0, 1.0, 2.0, 3.0};
69 double a_inv[4] = {4.0, 1.0, 2.0, 3.0};
70 lapack_int ipiv[2];
71 double work[16];
72
73 lapack_int info = LAPACKE_dgetrf(LAPACK_COL_MAJOR, 2, 2, a_inv, 2, ipiv);
74
75 if (info != 0) PUT_ERR_F("ERROR in LAPACKE_dgetrf: info=%d", (int)info);
76
77 if (info == 0) {
78 info = LAPACKE_dgetri_work(
79 LAPACK_COL_MAJOR, 2, a_inv, 2, ipiv, work, 16);
80 if (info != 0)
81 PUT_ERR_F("ERROR in LAPACKE_dgetri_work: info=%d", (int)info);
82 }
83
84 if (info == 0) utest_check_identity_2x2(a_ref, a_inv, 1e-12, "dgetrf+dgetri");
85 }
86
87#ifndef YAC_LAPACK_NO_DSYTR
88 {
89 // symmetric matrix A = [[4,1],[1,3]]
90 double a_ref[4] = {4.0, 1.0, 1.0, 3.0};
91 double a_inv[4] = {4.0, 1.0, 1.0, 3.0};
92 lapack_int ipiv[2];
93 double work[16];
94
95 lapack_int info =
96 LAPACKE_dsytrf_work(LAPACK_COL_MAJOR, 'U', 2, a_inv, 2, ipiv, work, 16);
97
98 if (info != 0)
99 PUT_ERR_F("ERROR in LAPACKE_dsytrf_work: info=%d", (int)info);
100
101 if (info == 0) {
102 info = LAPACKE_dsytri_work(
103 LAPACK_COL_MAJOR, 'U', 2, a_inv, 2, ipiv, work);
104 if (info != 0)
105 PUT_ERR_F("ERROR in LAPACKE_dsytri_work: info=%d", (int)info);
106 }
107
108 if (info == 0) {
109 utest_symmetrise_from_upper_2x2(a_inv);
110 utest_check_identity_2x2(a_ref, a_inv, 1e-12, "dsytrf+dsytri");
111 }
112 }
113#endif
114
115 return TEST_EXIT_CODE;
116}
static double const tol
#define PUT_ERR_F(fmt,...)
Definition tests.h:11
#define TEST_EXIT_CODE
Definition tests.h:15
int info