Project
Loading...
Searching...
No Matches
SymMatrixSolver.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
17
19#include "Framework/Logger.h"
20
21#include <iostream>
22#include <random>
23#include <iomanip>
24#include <chrono>
25
26using namespace o2::math_utils;
27
29{
30 // Upper Triangulization
31 for (int i = 0; i < mN; i++) {
32 double* rowI = &mA[i * mShift];
33 double* rowIb = &mA[i * mShift + mN];
34 double c = (std::fabs(rowI[i]) > 1.e-10) ? 1. / rowI[i] : 0.;
35 double* rowJ = rowI + mShift;
36 for (int j = i + 1; j < mN; j++, rowJ += mShift) { // row j
37 if (rowI[j] != 0.) {
38 double aij = c * rowI[j]; // A[i][j] / A[i][i]
39 for (int k = j; k < mShift; k++) {
40 rowJ[k] -= aij * rowI[k]; // A[j][k] -= A[i][k]/A[i][i]*A[j][i]
41 }
42 rowI[j] = aij; // A[i][j] /= A[i][i]
43 }
44 }
45 for (int k = 0; k < mM; k++) {
46 rowIb[k] *= c;
47 }
48 }
49 // Diagonalization
50 for (int i = mN - 1; i >= 0; i--) {
51 double* rowIb = &mA[i * mShift + mN];
52 double* rowJb = rowIb - mShift;
53 for (int j = i - 1; j >= 0; j--, rowJb -= mShift) { // row j
54 double aji = mA[j * mShift + i];
55 if (aji != 0.) {
56 for (int k = 0; k < mM; k++) {
57 rowJb[k] -= aji * rowIb[k];
58 }
59 }
60 }
61 }
62}
63
65{
66 for (int i = 0; i < mN; i++) {
67 LOG(info) << "";
68 for (int j = 0; j < mN; j++) {
69 LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << A(i, j) << " ";
70 }
71 LOG(info) << " | ";
72 for (int j = 0; j < mM; j++) {
73 LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << B(i, j) << " ";
74 }
75 }
76 LOG(info) << std::setprecision(-1);
77}
78
80{
81 constexpr int n = 30;
82 constexpr int d = 3;
83
84 // std::random_device rd; // Will be used to obtain a seed for the random
85 std::mt19937 gen(1); // Standard mersenne_twister_engine seeded with 1
86 std::uniform_real_distribution<> uniform(-.999, .999);
87
88 double maxDiff = 0.;
89 int nTries = 10000;
90
91 auto tmpTime = std::chrono::high_resolution_clock::now();
92 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(tmpTime - tmpTime);
93 auto durationMult = duration;
94
95 for (int iter = 0; iter < nTries; iter++) {
96
97 double x[n][d];
98 double A[n][n];
99 {
100 for (int i = 0; i < n; i++) {
101 for (int j = 0; j < d; j++) {
102 x[i][j] = 1. * uniform(gen);
103 }
104 }
105 for (int i = 0; i < n; i++) {
106 A[i][i] = fabs(2. + uniform(gen));
107 }
108 for (int i = 0; i < n; i++) {
109 for (int j = i + 1; j < n; j++) {
110 A[i][j] = A[i][i] * A[j][j] * uniform(gen);
111 A[j][i] = A[i][j];
112 }
113 }
114 for (int i = 0; i < n; i++) {
115 A[i][i] = A[i][i] * A[i][i];
116 }
117 if (prn && iter == nTries - 1) {
118 for (int i = 0; i < n; i++) {
119 LOG(info) << "";
120 for (int j = 0; j < n; j++) {
121 LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << A[i][j] << " ";
122 }
123 }
124 LOG(info) << "";
125 }
126 }
127 double b[n][d];
128 auto startMult = std::chrono::high_resolution_clock::now();
129 for (int i = 0; i < n; i++) {
130 for (int k = 0; k < d; k++) {
131 b[i][k] = 0.;
132 }
133 for (int j = 0; j < n; j++) {
134 for (int k = 0; k < d; k++) {
135 b[i][k] += x[j][k] * A[i][j];
136 }
137 }
138 }
139 auto stopMult = std::chrono::high_resolution_clock::now();
140 durationMult += std::chrono::duration_cast<std::chrono::nanoseconds>(stopMult - startMult);
141
142 SymMatrixSolver sym(n, d);
143
144 for (int i = 0; i < n; i++) {
145 for (int k = 0; k < d; k++) {
146 sym.B(i, k) = b[i][k];
147 }
148 for (int j = i; j < n; j++) {
149 sym.A(i, j) = A[i][j];
150 }
151 }
152
153 auto start = std::chrono::high_resolution_clock::now();
154 sym.solve();
155 auto stop = std::chrono::high_resolution_clock::now();
156 duration += std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
157
158 double diff = 0.;
159 for (int i = 0; i < n; i++) {
160 for (int k = 0; k < d; k++) {
161 double t = std::fabs(x[i][k] - sym.B(i, k));
162 if (diff < t) {
163 diff = t;
164 }
165 }
166 }
167 if (maxDiff < diff) {
168 maxDiff = diff;
169 }
170 // LOG(info) << std::defaultfloat ;
171 // LOG(info) << "\n\n max diff " <<diff << "\n";
172 }
173
174 int ok = (maxDiff < 1.e-7);
175
176 if (prn || !ok) {
177 LOG(info) << std::defaultfloat;
178 LOG(info) << "\n\n Overall max diff " << maxDiff << "\n";
179 LOG(info) << " time " << duration.count() / nTries;
180 LOG(info) << " time multiplication " << durationMult.count() / nTries;
181 }
182 return ok;
183}
Definition of SymMatrixSolver class.
default_random_engine gen(dev())
int32_t i
uint32_t j
Definition RawData.h:0
Definition A.h:16
Definition B.h:16
double & A(int i, int j)
access to A elements
double & B(int i, int j)
access to B elements
static int test(bool prn=0)
Test the class functionality. Returns 1 when ok, 0 when not ok.
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint start
Definition glcorearb.h:469
float float & c
Definition Utils.h:111
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"