/*******************************************************************************
* This file is part of SWIFT.
* Copyright (C) 2016 Bert Vandenbroucke (bert.vandenbroucke@gmail.com).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
******************************************************************************/
#include
/* Some standard headers. */
#include
#include
/* Local headers */
#include "const.h"
#include "dimension.h"
#include "error.h"
#include "tools.h"
void setup_matrix(float A[3][3]) {
A[0][0] = random_uniform(-1.0, 1.0);
A[0][1] = random_uniform(-1.0, 1.0);
A[0][2] = random_uniform(-1.0, 1.0);
A[1][0] = random_uniform(-1.0, 1.0);
A[1][1] = random_uniform(-1.0, 1.0);
A[1][2] = random_uniform(-1.0, 1.0);
A[2][0] = random_uniform(-1.0, 1.0);
A[2][1] = random_uniform(-1.0, 1.0);
A[2][2] = random_uniform(-1.0, 1.0);
}
int is_unit_matrix(float A[3][3]) {
int check = 1;
check &= (fabsf(A[0][0] - 1.0f) < 1.e-6f);
#if defined(HYDRO_DIMENSION_2D) && defined(HYDRO_DIMENSION_3D)
check &= (fabsf(A[0][1]) < 1.e-6f);
check &= (fabsf(A[1][0]) < 1.e-6f);
check &= (fabsf(A[1][1] - 1.0f) < 1.e-6f);
#if defined(HYDRO_DIMENSION_3D)
check &= (fabsf(A[0][2]) < 1.e-6f);
check &= (fabsf(A[1][2]) < 1.e-6f);
check &= (fabsf(A[2][0]) < 1.e-6f);
check &= (fabsf(A[2][1]) < 1.e-6f);
check &= (fabsf(A[2][2] - 1.0f) < 1.e-6f);
#endif // 3D
#endif // 2D and 3D
return check;
}
void print_matrix(float A[3][3], const char* s) {
message("Matrix %s:", s);
#if defined(HYDRO_DIMENSION_1D)
message("[%.3e]", A[0][0]);
#elif defined(HYDRO_DIMENSION_2D)
message("[%.3e, %.3e]", A[0][0], A[0][1]);
message("[%.3e, %.3e]", A[1][0], A[1][1]);
#elif defined(HYDRO_DIMENSION_3D)
message("[%.8e, %.8e, %.8e]", A[0][0], A[0][1], A[0][2]);
message("[%.8e, %.8e, %.8e]", A[1][0], A[1][1], A[1][2]);
message("[%.8e, %.8e, %.8e]", A[2][0], A[2][1], A[2][2]);
#endif
}
void multiply_matrices(float A[3][3], float B[3][3], float C[3][3]) {
#if defined(HYDRO_DIMENSION_1D)
C[0][0] = A[0][0] * B[0][0];
#elif defined(HYDRO_DIMENSION_2D)
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
C[i][j] = 0.0f;
for (int k = 0; k < 2; ++k) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
#elif defined(HYDRO_DIMENSION_3D)
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
C[i][j] = 0.0f;
for (int k = 0; k < 3; ++k) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
#endif
}
int main(int argc, char* argv[]) {
float A[3][3], B[3][3], C[3][3];
setup_matrix(A);
memcpy(B, A, 9 * sizeof(float));
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (A[i][j] != B[i][j]) {
error("Matrices not equal after copy!");
}
}
}
invert_dimension_by_dimension_matrix(A);
multiply_matrices(A, B, C);
if (!is_unit_matrix(C)) {
print_matrix(A, "A - Inverse matrix");
print_matrix(B, "B - Original matrix");
print_matrix(C, "C - Multiplication (should be unit matrix)");
error("Inverted matrix is wrong!");
}
return 0;
}