carl  24.04
Computer ARithmetic Library
CharPol.h
Go to the documentation of this file.
1 /*
2  * File: CharPol.h
3  * Author: tobias
4  *
5  * Created on 13. Juni 2016, 14:34
6  */
7 
8 #pragma once
9 
10 #include <eigen3/Eigen/Core>
11 #include <cmath>
12 #include <vector>
13 
14 namespace carl {
15 
16 // allgorithm 8.11, p. 290
17 template<typename Coeff>
18 std::vector<Coeff> newtonSums(const std::vector<Coeff>& newtonSums) {
19  CARL_LOG_FUNC("carl.thom.tarski", "newtonSums = " << newtonSums);
20  CARL_LOG_ASSERT("carl.thom.tarski", newtonSums.size() >= 1, "newtonSums: invalid argument");
21  assert(newtonSums.size() > 0);
22  std::size_t p = newtonSums.size() - 1;
23  std::vector<Coeff> res(p + 1);
24  res[p] = Coeff(1);
25  for(std::size_t i = 1; i <= p; i++) {
26  Coeff sum(0);
27  for (std::size_t j = 1; j <= i; j++) {
28  sum += res[p - i + j] * newtonSums[j];
29  }
30  sum *= -(Coeff(1) / Coeff(i));
31  res[p-i] = sum;
32  }
33  return res;
34 }
35 
36 template<typename Coeff>
37 using CoeffMatrix = Eigen::Matrix<Coeff, Eigen::Dynamic, Eigen::Dynamic>;
38 
39 template<typename Coeff>
41  for (Eigen::Index i = 0; i < m.rows(); i++) {
42  for (Eigen::Index j = 0; j < m.cols(); j++) {
43  std::cout << m(i, j) << "\t";
44  }
45  std::cout << std::endl;
46  }
47 }
48 
49 // algorithm 8.17, p. 300
50 template<typename Coeff>
51 std::vector<Coeff> charPol(const CoeffMatrix<Coeff>& m) {
52  CARL_LOG_FUNC("carl.thom.tarski", "");
53  Eigen::Index n = m.cols();
54  CARL_LOG_ASSERT("carl.thom.tarski", n == m.rows(), "can only compute characteristic polynomial of square matrix");
55  CARL_LOG_INFO("carl.thom.tarski", "input has size " << n << "x" << n);
56 
57  // calculate r
58  std::size_t r = static_cast<std::size_t>(std::ceil(std::sqrt(n)));
59  if (r*r == std::size_t(n)) r++; // if n is a square number
60 
62 
63  std::vector<CoeffMatrix<Coeff>> B;
64  std::vector<Coeff> N((r * r), Coeff(0));
65  B.push_back(id);
66  N[0] = static_cast<Coeff>(n);
67  for(std::size_t i = 0; i < r - 1; i++) {
68  B.push_back(m * B.back());
69  N[i+1] = B.back().trace();
70  //printMatrix(B.back());
71  }
72 
73  std::vector<CoeffMatrix<Coeff>> C;
74  C.push_back(m * B.back());
75  N[r] = C.back().trace();
76  for(std::size_t j = 1; j < r - 1; j++) {
77  C.push_back(C.front() * C.back());
78  N[(j + 1) * r] = C.back().trace();
79  //printMatrix(C.back());
80  }
81 
82  for(std::size_t i = 1; i < r; i++) {
83  for(std::size_t j = 1; j < r; j++) {
84  CoeffMatrix<Coeff> tmp(B[i] * C[j-1]);
85  N[j*r + i] = tmp.trace();
86  }
87  }
88  N.resize(std::size_t(n) + 1);
89  std::vector<Coeff> res = newtonSums(N);
90  CARL_LOG_INFO("carl.thom.tarski", "done computing the char pol ... ");
91  return res;
92 }
93 
94 } // namespace carl
#define CARL_LOG_FUNC(channel, args)
Definition: carl-logging.h:46
#define CARL_LOG_ASSERT(channel, condition, msg)
Definition: carl-logging.h:47
#define CARL_LOG_INFO(channel, msg)
Definition: carl-logging.h:42
carl is the main namespace for the library.
Interval< Number > ceil(const Interval< Number > &_in)
Method which returns the next larger integer of the passed number or the number itself,...
Definition: Interval.h:1535
void printMatrix(const CoeffMatrix< Coeff > &m)
Definition: CharPol.h:40
Eigen::Matrix< Coeff, Eigen::Dynamic, Eigen::Dynamic > CoeffMatrix
Definition: CharPol.h:37
std::vector< Coeff > newtonSums(const std::vector< Coeff > &newtonSums)
Definition: CharPol.h:18
Interval< Number > sqrt(const Interval< Number > &i)
Definition: Power.h:51
typename UnderlyingNumberType< P >::type Coeff
std::vector< Coeff > charPol(const CoeffMatrix< Coeff > &m)
Definition: CharPol.h:51