105 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> matrixA;
106 Eigen::Matrix<IntScalarType, Eigen::Dynamic, 1> tempx;
107 matrixA.resize(1, 1);
110 for (
int i = 0; i < dim - 1; i++) {
111 matrixA.conservativeResize(i + 1, i + 2);
114 Eigen::Vector<IntScalarType, Eigen::Dynamic>::Zero(i + 1);
116 matrixA(0, i + 1) = a(i + 1);
117 tempx.conservativeResize(i + 2, 1);
122 matrixA.row(i) = tempx;
125 Eigen::Vector<IntScalarType, Eigen::Dynamic> det =
126 Eigen::Vector<IntScalarType, Eigen::Dynamic>::Zero(i + 2);
127 for (
int j = 0; j < i + 2; j++) {
128 Eigen::MatrixXd minor = Eigen::MatrixXd::Zero(i + 1, i + 1);
129 std::vector<IntScalarType> indicesToKeep(i + 2);
130 std::iota(std::begin(indicesToKeep), std::end(indicesToKeep), 0);
132 std::remove(indicesToKeep.begin(), indicesToKeep.end(), j),
133 indicesToKeep.end());
135 Eigen::Vector<IntScalarType, Eigen::Dynamic> indicesToKeepVector;
136 indicesToKeepVector =
137 Eigen::Map<Eigen::Vector<IntScalarType, Eigen::Dynamic>>(
138 indicesToKeep.data(), i + 1);
139 minor = matrixA(Eigen::indexing::all, indicesToKeepVector)
140 .template cast<double>();
141 det(j) = round(minor.determinant());
144 IntScalarType e =
gcd(det);
146 if (det == Eigen::Vector<IntScalarType, Eigen::Dynamic>::Zero(i + 2)) {
147 tempx = Eigen::Vector<IntScalarType, Eigen::Dynamic>::Zero(i + 2);
152 for (
int j = 0; j < i + 2; j++)
153 tempx(j) = pow(-1, j + 1) * det(j) / e;
155 matrixA.conservativeResize(dim, dim);
156 matrixA.row(dim - 1) = tempx;
158 return matrixA.block(1, 0, dim - 1, dim);
208 throw std::runtime_error(
"the size of arrays should be at least two");
210 throw std::runtime_error(
"No solution since the gcd is not 1 or -1.");
212 Eigen::Vector<IntScalarType, Eigen::Dynamic> u(n);
219 Eigen::Vector<IntScalarType, Eigen::Dynamic> na(n - 1);
221 na(Eigen::seq(1, n - 2)) = a(Eigen::seq(2, n - 1));
223 Eigen::Vector<IntScalarType, Eigen::Dynamic> k(n - 1);
234 u(Eigen::seq(2, n - 1)) = k(Eigen::seq(1, n - 2));
241 ccum(
const Eigen::MatrixBase<T> &qin)
246 Eigen::Vector<IntScalarType, Eigen::Dynamic> q(n);
251 throw std::runtime_error(
252 "Size of the input matrix for CCUM should be >1.");
253 if (abs(
gcd(qin)) != 1)
254 throw std::runtime_error(
255 "The absolute gcd of the input array is not 1.");
256 }
catch (std::runtime_error &e) {
257 std::cerr << e.what();
260 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> Q =
261 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic>::Identity(
265 bool swapFirst =
false;
266 int swapFirstElementWith;
268 int elementIndex = -1;
269 for (
auto element : q) {
273 IntScalarType temp = q(0);
275 q(elementIndex) = temp;
277 swapFirstElementWith = elementIndex;
284 int elementIndex = -1;
287 for (
const IntScalarType &element : q) {
289 if (elementIndex == 0)
291 if (!(q(0) == 0 && element == 0))
292 y =
gcd(q(0), element);
298 Q(1, 0) = Q(elementIndex, 0);
299 Q(elementIndex, 0) = temp;
308 Q.row(1).swap(Q.row(elementIndex));
311 Q.row(0).swap(Q.row(swapFirstElementWith));
317 if (!(q(0) == 0 && q(1) == 0))
324 IntScalarType alpha, beta;
326 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> M =
327 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic>::Identity(
329 M.block(0, 0, 2, 2) << u, v, -beta, alpha;
331 Eigen::Vector<IntScalarType, Eigen::Dynamic> t;
334 int swappedElementIndex;
335 bool swapped =
false;
336 for (IntScalarType &element : t) {
338 if (elementIndex < 2)
342 if (element % y != 0) {
344 int temp = t(elementIndex);
345 t(elementIndex) = t(1);
347 swappedElementIndex = elementIndex;
351 assert(elementIndex != t.size());
354 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> tempMatrix(n,
356 tempMatrix =
ccum(t);
361 tempMatrix.row(1).swap(tempMatrix.row(swappedElementIndex));
364 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> invM =
365 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic>::Identity(
367 invM.block(0, 0, 2, 2) << alpha, -v, beta, u;
368 Eigen::Matrix<IntScalarType, Eigen::Dynamic, Eigen::Dynamic> output(n, n);
369 output = invM * tempMatrix;
371 output.row(0).swap(output.row(swapFirstElementWith));
375 static std::deque<std::vector<IntScalarType>>
comb(
const int &n,
377 std::deque<std::vector<IntScalarType>> output;
378 std::string bitmask(k, 1);
379 bitmask.resize(n, 0);
383 std::vector<IntScalarType> kCombination(k);
386 for (
int i = 0; i < n; ++i)
389 kCombination[arrIndex] = (IntScalarType)i;
393 assert(arrIndex == k);
394 output.push_back(kCombination);
395 }
while (std::prev_permutation(bitmask.begin(), bitmask.end()));