Apollo  6.0
Open source self driving car software
matrix_operations.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2017 The Apollo Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 
22 #pragma once
23 
24 #include <cmath>
25 #include <utility>
26 #include <vector>
27 
28 #include "Eigen/Dense"
29 #include "Eigen/SVD"
30 
31 #include "cyber/common/log.h"
32 
37 namespace apollo {
38 namespace common {
39 namespace math {
40 
50 template <typename T, unsigned int N>
51 Eigen::Matrix<T, N, N> PseudoInverse(const Eigen::Matrix<T, N, N> &m,
52  const double epsilon = 1.0e-6) {
53  Eigen::JacobiSVD<Eigen::Matrix<T, N, N>> svd(
54  m, Eigen::ComputeFullU | Eigen::ComputeFullV);
55  return static_cast<Eigen::Matrix<T, N, N>>(
56  svd.matrixV() *
57  (svd.singularValues().array().abs() > epsilon)
58  .select(svd.singularValues().array().inverse(), 0)
59  .matrix()
60  .asDiagonal() *
61  svd.matrixU().adjoint());
62 }
63 
73 template <typename T, unsigned int M, unsigned int N>
74 Eigen::Matrix<T, N, M> PseudoInverse(const Eigen::Matrix<T, M, N> &m,
75  const double epsilon = 1.0e-6) {
76  Eigen::Matrix<T, M, M> t = m * m.transpose();
77  return static_cast<Eigen::Matrix<T, N, M>>(m.transpose() *
78  PseudoInverse<T, M>(t));
79 }
80 
97 template <typename T, unsigned int L, unsigned int N, unsigned int O>
98 bool ContinuousToDiscrete(const Eigen::Matrix<T, L, L> &m_a,
99  const Eigen::Matrix<T, L, N> &m_b,
100  const Eigen::Matrix<T, O, L> &m_c,
101  const Eigen::Matrix<T, O, N> &m_d, const double ts,
102  Eigen::Matrix<T, L, L> *ptr_a_d,
103  Eigen::Matrix<T, L, N> *ptr_b_d,
104  Eigen::Matrix<T, O, L> *ptr_c_d,
105  Eigen::Matrix<T, O, N> *ptr_d_d) {
106  if (ts <= 0.0) {
107  AERROR << "ContinuousToDiscrete : ts is less than or equal to zero";
108  return false;
109  }
110 
111  // Only matrix_a is mandatory to be non-zeros in matrix
112  // conversion.
113  if (m_a.rows() == 0) {
114  AERROR << "ContinuousToDiscrete: matrix_a size 0 ";
115  return false;
116  }
117 
118  Eigen::Matrix<T, L, L> m_identity = Eigen::Matrix<T, L, L>::Identity();
119  *ptr_a_d = PseudoInverse<T, L>(m_identity - ts * 0.5 * m_a) *
120  (m_identity + ts * 0.5 * m_a);
121 
122  *ptr_b_d =
123  std::sqrt(ts) * PseudoInverse<T, L>(m_identity - ts * 0.5 * m_a) * m_b;
124 
125  *ptr_c_d =
126  std::sqrt(ts) * m_c * PseudoInverse<T, L>(m_identity - ts * 0.5 * m_a);
127 
128  *ptr_d_d =
129  0.5 * m_c * PseudoInverse<T, L>(m_identity - ts * 0.5 * m_a) * m_b + m_d;
130 
131  return true;
132 }
133 
134 bool ContinuousToDiscrete(const Eigen::MatrixXd &m_a,
135  const Eigen::MatrixXd &m_b,
136  const Eigen::MatrixXd &m_c,
137  const Eigen::MatrixXd &m_d, const double ts,
138  Eigen::MatrixXd *ptr_a_d, Eigen::MatrixXd *ptr_b_d,
139  Eigen::MatrixXd *ptr_c_d, Eigen::MatrixXd *ptr_d_d);
140 
141 template <typename T, int M, int N, typename D>
142 void DenseToCSCMatrix(const Eigen::Matrix<T, M, N> &dense_matrix,
143  std::vector<T> *data, std::vector<D> *indices,
144  std::vector<D> *indptr) {
145  static constexpr double epsilon = 1e-9;
146  int data_count = 0;
147  for (int c = 0; c < dense_matrix.cols(); ++c) {
148  indptr->emplace_back(data_count);
149  for (int r = 0; r < dense_matrix.rows(); ++r) {
150  if (std::fabs(dense_matrix(r, c)) < epsilon) {
151  continue;
152  }
153  data->emplace_back(dense_matrix(r, c));
154  ++data_count;
155  indices->emplace_back(r);
156  }
157  }
158  indptr->emplace_back(data_count);
159 }
160 
161 } // namespace math
162 } // namespace common
163 } // namespace apollo
Eigen::Matrix< T, N, N > PseudoInverse(const Eigen::Matrix< T, N, N > &m, const double epsilon=1.0e-6)
Computes the Moore-Penrose pseudo-inverse of a given square matrix, rounding all eigenvalues with abs...
Definition: matrix_operations.h:51
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
bool ContinuousToDiscrete(const Eigen::Matrix< T, L, L > &m_a, const Eigen::Matrix< T, L, N > &m_b, const Eigen::Matrix< T, O, L > &m_c, const Eigen::Matrix< T, O, N > &m_d, const double ts, Eigen::Matrix< T, L, L > *ptr_a_d, Eigen::Matrix< T, L, N > *ptr_b_d, Eigen::Matrix< T, O, L > *ptr_c_d, Eigen::Matrix< T, O, N > *ptr_d_d)
Computes bilinear transformation of the continuous to discrete form for state space representation Th...
Definition: matrix_operations.h:98
void DenseToCSCMatrix(const Eigen::Matrix< T, M, N > &dense_matrix, std::vector< T > *data, std::vector< D > *indices, std::vector< D > *indptr)
Definition: matrix_operations.h:142
#define AERROR
Definition: log.h:44