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