1d86ed7fbStbbdev /*
2*b15aabb3Stbbdev Copyright (c) 2005-2021 Intel Corporation
3d86ed7fbStbbdev
4d86ed7fbStbbdev Licensed under the Apache License, Version 2.0 (the "License");
5d86ed7fbStbbdev you may not use this file except in compliance with the License.
6d86ed7fbStbbdev You may obtain a copy of the License at
7d86ed7fbStbbdev
8d86ed7fbStbbdev http://www.apache.org/licenses/LICENSE-2.0
9d86ed7fbStbbdev
10d86ed7fbStbbdev Unless required by applicable law or agreed to in writing, software
11d86ed7fbStbbdev distributed under the License is distributed on an "AS IS" BASIS,
12d86ed7fbStbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86ed7fbStbbdev See the License for the specific language governing permissions and
14d86ed7fbStbbdev limitations under the License.
15d86ed7fbStbbdev */
16d86ed7fbStbbdev
17d86ed7fbStbbdev #include <cstdio>
18d86ed7fbStbbdev #include <cassert>
19d86ed7fbStbbdev #include <cstring>
20d86ed7fbStbbdev #include <cstdlib>
21d86ed7fbStbbdev
22d86ed7fbStbbdev #include <mkl_cblas.h>
23d86ed7fbStbbdev
posdef_gen(double * A,int n)24d86ed7fbStbbdev static void posdef_gen(double *A, int n) {
25d86ed7fbStbbdev /* Allocate memory for the matrix and its transpose */
26d86ed7fbStbbdev double *L = (double *)calloc(sizeof(double), n * n);
27d86ed7fbStbbdev assert(L);
28d86ed7fbStbbdev
29d86ed7fbStbbdev double *LT = (double *)calloc(sizeof(double), n * n);
30d86ed7fbStbbdev assert(LT);
31d86ed7fbStbbdev
32d86ed7fbStbbdev memset(A, 0, sizeof(double) * n * n);
33d86ed7fbStbbdev
34d86ed7fbStbbdev /* Generate a conditioned matrix and fill it with random numbers */
35d86ed7fbStbbdev for (int j = 0; j < n; ++j) {
36d86ed7fbStbbdev for (int k = 0; k < j; ++k) {
37d86ed7fbStbbdev // The initial value has to be between [0,1].
38d86ed7fbStbbdev L[k * n + j] =
39d86ed7fbStbbdev (((j * k) / ((double)(j + 1)) / ((double)(k + 2)) * 2.0) - 1.0) / ((double)n);
40d86ed7fbStbbdev }
41d86ed7fbStbbdev
42d86ed7fbStbbdev L[j * n + j] = 1;
43d86ed7fbStbbdev }
44d86ed7fbStbbdev
45d86ed7fbStbbdev /* Compute transpose of the matrix */
46d86ed7fbStbbdev for (int i = 0; i < n; ++i) {
47d86ed7fbStbbdev for (int j = 0; j < n; ++j) {
48d86ed7fbStbbdev LT[j * n + i] = L[i * n + j];
49d86ed7fbStbbdev }
50d86ed7fbStbbdev }
51d86ed7fbStbbdev cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, 1, L, n, LT, n, 0, A, n);
52d86ed7fbStbbdev
53d86ed7fbStbbdev free(L);
54d86ed7fbStbbdev free(LT);
55d86ed7fbStbbdev }
56d86ed7fbStbbdev
57d86ed7fbStbbdev // Read the matrix from the input file
matrix_init(double * & A,int & n,const char * fname)58d86ed7fbStbbdev void matrix_init(double *&A, int &n, const char *fname) {
59d86ed7fbStbbdev if (fname) {
60d86ed7fbStbbdev int i;
61d86ed7fbStbbdev int j;
62d86ed7fbStbbdev FILE *fp;
63d86ed7fbStbbdev
64d86ed7fbStbbdev fp = fopen(fname, "r");
65d86ed7fbStbbdev if (fp == nullptr) {
66d86ed7fbStbbdev fprintf(stderr, "\nFile does not exist\n");
67d86ed7fbStbbdev std::exit(0);
68d86ed7fbStbbdev }
69d86ed7fbStbbdev if (fscanf(fp, "%d", &n) <= 0) {
70d86ed7fbStbbdev fprintf(stderr, "\nCouldn't read n from %s\n", fname);
71d86ed7fbStbbdev std::exit(-1);
72d86ed7fbStbbdev }
73d86ed7fbStbbdev A = (double *)calloc(sizeof(double), n * n);
74d86ed7fbStbbdev for (i = 0; i < n; ++i) {
75d86ed7fbStbbdev for (j = 0; j <= i; ++j) {
76d86ed7fbStbbdev if (fscanf(fp, "%lf ", &A[i * n + j]) <= 0) {
77d86ed7fbStbbdev fprintf(stderr, "\nMatrix size incorrect %i %i\n", i, j);
78d86ed7fbStbbdev std::exit(-1);
79d86ed7fbStbbdev }
80d86ed7fbStbbdev if (i != j) {
81d86ed7fbStbbdev A[j * n + i] = A[i * n + j];
82d86ed7fbStbbdev }
83d86ed7fbStbbdev }
84d86ed7fbStbbdev }
85d86ed7fbStbbdev fclose(fp);
86d86ed7fbStbbdev }
87d86ed7fbStbbdev else {
88d86ed7fbStbbdev A = (double *)calloc(sizeof(double), n * n);
89d86ed7fbStbbdev posdef_gen(A, n);
90d86ed7fbStbbdev }
91d86ed7fbStbbdev }
92d86ed7fbStbbdev
93d86ed7fbStbbdev // write matrix to file
matrix_write(double * A,int n,const char * fname,bool is_triangular=false)94d86ed7fbStbbdev void matrix_write(double *A, int n, const char *fname, bool is_triangular = false) {
95d86ed7fbStbbdev if (fname) {
96d86ed7fbStbbdev int i = 0;
97d86ed7fbStbbdev int j = 0;
98d86ed7fbStbbdev FILE *fp = nullptr;
99d86ed7fbStbbdev
100d86ed7fbStbbdev fp = fopen(fname, "w");
101d86ed7fbStbbdev if (fp == nullptr) {
102d86ed7fbStbbdev fprintf(stderr, "\nCould not open file %s for writing.\n", fname);
103d86ed7fbStbbdev std::exit(0);
104d86ed7fbStbbdev }
105d86ed7fbStbbdev fprintf(fp, "%d\n", n);
106d86ed7fbStbbdev for (i = 0; i < n; ++i) {
107d86ed7fbStbbdev for (j = 0; j <= i; ++j) {
108d86ed7fbStbbdev fprintf(fp, "%lf ", A[j * n + i]);
109d86ed7fbStbbdev }
110d86ed7fbStbbdev if (!is_triangular) {
111d86ed7fbStbbdev for (; j < n; ++j) {
112d86ed7fbStbbdev fprintf(fp, "%lf ", A[i * n + j]);
113d86ed7fbStbbdev }
114d86ed7fbStbbdev }
115d86ed7fbStbbdev else {
116d86ed7fbStbbdev for (; j < n; ++j) {
117d86ed7fbStbbdev fprintf(fp, "%lf ", 0.0);
118d86ed7fbStbbdev }
119d86ed7fbStbbdev }
120d86ed7fbStbbdev fprintf(fp, "\n");
121d86ed7fbStbbdev }
122d86ed7fbStbbdev if (is_triangular) {
123d86ed7fbStbbdev fprintf(fp, "\n");
124d86ed7fbStbbdev for (i = 0; i < n; ++i) {
125d86ed7fbStbbdev for (j = 0; j < i; ++j) {
126d86ed7fbStbbdev fprintf(fp, "%lf ", 0.0);
127d86ed7fbStbbdev }
128d86ed7fbStbbdev for (; j < n; ++j) {
129d86ed7fbStbbdev fprintf(fp, "%lf ", A[i * n + j]);
130d86ed7fbStbbdev }
131d86ed7fbStbbdev fprintf(fp, "\n");
132d86ed7fbStbbdev }
133d86ed7fbStbbdev }
134d86ed7fbStbbdev fclose(fp);
135d86ed7fbStbbdev }
136d86ed7fbStbbdev }
137