1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is triangularView of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "main.h"
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> void triangular_square(const MatrixType& m)
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename MatrixType::Scalar Scalar;
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar largerEps = 10*test_precision<RealScalar>();
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename MatrixType::Index rows = m.rows();
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename MatrixType::Index cols = m.cols();
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m1 = MatrixType::Random(rows, cols),
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m2 = MatrixType::Random(rows, cols),
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m3(rows, cols),
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m4(rows, cols),
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             r1(rows, cols),
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             r2(rows, cols);
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VectorType v2 = VectorType::Random(rows);
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m1up = m1.template triangularView<Upper>();
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m2up = m2.template triangularView<Upper>();
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (rows*cols>1)
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(m1up.isUpperTriangular());
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(m2up.transpose().isLowerTriangular());
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(!m2.isLowerTriangular());
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overloaded operator+=
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r1.setZero();
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r2.setZero();
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r1.template triangularView<Upper>() +=  m1;
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r2 += m1up;
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(r1,r2);
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overloaded operator=
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<Upper>() = m2.transpose() + m2;
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m2.transpose() + m2;
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<Lower>().transpose().toDenseMatrix(), m1);
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overloaded operator=
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<Lower>() = m2.transpose() + m2;
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<Lower>().toDenseMatrix(), m1);
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<Lower>().conjugate().toDenseMatrix(),
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                   m3.conjugate().template triangularView<Lower>().toDenseMatrix());
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1 = MatrixType::Random(rows, cols);
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<rows; ++i)
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    while (internal::abs2(m1(i,i))<1e-1) m1(i,i) = internal::random<Scalar>();
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Transpose<MatrixType> trm4(m4);
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test back and forward subsitution with a vector as the rhs
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Upper>();
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Lower>().solve(v2)), largerEps));
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Lower>();
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Upper>().solve(v2)), largerEps));
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Upper>();
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(v2.isApprox(m3 * (m1.template triangularView<Upper>().solve(v2)), largerEps));
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Lower>();
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Lower>().solve(v2)), largerEps));
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test back and forward subsitution with a matrix as the rhs
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Upper>();
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Lower>().solve(m2)), largerEps));
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Lower>();
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Upper>().solve(m2)), largerEps));
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Upper>();
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isApprox(m3 * (m1.template triangularView<Upper>().solve(m2)), largerEps));
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Lower>();
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Lower>().solve(m2)), largerEps));
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // check M * inv(L) using in place API
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m4 = m3;
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.transpose().template triangularView<Eigen::Upper>().solveInPlace(trm4);
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m4 * m1.template triangularView<Eigen::Lower>(), m3);
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // check M * inv(U) using in place API
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<Upper>();
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m4 = m3;
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3.transpose().template triangularView<Eigen::Lower>().solveInPlace(trm4);
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m4 * m1.template triangularView<Eigen::Upper>(), m3);
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // check solve with unit diagonal
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = m1.template triangularView<UnitUpper>();
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isApprox(m3 * (m1.template triangularView<UnitUpper>().solve(m2)), largerEps));
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   VERIFY((  m1.template triangularView<Upper>()
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//           * m2.template triangularView<Upper>()).isUpperTriangular());
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test swap
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setOnes();
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.setZero();
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.template triangularView<Upper>().swap(m1);
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3.setZero();
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3.template triangularView<Upper>().setOnes();
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m2,m3);
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> void triangular_rect(const MatrixType& m)
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef const typename MatrixType::Index Index;
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename MatrixType::Scalar Scalar;
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { Rows =  MatrixType::RowsAtCompileTime, Cols =  MatrixType::ColsAtCompileTime };
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, Rows, 1> VectorType;
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, Rows, Rows> RMatrixType;
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Index rows = m.rows();
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Index cols = m.cols();
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m1 = MatrixType::Random(rows, cols),
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m2 = MatrixType::Random(rows, cols),
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m3(rows, cols),
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             m4(rows, cols),
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             r1(rows, cols),
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath             r2(rows, cols);
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m1up = m1.template triangularView<Upper>();
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType m2up = m2.template triangularView<Upper>();
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (rows>1 && cols>1)
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(m1up.isUpperTriangular());
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(m2up.transpose().isLowerTriangular());
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(!m2.isLowerTriangular());
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overloaded operator+=
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r1.setZero();
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r2.setZero();
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r1.template triangularView<Upper>() +=  m1;
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  r2 += m1up;
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(r1,r2);
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overloaded operator=
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<Upper>() = 3 * m2;
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3 = 3 * m2;
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<Upper>().toDenseMatrix(), m1);
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<Lower>() = 3 * m2;
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<Lower>().toDenseMatrix(), m1);
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<StrictlyUpper>() = 3 * m2;
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<StrictlyUpper>().toDenseMatrix(), m1);
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setZero();
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.template triangularView<StrictlyLower>() = 3 * m2;
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m3.template triangularView<StrictlyLower>().toDenseMatrix(), m1);
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setRandom();
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<Upper>();
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isUpperTriangular());
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(!m2.isLowerTriangular());
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<StrictlyUpper>();
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isUpperTriangular());
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<UnitUpper>();
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isUpperTriangular());
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.diagonal().array() -= Scalar(1);
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<Lower>();
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isLowerTriangular());
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(!m2.isUpperTriangular());
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<StrictlyLower>();
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isLowerTriangular());
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2 = m1.template triangularView<UnitLower>();
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.isLowerTriangular());
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.diagonal().array() -= Scalar(1);
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test swap
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m1.setOnes();
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.setZero();
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m2.template triangularView<Upper>().swap(m1);
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3.setZero();
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m3.template triangularView<Upper>().setOnes();
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m2,m3);
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid bug_159()
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Matrix3d m = Matrix3d::Random().triangularView<Lower>();
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_UNUSED_VARIABLE(m)
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_triangular()
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int maxsize = (std::min)(EIGEN_TEST_MAX_SIZE,20);
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i = 0; i < g_repeat ; i++)
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int r = internal::random<int>(2,maxsize); EIGEN_UNUSED_VARIABLE(r);
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int c = internal::random<int>(2,maxsize); EIGEN_UNUSED_VARIABLE(c);
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_3( triangular_square(Matrix3d()) );
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_4( triangular_square(Matrix<std::complex<float>,8, 8>()) );
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_5( triangular_square(MatrixXcd(r,r)) );
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_6( triangular_square(Matrix<float,Dynamic,Dynamic,RowMajor>(r, r)) );
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_7( triangular_rect(Matrix<float, 4, 5>()) );
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_8( triangular_rect(Matrix<double, 6, 2>()) );
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_9( triangular_rect(MatrixXcf(r, c)) );
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_5( triangular_rect(MatrixXcd(r, c)) );
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_6( triangular_rect(Matrix<float,Dynamic,Dynamic,RowMajor>(r, c)) );
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  CALL_SUBTEST_1( bug_159() );
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
236