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
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
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
float float & c
Definition Utils.h:111
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"