oILAB
Loading...
Searching...
No Matches
IntegerLattice.h
Go to the documentation of this file.
1/* This file is part of gbLAB.
2 *
3 * gbLAB is distributed without any warranty under the MIT License.
4 */
5
6
7#ifndef gbLAB_IntegerLattice_h_
8#define gbLAB_IntegerLattice_h_
9
10#include "../Math/DiophantineSolver.h"
11
12namespace oILAB {
17template <int dim> class IntegerLattice {
18 using IntScalarType = long long int;
19 using VectorDimI = Eigen::Matrix<IntScalarType, dim, 1>;
20 using MatrixDimI = Eigen::Matrix<IntScalarType, dim, dim>;
21
22public:
25
26 static Eigen::Matrix<IntScalarType, dim - 1, dim>
27 perpendicularDirections(const Eigen::Vector<IntScalarType, dim> &in) {
28 Eigen::Matrix<IntScalarType, dim - 1, dim> out =
29 Eigen::Matrix<IntScalarType, dim - 1, dim>::Zero();
30
31 int firstNonZero = 0;
32 for (int ind = 0; ind < dim; ind++) {
33 if (in(ind) != 0) {
34 firstNonZero = ind;
35 break;
36 } else {
37 out(ind, ind) = 1;
38 }
39 }
40
41 if (firstNonZero == dim - 1)
42 return out;
43
44 out(firstNonZero, firstNonZero) =
45 -in(firstNonZero + 1) /
46 IntegerMath<IntScalarType>::gcd(in(firstNonZero), in(firstNonZero + 1));
47 out(firstNonZero, firstNonZero + 1) =
48 in(firstNonZero) /
49 IntegerMath<IntScalarType>::gcd(in(firstNonZero), in(firstNonZero + 1));
50
51 for (int ind = firstNonZero + 2; ind < dim; ind++) {
52 if (in(ind) == 0) {
53 out.row(ind - 1) = Eigen::Vector<IntScalarType, dim>::Zero(dim);
54 out(ind - 1, ind) = 1;
55 continue;
56 }
57 Eigen::Vector<IntScalarType, 3> truncated_in;
58 truncated_in << in(ind - 2), in(ind - 1), in(ind);
59 // truncated_in=
60 // truncated_in/IntegerMath<IntScalarType>::gcd(truncated_in);
61
62 IntScalarType x, y;
64 truncated_in(0), truncated_in(1),
65 -truncated_in(2) *
66 IntegerMath<IntScalarType>::gcd(truncated_in(0), truncated_in(1)),
67 x, y);
68
69 out(ind - 1, ind) =
70 IntegerMath<IntScalarType>::gcd(truncated_in(0), truncated_in(1));
71 out(ind - 1, ind - 2) = x;
72 out(ind - 1, ind - 1) = y;
73
74 out.row(ind - 1) =
75 out.row(ind - 1) / IntegerMath<IntScalarType>::gcd(out.row(ind - 1));
76 }
77 return out;
78 }
79 };
80 } // namespace oILAB
81#endif
static void solveDiophantine2vars(IntScalarType a, IntScalarType b, IntScalarType c, IntScalarType &x, IntScalarType &y)
long long int IntScalarType
Eigen::Matrix< IntScalarType, dim, 1 > VectorDimI
static Eigen::Matrix< IntScalarType, dim - 1, dim > perpendicularDirections(const Eigen::Vector< IntScalarType, dim > &in)
const MatrixDimI latticeBasis
Eigen::Matrix< IntScalarType, dim, dim > MatrixDimI
static IntScalarType gcd(const IntScalarType &a, const IntScalarType &b)
Definition IntegerMath.h:26