Compare commits

...

50 Commits
3.1.2 ... 3.1

Author SHA1 Message Date
Antonio Sanchez
8dd23c4ffd Add CI to build docs 2025-10-16 21:59:33 -07:00
Anton Gladky
d65a6aeb20 Port unsupported constrained CG to Eigen3
(grafted from 4cd4be97a7
)
2014-01-15 17:49:52 +01:00
Gael Guennebaud
395214bcc3 Fix changeset 2702788da7
for fixed size matrices
(transplanted from 8f496cd3a3
)
2013-11-01 18:17:55 +01:00
Gael Guennebaud
696bee033b Fix bug #678: vectors of row and columns transpositions were not properly resized in FullPivQR
(grafted from 2702788da7
)
2013-10-29 18:02:18 +01:00
Martinho Fernandes
59bd03457a Fix bug #503
C++11 support on simple allocators comes for free. `aligned_allocator` does not
need to add any `construct` overloads to work with C++11 compilers.
(grafted from a1f056cf2a
)
2013-09-10 17:08:04 +02:00
vanhoucke
088e8fcfef Silence unused variable warning.
(grafted from 3736e00ae7
)
2013-10-04 00:21:03 +00:00
Gael Guennebaud
0e2efbddd3 Fix bug #666: unused-local-typedefs warning 2013-10-28 17:34:24 +01:00
Thomas Capricelli
12b9b92c40 fix a weird typo I commited in ae76c97704
(Nov 10th, 2009)
2013-10-11 20:44:25 +02:00
Gael Guennebaud
0952ab2ac4 Added tag 3.1.4 for changeset 38229a3d23 2013-08-01 11:35:49 +02:00
Gael Guennebaud
38229a3d23 bump to 3.1.4 2013-08-01 11:35:43 +02:00
Gael Guennebaud
b18f9427a8 Fix bug in sparse documentation.
(transplanted from 4020d4286f
)
2013-07-04 06:49:24 +02:00
Gael Guennebaud
a6fbf2c202 CwiseUnaryView should not inherit no_assignment_operator!
(transplanted from 1330ca611b
)
2013-06-24 13:45:33 +02:00
Gael Guennebaud
2034af6db9 fix compilation of ArrayBase::transposeInPlace
(transplanted from c21a04bcf9
)
2013-06-24 13:35:13 +02:00
Gael Guennebaud
fbe1d5fb2c bug #620: fix robustness issue in JacobiSVD::solve (also fix a perf. issue)
(transplanted from 8bbde351e7
)
2013-06-24 13:08:09 +02:00
Jitse Niesen
560877016a Avoid phrase "static allocation" for local storage on stack (bug #615).
(transplanted from 4e6d746514
)
2013-06-18 14:35:12 +01:00
Gael Guennebaud
c7ba7f59d6 Fix compilation issue with some compilers (when doing using Base::foo;, foo must be visible in the direct base class)
(transplanted from 33788b97dd
)
2013-06-18 00:48:47 +02:00
Jeff Dean
5dca39eb8b Fix bug #613: psqrt was incorrect for small numbers
(transplanted from d5fa5001a7
)
2013-06-13 18:17:27 +02:00
Gael Guennebaud
21826e9e53 Add missing dependency in SparseSholesky header
(transplanted from f3af423c70
)
2013-06-11 21:13:30 +02:00
Gael Guennebaud
97c08b43b4 Fix bug #608: the sign computation in LDLT was broken
(transplanted from a69b4b092b
)
2013-06-09 23:19:32 +02:00
Gael Guennebaud
8f67e02ee2 Fix non const data() member in Array and Matrix wrappers.
(transplanted from b5e5b6aa57
)
2013-05-16 10:18:19 +02:00
Gael Guennebaud
93c329445c Add missing data member function in CwiseUnaryView
(transplanted from e21dc15386
)
2013-02-07 17:44:24 +01:00
Gael Guennebaud
575255bc1f fix a typo in commit 324ecf153b
(regarding MKL on windows)
(transplanted from 576d62db64
)
2012-08-27 13:17:45 +02:00
Gael Guennebaud
d29654fb4e Added tag 3.1.3 for changeset 2221cdbe62 2013-04-16 09:38:46 +02:00
Gael Guennebaud
2221cdbe62 bump to 3.1.3 2013-04-16 09:38:40 +02:00
Hauke Heibel
ba1e62f516 Prevent calling .norm() on integer matrices in the unit tests.
(transplanted from b5d8299ee7
)
2013-02-28 12:33:34 +01:00
Gael Guennebaud
ce2b0ac502 Fix two numerical issues in unit tests.
(transplanted from 455e6e38b6
)
2013-02-27 08:07:18 +01:00
Gael Guennebaud
1f7dfcff8a Add missing template keyword
(transplanted from 858ac9ffe0
)
2013-03-01 00:03:28 +01:00
Gael Guennebaud
2234043f99 Enable SSE with ICC even when it mimics a gcc version lower than 4.2
(transplanted from 6eaff5a098
)
2013-04-11 19:48:34 +02:00
Gael Guennebaud
69ff8afea7 Workaround gcc-4.7 bug #53900 (too aggressive optimization in our alignment check)
(transplanted from 19c78cf510
)
2013-01-22 22:59:09 +01:00
Gael Guennebaud
64a6d37729 Fix a serious bug in handmade_aligned_realloc: original data have to be moved if the alignment offset differs.
(transplanted from 7e04d7db02
)
2013-04-10 13:58:20 +02:00
Gael Guennebaud
4ac874ed03 Upload CDASH submissions for the 3.1 branch to a separate project 2013-04-10 10:06:36 +02:00
Gael Guennebaud
0029599c4a Fix bug #581: remove useless piece of code is blueNorm
(transplanted from 8f44205671
)
2013-04-09 09:23:40 +02:00
Claas H. Köhler
f78dffffda Forward compiler flags to Fortran workaround
(transplanted from d6d638c751
)
2013-03-17 14:17:44 +01:00
Gael Guennebaud
e304a92f41 fix sparse vector assignment from a sparse matrix
(transplanted from 98ce4455dd
)
2013-03-06 11:58:22 +01:00
Gael Guennebaud
2674a31421 Fix a compilation with CGAL::Gmpq by adding explicit internal:: namespace when calling abs(). 2013-02-26 16:46:10 +01:00
Gael Guennebaud
de25881056 Fix computation of outer-stride when calling .real() or .imag()
(transplanted from 63135a7350
)
2013-02-26 15:08:50 +01:00
Jitse Niesen
7df8b57770 Fix linear vectorized transversal in linspace (fixes bug #526).
(transplanted from b4f6aec195
)
2013-02-18 17:26:03 +00:00
Gael Guennebaud
ddba6054e0 Push cdash report of the 3.1 branch in its own cdash subproject 2013-02-15 15:30:27 +01:00
Gael Guennebaud
6adc13ea04 Fix SSE plog<float> to return -INF on 0
(transplanted from 8745da14d8
)
2013-02-14 23:34:05 +01:00
Gael Guennebaud
66cbfd4d39 Fix some implicit int64 to int conversion warnings. However, the real issue
is that PermutationMatrix mixes the type of the stored indices and the "Index"
type used for the sizes, coeff indices, etc., which should be DenseIndex.
2013-02-14 18:16:51 +01:00
Gael Guennebaud
394784c999 Fix bug in aligned_free with windows CE
(transplanted from 25bcbfb10c
)
2013-02-13 19:09:31 +01:00
Gael Guennebaud
fcc46f49ca Fix bug #551: compilation issue when using EIGEN_DEFAULT_DENSE_INDEX_TYPE 2013-02-09 09:43:17 +01:00
Gael Guennebaud
92983fc95a Fix traits of Map<Quaternion>, and respectively extend the unit tests
(transplanted from 392ffce3b9
)
2013-01-20 10:21:54 +01:00
Gael Guennebaud
d5702fb7e9 Some minor documentation fixes in Quaternion
(transplanted from fb89b66229
)
2013-01-20 10:20:39 +01:00
Christoph Hertzberg
8aaa570c6d Fix bug #507: Mark variable as unused in NDEBUG case 2012-12-20 11:21:47 +01:00
Christoph Hertzberg
8c65cacad8 Fix bug #531: Empty line in <table> made doxygen render it as paragraphs 2012-12-17 16:13:42 +01:00
Gael Guennebaud
2041114285 Fix bug #533: add some missing const qualifiers (was already fixed in devel branch) 2012-12-16 20:36:59 +01:00
Gael Guennebaud
ac406a7685 Fix bug #535: unused variable warnings
(transplanted from 925a5b7d07
)
2012-12-16 20:21:28 +01:00
Gael Guennebaud
45ccaacc54 fix geometry tutorial
(transplanted from 8719b1bf16
)
2012-11-29 22:48:13 +08:00
Gael Guennebaud
43e90e3575 Added tag 3.1.2 for changeset 63c58c8436 2012-11-05 22:23:03 +01:00
49 changed files with 493 additions and 147 deletions

41
.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
qrc_*cxx
*.orig
*.pyc
*.diff
diff
*.save
save
*.old
*.gmo
*.qm
core
core.*
*.bak
*~
*.build*
*.moc.*
*.moc
ui_*
CMakeCache.txt
tags
.*.swp
activity.png
*.out
*.php*
*.log
*.orig
*.rej
log
patch
*.patch
a
a.*
lapack/testing
lapack/reference
.*project
.settings
Makefile
!ci/build.gitlab-ci.yml
!scripts/buildtests.in
!Eigen/Core
!Eigen/src/Core

28
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,28 @@
# This file is part of Eigen, a lightweight C++ template library
# for linear algebra.
#
# Copyright (C) 2023, The Eigen Authors
#
# This Source Code Form is subject to the terms of the Mozilla
# Public License v. 2.0. If a copy of the MPL was not distributed
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
stages:
- build
- deploy
variables:
# CMake build directory.
EIGEN_CI_BUILDDIR: .build
# Specify the CMake build target.
EIGEN_CI_BUILD_TARGET: ""
# If a test regex is specified, that will be selected.
# Otherwise, we will try a label if specified.
EIGEN_CI_CTEST_REGEX: ""
EIGEN_CI_CTEST_LABEL: ""
EIGEN_CI_CTEST_ARGS: ""
include:
- "/ci/common.gitlab-ci.yml"
- "/ci/build.linux.gitlab-ci.yml"
- "/ci/deploy.gitlab-ci.yml"

View File

@@ -4,10 +4,10 @@
## # The following are required to uses Dart and the Cdash dashboard
## ENABLE_TESTING()
## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "Eigen")
set(CTEST_PROJECT_NAME "Eigen3.1")
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "manao.inria.fr")
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
set(CTEST_DROP_SITE_CDASH TRUE)
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen3.1")
set(CTEST_DROP_SITE_CDASH TRUE)

View File

@@ -44,7 +44,7 @@
#endif
#else
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
#endif
#endif

View File

@@ -2,6 +2,7 @@
#define EIGEN_SPARSECHOLESKY_MODULE_H
#include "SparseCore"
#include "OrderingMethods"
#include "src/Core/util/DisableStupidWarnings.h"

View File

@@ -277,15 +277,13 @@ template<> struct ldlt_inplace<Lower>
// are compared; if any diagonal is negligible compared
// to the largest overall, the algorithm bails.
cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
if(sign)
*sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
}
// Finish early if the matrix is not full rank.
if(biggest_in_corner < cutoff)
{
for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i;
if(sign) *sign = 0;
break;
}
@@ -326,6 +324,16 @@ template<> struct ldlt_inplace<Lower>
}
if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff))
A21 /= mat.coeffRef(k,k);
if(sign)
{
// LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right
int newSign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0;
if(k == 0)
*sign = newSign;
else if(*sign != newSign)
*sign = 0;
}
}
return true;
@@ -534,8 +542,7 @@ template<typename Derived>
bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
const Index size = m_matrix.rows();
eigen_assert(size == bAndX.rows());
eigen_assert(m_matrix.rows() == bAndX.rows());
bAndX = this->solve(bAndX);

View File

@@ -55,7 +55,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
inline CoeffReturnType coeff(Index row, Index col) const
@@ -175,7 +175,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
inline CoeffReturnType coeff(Index row, Index col) const

View File

@@ -210,7 +210,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr)
// The vm*powx functions are not avaibale in the windows version of MKL.
#ifdef _WIN32
#ifndef _WIN32
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float)
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double)
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8)

View File

@@ -44,9 +44,10 @@ struct traits<CwiseUnaryView<ViewOp, MatrixType> >
// "error: no integral type can represent all of the enumerator values
InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic
? int(Dynamic)
: int(MatrixTypeInnerStride)
* int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
: int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret == Dynamic
? int(Dynamic)
: outer_stride_at_compile_time<MatrixType>::ret * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar))
};
};
}
@@ -55,8 +56,7 @@ template<typename ViewOp, typename MatrixType, typename StorageKind>
class CwiseUnaryViewImpl;
template<typename ViewOp, typename MatrixType>
class CwiseUnaryView : internal::no_assignment_operator,
public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
{
public:
@@ -98,6 +98,10 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
inline Scalar* data() { return &coeffRef(0); }
inline const Scalar* data() const { return &coeff(0); }
inline Index innerStride() const
{
@@ -106,7 +110,7 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
inline Index outerStride() const
{
return derived().nestedExpression().outerStride();
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
}
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const

View File

@@ -39,13 +39,24 @@ struct plain_array
plain_array(constructor_without_unaligned_array_assert) {}
};
#ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
#elif EIGEN_GNUC_AT_LEAST(4,7)
// GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
// See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
// Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
template<typename PtrType>
EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \
&& "this assertion is explained here: " \
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
" **** READ THIS WEB PAGE !!! ****");
#else
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
&& "this assertion is explained here: " \
"http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
" **** READ THIS WEB PAGE !!! ****");
#endif

View File

@@ -533,8 +533,11 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
// linear access for packet ops:
// 1) initialization
// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
// 2) each step
// 2) each step (where size is 1 for coeff access or PacketSize for packet access)
// base += [size*step, ..., size*step]
//
// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp)
// in order to avoid the padd() in operator() ?
template <typename Scalar>
struct linspaced_op_impl<Scalar,false>
{
@@ -543,10 +546,15 @@ struct linspaced_op_impl<Scalar,false>
linspaced_op_impl(Scalar low, Scalar step) :
m_low(low), m_step(step),
m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
m_base(padd(pset1<Packet>(low),pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
template<typename Index>
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
{
m_base = padd(m_base, pset1<Packet>(m_step));
return m_low+i*m_step;
}
template<typename Index>
EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }

View File

@@ -105,13 +105,13 @@ class PermutationBase : public EigenBase<Derived>
#endif
/** \returns the number of rows */
inline Index rows() const { return indices().size(); }
inline Index rows() const { return Index(indices().size()); }
/** \returns the number of columns */
inline Index cols() const { return indices().size(); }
inline Index cols() const { return Index(indices().size()); }
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
inline Index size() const { return indices().size(); }
inline Index size() const { return Index(indices().size()); }
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename DenseDerived>

View File

@@ -551,6 +551,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
: (rows() == other.rows() && cols() == other.cols())))
&& "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
EIGEN_ONLY_USED_FOR_DEBUG(other);
#else
resizeLike(other);
#endif

View File

@@ -13,6 +13,7 @@
namespace Eigen {
namespace internal {
template<typename ExpressionType, typename Scalar>
inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
{
@@ -76,21 +77,20 @@ MatrixBase<Derived>::blueNorm() const
using std::pow;
using std::min;
using std::max;
static Index nmax = -1;
static bool initialized = false;
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
if(nmax <= 0)
if(!initialized)
{
int nbig, ibeta, it, iemin, iemax, iexp;
int ibeta, it, iemin, iemax, iexp;
RealScalar abig, eps;
// This program calculates the machine-dependent constants
// bl, b2, slm, s2m, relerr overfl, nmax
// bl, b2, slm, s2m, relerr overfl
// from the "basic" machine-dependent numbers
// nbig, ibeta, it, iemin, iemax, rbig.
// ibeta, it, iemin, iemax, rbig.
// The following define the basic machine-dependent constants.
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
// are used. For any specific computer, each of the assignment
// statements can be replaced
nbig = (std::numeric_limits<Index>::max)(); // largest integer
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
@@ -111,8 +111,7 @@ MatrixBase<Derived>::blueNorm() const
eps = RealScalar(pow(double(ibeta), 1-it));
relerr = internal::sqrt(eps); // tolerance for neglecting asml
abig = RealScalar(1.0/eps - 1.0);
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
else nmax = nbig;
initialized = true;
}
Index n = size();
RealScalar ab2 = b2 / RealScalar(n);

View File

@@ -104,6 +104,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
@@ -252,7 +253,7 @@ struct inplace_transpose_selector;
template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,true> { // square matrix
static void run(MatrixType& m) {
m.template triangularView<StrictlyUpper>().swap(m.transpose());
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
}
};
@@ -260,7 +261,7 @@ template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,false> { // non square matrix
static void run(MatrixType& m) {
if (m.rows()==m.cols())
m.template triangularView<StrictlyUpper>().swap(m.transpose());
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
else
m = m.transpose().eval();
}
@@ -353,7 +354,7 @@ struct check_transpose_aliasing_run_time_selector
{
static bool run(const Scalar* dest, const OtherDerived& src)
{
return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src));
}
};
@@ -362,8 +363,8 @@ struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseB
{
static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
{
return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.lhs())))
|| ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.rhs())));
return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs())))
|| ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs())));
}
};

View File

@@ -31,7 +31,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
/* the smallest non denormalized float number */
_EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos, 0x00800000);
_EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf, 0xff800000);//-1.f/0.f);
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
@@ -51,7 +52,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
Packet4i emm0;
Packet4f invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps());
Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps());
Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */
emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
@@ -96,7 +98,9 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
y2 = pmul(e, p4f_cephes_log_q2);
x = padd(x, y);
x = padd(x, y2);
return _mm_or_ps(x, invalid_mask); // negative arg will be NAN
// negative arg will be NAN, 0 will be -INF
return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)),
_mm_and_ps(iszero_mask, p4f_minus_inf));
}
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
@@ -370,7 +374,7 @@ Packet4f psqrt<Packet4f>(const Packet4f& _x)
Packet4f half = pmul(_x, pset1<Packet4f>(.5f));
/* select only the inverse sqrt of non-zero inputs */
Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>(std::numeric_limits<float>::epsilon()));
Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>((std::numeric_limits<float>::min)()));
Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x));
x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x))));

View File

@@ -69,8 +69,8 @@ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdi
* - the number of scalars that fit into a packet (when vectorization is enabled).
*
* \sa setCpuCacheSizes */
template<typename LhsScalar, typename RhsScalar, int KcFactor>
void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
template<typename LhsScalar, typename RhsScalar, int KcFactor, typename SizeType>
void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n)
{
EIGEN_UNUSED_VARIABLE(n);
// Explanations:
@@ -91,13 +91,13 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd
};
manage_caching_sizes(GetAction, &l1, &l2);
k = std::min<std::ptrdiff_t>(k, l1/kdiv);
std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
k = std::min<SizeType>(k, l1/kdiv);
SizeType _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
if(_m<m) m = _m & mr_mask;
}
template<typename LhsScalar, typename RhsScalar>
inline void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
template<typename LhsScalar, typename RhsScalar, typename SizeType>
inline void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n)
{
computeProductBlockingSizes<LhsScalar,RhsScalar,1>(k, m, n);
}

View File

@@ -13,7 +13,7 @@
#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 1
#define EIGEN_MINOR_VERSION 2
#define EIGEN_MINOR_VERSION 4
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \

View File

@@ -88,11 +88,11 @@ inline void throw_std_bad_alloc()
/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
* Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
*/
inline void* handmade_aligned_malloc(size_t size)
inline void* handmade_aligned_malloc(std::size_t size)
{
void *original = std::malloc(size+16);
if (original == 0) return 0;
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -108,13 +108,18 @@ inline void handmade_aligned_free(void *ptr)
* Since we know that our handmade version is based on std::realloc
* we can use std::realloc to implement efficient reallocation.
*/
inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
{
if (ptr == 0) return handmade_aligned_malloc(size);
void *original = *(reinterpret_cast<void**>(ptr) - 1);
std::ptrdiff_t previous_offset = static_cast<char *>(ptr)-static_cast<char *>(original);
original = std::realloc(original,size+16);
if (original == 0) return 0;
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
void *previous_aligned = static_cast<char *>(original)+previous_offset;
if(aligned!=previous_aligned)
std::memmove(aligned, previous_aligned, size);
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -123,7 +128,7 @@ inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
*** Implementation of generic aligned realloc (when no realloc can be used)***
*****************************************************************************/
void* aligned_malloc(size_t size);
void* aligned_malloc(std::size_t size);
void aligned_free(void *ptr);
/** \internal
@@ -227,7 +232,7 @@ inline void aligned_free(void *ptr)
std::free(ptr);
#elif EIGEN_HAS_MM_MALLOC
_mm_free(ptr);
#elif defined(_MSC_VER)
#elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
_aligned_free(ptr);
#else
handmade_aligned_free(ptr);
@@ -446,7 +451,6 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T *
template<typename Scalar, typename Index>
static inline Index first_aligned(const Scalar* array, Index size)
{
typedef typename packet_traits<Scalar>::type Packet;
enum { PacketSize = packet_traits<Scalar>::size,
PacketAlignedMask = PacketSize-1
};
@@ -705,15 +709,6 @@ public:
::new( p ) T( value );
}
// Support for c++11
#if (__cplusplus >= 201103L)
template<typename... Args>
void construct(pointer p, Args&&... args)
{
::new(p) T(std::forward<Args>(args)...);
}
#endif
void destroy( pointer p )
{
p->~T();

View File

@@ -512,8 +512,7 @@ template<typename MatrixType>
template<typename OtherDerived, typename ResultType>
bool SVD<MatrixType>::solve(const MatrixBase<OtherDerived> &b, ResultType* result) const
{
const int rows = m_matU.rows();
ei_assert(b.rows() == rows);
ei_assert(b.rows() == m_matU.rows());
Scalar maxVal = m_sigma.cwise().abs().maxCoeff();
for (int j=0; j<b.cols(); ++j)

View File

@@ -193,7 +193,8 @@ public:
*
* \brief The quaternion class used to represent 3D orientations and rotations
*
* \param _Scalar the scalar type, i.e., the type of the coefficients
* \tparam _Scalar the scalar type, i.e., the type of the coefficients
* \tparam _Options controls the memory alignement of the coeffecients. Can be \# AutoAlign or \# DontAlign. Default is AutoAlign.
*
* This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of
* orientations and rotations of objects in three dimensions. Compared to other representations
@@ -304,41 +305,29 @@ typedef Quaternion<double> Quaterniond;
namespace internal {
template<typename _Scalar, int _Options>
struct traits<Map<Quaternion<_Scalar>, _Options> >:
traits<Quaternion<_Scalar, _Options> >
struct traits<Map<Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
{
typedef _Scalar Scalar;
typedef Map<Matrix<_Scalar,4,1>, _Options> Coefficients;
typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
enum {
IsAligned = TraitsBase::IsAligned,
Flags = TraitsBase::Flags
};
};
}
namespace internal {
template<typename _Scalar, int _Options>
struct traits<Map<const Quaternion<_Scalar>, _Options> >:
traits<Quaternion<_Scalar> >
struct traits<Map<const Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
{
typedef _Scalar Scalar;
typedef Map<const Matrix<_Scalar,4,1>, _Options> Coefficients;
typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
typedef traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> > TraitsBase;
enum {
IsAligned = TraitsBase::IsAligned,
Flags = TraitsBase::Flags & ~LvalueBit
};
};
}
/** \brief Quaternion expression mapping a constant memory buffer
/** \ingroup Geometry_Module
* \brief Quaternion expression mapping a constant memory buffer
*
* \param _Scalar the type of the Quaternion coefficients
* \param _Options see class Map
* \tparam _Scalar the type of the Quaternion coefficients
* \tparam _Options see class Map
*
* This is a specialization of class Map for Quaternion. This class allows to view
* a 4 scalar memory buffer as an Eigen's Quaternion object.
@@ -371,10 +360,11 @@ class Map<const Quaternion<_Scalar>, _Options >
const Coefficients m_coeffs;
};
/** \brief Expression of a quaternion from a memory buffer
/** \ingroup Geometry_Module
* \brief Expression of a quaternion from a memory buffer
*
* \param _Scalar the type of the Quaternion coefficients
* \param _Options see class Map
* \tparam _Scalar the type of the Quaternion coefficients
* \tparam _Options see class Map
*
* This is a specialization of class Map for Quaternion. This class allows to view
* a 4 scalar memory buffer as an Eigen's Quaternion object.

View File

@@ -577,7 +577,7 @@ struct kernel_retval<FullPivLU<_MatrixType> >
RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
Index p = 0;
for(Index i = 0; i < dec().nonzeroPivots(); ++i)
if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
if(internal::abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
pivots.coeffRef(p++) = i;
eigen_internal_assert(p == rank());
@@ -645,7 +645,7 @@ struct image_retval<FullPivLU<_MatrixType> >
RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
Index p = 0;
for(Index i = 0; i < dec().nonzeroPivots(); ++i)
if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
if(internal::abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
pivots.coeffRef(p++) = i;
eigen_internal_assert(p == rank());

View File

@@ -56,6 +56,12 @@ template<typename _MatrixType> class ColPivHouseholderQR
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
private:
typedef typename PermutationType::Index PermIndexType;
public:
/**
* \brief Default Constructor.
@@ -81,7 +87,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR(Index rows, Index cols)
: m_qr(rows, cols),
m_hCoeffs((std::min)(rows,cols)),
m_colsPermutation(cols),
m_colsPermutation(PermIndexType(cols)),
m_colsTranspositions(cols),
m_temp(cols),
m_colSqNorms(cols),
@@ -91,7 +97,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
m_colsPermutation(matrix.cols()),
m_colsPermutation(PermIndexType(matrix.cols())),
m_colsTranspositions(matrix.cols()),
m_temp(matrix.cols()),
m_colSqNorms(matrix.cols()),
@@ -436,9 +442,9 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
}
m_colsPermutation.setIdentity(cols);
for(Index k = 0; k < m_nonzero_pivots; ++k)
m_colsPermutation.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
m_colsPermutation.setIdentity(PermIndexType(cols));
for(PermIndexType k = 0; k < m_nonzero_pivots; ++k)
m_colsPermutation.applyTranspositionOnTheRight(PermIndexType(k), PermIndexType(m_colsTranspositions.coeff(k)));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;

View File

@@ -63,9 +63,10 @@ template<typename _MatrixType> class FullPivHouseholderQR
typedef typename MatrixType::Index Index;
typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef Matrix<Index, 1, ColsAtCompileTime, RowMajor, 1, MaxColsAtCompileTime> IntRowVectorType;
typedef Matrix<Index, 1,
EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime,RowsAtCompileTime), RowMajor, 1,
EIGEN_SIZE_MIN_PREFER_FIXED(MaxColsAtCompileTime,MaxRowsAtCompileTime)> IntDiagSizeVectorType;
typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_col_type<MatrixType>::type ColVectorType;
@@ -158,7 +159,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
return m_cols_permutation;
}
const IntColVectorType& rowsTranspositions() const
const IntDiagSizeVectorType& rowsTranspositions() const
{
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rows_transpositions;
@@ -348,8 +349,8 @@ template<typename _MatrixType> class FullPivHouseholderQR
protected:
MatrixType m_qr;
HCoeffsType m_hCoeffs;
IntColVectorType m_rows_transpositions;
IntRowVectorType m_cols_transpositions;
IntDiagSizeVectorType m_rows_transpositions;
IntDiagSizeVectorType m_cols_transpositions;
PermutationType m_cols_permutation;
RowVectorType m_temp;
bool m_isInitialized, m_usePrescribedThreshold;
@@ -389,8 +390,8 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
m_precision = NumTraits<Scalar>::epsilon() * size;
m_rows_transpositions.resize(matrix.rows());
m_cols_transpositions.resize(matrix.cols());
m_rows_transpositions.resize(size);
m_cols_transpositions.resize(size);
Index number_of_transpositions = 0;
RealScalar biggest(0);
@@ -520,14 +521,14 @@ template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
{
public:
typedef typename MatrixType::Index Index;
typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType;
typedef typename FullPivHouseholderQR<MatrixType>::IntDiagSizeVectorType IntDiagSizeVectorType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef Matrix<typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime, RowMajor, 1,
MatrixType::MaxRowsAtCompileTime> WorkVectorType;
FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr,
const HCoeffsType& hCoeffs,
const IntColVectorType& rowsTranspositions)
const IntDiagSizeVectorType& rowsTranspositions)
: m_qr(qr),
m_hCoeffs(hCoeffs),
m_rowsTranspositions(rowsTranspositions)
@@ -566,7 +567,7 @@ public:
protected:
typename MatrixType::Nested m_qr;
typename HCoeffsType::Nested m_hCoeffs;
typename IntColVectorType::Nested m_rowsTranspositions;
typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
};
} // end namespace internal

View File

@@ -833,17 +833,13 @@ struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
// A = U S V^*
// So A^{-1} = V S^{-1} U^*
Matrix<Scalar, Dynamic, Rhs::ColsAtCompileTime, 0, _MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime> tmp;
Index diagSize = (std::min)(dec().rows(), dec().cols());
typename JacobiSVDType::SingularValuesType invertedSingVals(diagSize);
Index nonzeroSingVals = dec().nonzeroSingularValues();
invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();
invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();
dst = dec().matrixV().leftCols(diagSize)
* invertedSingVals.asDiagonal()
* dec().matrixU().leftCols(diagSize).adjoint()
* rhs();
tmp.noalias() = dec().matrixU().leftCols(nonzeroSingVals).adjoint() * rhs();
tmp = dec().singularValues().head(nonzeroSingVals).asDiagonal().inverse() * tmp;
dst = dec().matrixV().leftCols(nonzeroSingVals) * tmp;
}
};
} // end namespace internal

View File

@@ -209,6 +209,7 @@ class SparseSelfAdjointTimeDenseProduct
template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
{
EIGEN_ONLY_USED_FOR_DEBUG(alpha);
// TODO use alpha
eigen_assert(alpha==Scalar(1) && "alpha != 1 is not implemented yet, sorry");
typedef typename internal::remove_all<Lhs>::type _Lhs;

View File

@@ -202,7 +202,7 @@ class SparseVector
}
inline SparseVector(const SparseVector& other)
: m_size(0)
: SparseBase(other), m_size(0)
{
*this = other.derived();
}
@@ -230,7 +230,8 @@ class SparseVector
template<typename OtherDerived>
inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
{
if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
if ( (bool(OtherDerived::IsVectorAtCompileTime) && int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
|| ((!bool(OtherDerived::IsVectorAtCompileTime)) && ( bool(IsColVector) ? other.cols()>1 : other.rows()>1 )))
return assign(other.transpose());
else
return assign(other);

View File

@@ -0,0 +1,30 @@
# Base configuration for linux cross-compilation.
.build:linux:cross:
extends: .common:linux:cross
stage: build
variables:
EIGEN_CI_BUILD_TARGET: buildtests
script:
- . ci/scripts/build.linux.script.sh
tags:
- saas-linux-2xlarge-amd64
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "web" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_PROJECT_NAMESPACE == "libeigen" && $CI_MERGE_REQUEST_LABELS =~ "/all-tests/"
cache:
key: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG-BUILD"
paths:
- ${EIGEN_CI_BUILDDIR}/
build:linux:docs:
extends: .build:linux:cross
variables:
EIGEN_CI_TARGET_ARCH: any
EIGEN_CI_BUILD_TARGET: doc
EIGEN_CI_INSTALL: ca-certificates clang flex python3 bison graphviz
EIGEN_CI_C_COMPILER: clang
EIGEN_CI_CXX_COMPILER: clang++
EIGEN_CI_BEFORE_SCRIPT: ". ci/scripts/build_and_install_doxygen.sh Release_1_13_2"
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_NAMESPACE == "libeigen"

24
ci/common.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,24 @@
# Base configuration for linux builds and tests.
.common:linux:cross:
image: ubuntu:20.04
variables:
EIGEN_CI_TARGET_ARCH: ""
EIGEN_CI_ADDITIONAL_ARGS: ""
# If host matches target, use the following:
EIGEN_CI_C_COMPILER: ""
EIGEN_CI_CXX_COMPILER: ""
EIGEN_CI_INSTALL: "${EIGEN_CI_C_COMPILER} ${EIGEN_CI_CXX_COMPILER}"
# If host does not match the target, use the following:
EIGEN_CI_CROSS_TARGET_TRIPLE: ""
EIGEN_CI_CROSS_C_COMPILER: ${EIGEN_CI_C_COMPILER}
EIGEN_CI_CROSS_CXX_COMPILER: ${EIGEN_CI_CXX_COMPILER}
EIGEN_CI_CROSS_INSTALL: "${EIGEN_CI_CROSS_C_COMPILER} ${EIGEN_CI_CROSS_CXX_COMPILER}"
before_script:
# Call script in current shell - it sets up some environment variables.
- . ci/scripts/common.linux.before_script.sh
artifacts:
when: always
name: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG"
paths:
- ${EIGEN_CI_BUILDDIR}/
expire_in: 5 days

25
ci/deploy.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,25 @@
# Upload docs if pipeline succeeded.
deploy:docs:
stage: deploy
image: busybox
dependencies: [ build:linux:docs ]
variables:
PAGES_PREFIX: docs-nightly
script:
- echo "Deploying site to $CI_PAGES_URL"
- mv ${EIGEN_CI_BUILDDIR}/doc/html public
pages:
path_prefix: $PAGES_PREFIX
expire_in: never
artifacts:
name: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG"
paths:
- public
tags:
- saas-linux-small-amd64
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "web" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_NAMESPACE == "libeigen"
variables:
PAGES_PREFIX: docs-$CI_COMMIT_REF_NAME

View File

@@ -0,0 +1,31 @@
#!/bin/bash
set -x
# Create and enter build directory.
rootdir=`pwd`
mkdir -p ${EIGEN_CI_BUILDDIR}
cd ${EIGEN_CI_BUILDDIR}
# Configure build.
cmake -G Ninja \
-DCMAKE_CXX_COMPILER=${EIGEN_CI_CXX_COMPILER} \
-DCMAKE_C_COMPILER=${EIGEN_CI_C_COMPILER} \
-DCMAKE_CXX_COMPILER_TARGET=${EIGEN_CI_CXX_COMPILER_TARGET} \
${EIGEN_CI_ADDITIONAL_ARGS} ${rootdir}
target=""
if [[ ${EIGEN_CI_BUILD_TARGET} ]]; then
target="--target ${EIGEN_CI_BUILD_TARGET}"
fi
# Builds (particularly gcc) sometimes get killed, potentially when running
# out of resources. In that case, keep trying to build the remaining
# targets (k0), then try to build again with a single thread (j1) to minimize
# resource use.
cmake --build . ${target} -- -k0 || cmake --build . ${target} -- -k0 -j1
# Return to root directory.
cd ${rootdir}
set +x

View File

@@ -0,0 +1,6 @@
git clone --depth 1 --branch $1 https://github.com/doxygen/doxygen.git
cmake -B doxygen/.build -G Ninja \
-DCMAKE_CXX_COMPILER=${EIGEN_CI_CXX_COMPILER} \
-DCMAKE_C_COMPILER=${EIGEN_CI_C_COMPILER} \
doxygen
cmake --build doxygen/.build -t install

View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -x
echo "Running ${CI_JOB_NAME}"
# Get architecture and display CI configuration.
export ARCH=`uname -m`
export NPROC=`nproc`
echo "arch=$ARCH, target=${EIGEN_CI_TARGET_ARCH}"
echo "Processors: ${NPROC}"
echo "CI Variables:"
export | grep EIGEN
# Set noninteractive, otherwise tzdata may be installed and prompt for a
# geographical region.
export DEBIAN_FRONTEND=noninteractive
apt-get update -y > /dev/null
apt-get install -y --no-install-recommends ninja-build cmake git > /dev/null
# Install required dependencies and set up compilers.
# These are required even for testing to ensure that dynamic runtime libraries
# are available.
if [[ "$ARCH" == "${EIGEN_CI_TARGET_ARCH}" || "${EIGEN_CI_TARGET_ARCH}" == "any" ]]; then
apt-get install -y --no-install-recommends ${EIGEN_CI_INSTALL} > /dev/null;
export EIGEN_CI_CXX_IMPLICIT_INCLUDE_DIRECTORIES="";
export EIGEN_CI_CXX_COMPILER_TARGET="";
else
apt-get install -y --no-install-recommends ${EIGEN_CI_CROSS_INSTALL} > /dev/null;
export EIGEN_CI_C_COMPILER=${EIGEN_CI_CROSS_C_COMPILER};
export EIGEN_CI_CXX_COMPILER=${EIGEN_CI_CROSS_CXX_COMPILER};
export EIGEN_CI_CXX_COMPILER_TARGET=${EIGEN_CI_CROSS_TARGET_TRIPLE};
# Tell the compiler where to find headers and libraries if using clang.
# NOTE: this breaks GCC since it messes with include path order
# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129)
if [[ "${EIGEN_CI_CROSS_CXX_COMPILER}" == *"clang"* ]]; then
export CPLUS_INCLUDE_PATH="/usr/${EIGEN_CI_CROSS_TARGET_TRIPLE}/include";
export LIBRARY_PATH="/usr/${EIGEN_CI_CROSS_TARGET_TRIPLE}/lib64";
fi
fi
echo "Compilers: ${EIGEN_CI_C_COMPILER} ${EIGEN_CI_CXX_COMPILER}"
if [ -n "$EIGEN_CI_BEFORE_SCRIPT" ]; then eval "$EIGEN_CI_BEFORE_SCRIPT"; fi
set +x

View File

@@ -24,6 +24,8 @@ function(workaround_9220 language language_works)
set(text
"project(test NONE)
cmake_minimum_required(VERSION 2.6.0)
set (CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")
set (CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}\")
enable_language(${language} OPTIONAL)
")
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/language_tests/${language})

View File

@@ -98,8 +98,8 @@ Matrix3f a;
MatrixXf b;
\endcode
Here,
\li \c a is a 3x3 matrix, with a static float[9] array of uninitialized coefficients,
\li \c b is a dynamic-size matrix whose size is currently 0x0, and whose array of
\li \c a is a 3-by-3 matrix, with a plain float[9] array of uninitialized coefficients,
\li \c b is a dynamic-size matrix whose size is currently 0-by-0, and whose array of
coefficients hasn't yet been allocated at all.
Constructors taking sizes are also available. For matrices, the number of rows is always passed first.
@@ -216,7 +216,7 @@ The simple answer is: use fixed
sizes for very small sizes where you can, and use dynamic sizes for larger sizes or where you have to. For small sizes,
especially for sizes smaller than (roughly) 16, using fixed sizes is hugely beneficial
to performance, as it allows Eigen to avoid dynamic memory allocation and to unroll
loops. Internally, a fixed-size Eigen matrix is just a plain static array, i.e. doing
loops. Internally, a fixed-size Eigen matrix is just a plain array, i.e. doing
\code Matrix4f mymatrix; \endcode
really amounts to just doing
\code float mymatrix[16]; \endcode
@@ -231,8 +231,9 @@ member variables.
The limitation of using fixed sizes, of course, is that this is only possible
when you know the sizes at compile time. Also, for large enough sizes, say for sizes
greater than (roughly) 32, the performance benefit of using fixed sizes becomes negligible.
Worse, trying to create a very large matrix using fixed sizes could result in a stack overflow,
since Eigen will try to allocate the array as a static array, which by default goes on the stack.
Worse, trying to create a very large matrix using fixed sizes inside a function could result in a
stack overflow, since Eigen will try to allocate the array automatically as a local variable, and
this is normally done on the stack.
Finally, depending on circumstances, Eigen can also be more aggressive trying to vectorize
(use SIMD instructions) when dynamic sizes are used, see \ref TopicVectorization "Vectorization".

View File

@@ -178,7 +178,7 @@ matNxN = t.linear();
\endcode</td></tr>
<tr><td>
extract the rotation matrix</td><td>\code
matNxN = t.extractRotation();
matNxN = t.rotation();
\endcode</td></tr>
</table>

View File

@@ -130,7 +130,7 @@ Describing the \a buildProblem and \a save functions is out of the scope of this
The SparseMatrix and SparseVector classes take three template arguments:
* the scalar type (e.g., double)
* the storage order (ColMajor or RowMajor, the default is RowMajor)
* the storage order (ColMajor or RowMajor, the default is ColMajor)
* the inner index type (default is \c int).
As for dense Matrix objects, constructors takes the size of the object.

View File

@@ -55,7 +55,7 @@ All combinations are allowed: you can have a matrix with a fixed number of rows
Matrix<double, 6, Dynamic> // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2> // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor> // Fully dynamic, row major (heap allocation)
Matrix<double, 13, 3> // Fully fixed (static allocation)
Matrix<double, 13, 3> // Fully fixed (usually allocated on stack)
\endcode
In most cases, you can simply use one of the convenience typedefs for \ref matrixtypedefs "matrices" and \ref arraytypedefs "arrays". Some examples:

View File

@@ -6,7 +6,6 @@ namespace Eigen {
\section TopicLinAlgBigTable Catalogue of decompositions offered by Eigen
<table class="manual-vl">
<tr>
<th class="meta"></th>
<th class="meta" colspan="5">Generic information, not Eigen-specific</th>

View File

@@ -42,10 +42,10 @@ template<typename MatrixType> void array_for_matrix(const MatrixType& m)
VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());
// reductions
VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.cwiseAbs().maxCoeff());
VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.cwiseAbs().maxCoeff());
VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).cwiseAbs().maxCoeff());
VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).cwiseAbs().maxCoeff());
VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());
VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());
VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).squaredNorm());
VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).squaredNorm());
VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));
// vector-wise ops

View File

@@ -56,12 +56,12 @@ template<typename MatrixType> void diagonal(const MatrixType& m)
VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
m2.diagonal(N1) = 2 * m1.diagonal(N1);
VERIFY_IS_APPROX(m2.diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
m2.diagonal(N1)[0] *= 3;
VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);
m2.diagonal(N2) = 2 * m1.diagonal(N2);
VERIFY_IS_APPROX(m2.diagonal<N2>(), static_cast<Scalar>(2) * m1.diagonal(N2));
VERIFY_IS_APPROX(m2.template diagonal<N2>(), static_cast<Scalar>(2) * m1.diagonal(N2));
m2.diagonal(N2)[0] *= 3;
VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);
}

View File

@@ -171,23 +171,36 @@ template<typename Scalar, int Options> void quaternion(void)
template<typename Scalar> void mapQuaternion(void){
typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
typedef Map<const Quaternion<Scalar>, Aligned> MCQuaternionA;
typedef Map<Quaternion<Scalar> > MQuaternionUA;
typedef Map<const Quaternion<Scalar> > MCQuaternionUA;
typedef Quaternion<Scalar> Quaternionx;
typedef Matrix<Scalar,3,1> Vector3;
typedef AngleAxis<Scalar> AngleAxisx;
Vector3 v0 = Vector3::Random(),
v1 = Vector3::Random();
Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
EIGEN_ALIGN16 Scalar array1[4];
EIGEN_ALIGN16 Scalar array2[4];
EIGEN_ALIGN16 Scalar array3[4+1];
Scalar* array3unaligned = array3+1;
MQuaternionA mq1(array1);
MCQuaternionA mcq1(array1);
MQuaternionA mq2(array2);
MQuaternionUA mq3(array3unaligned);
MCQuaternionUA mcq3(array3unaligned);
// std::cerr << array1 << " " << array2 << " " << array3 << "\n";
MQuaternionA(array1).coeffs().setRandom();
(MQuaternionA(array2)) = MQuaternionA(array1);
(MQuaternionUA(array3unaligned)) = MQuaternionA(array1);
mq1 = AngleAxisx(a, v0.normalized());
mq2 = mq1;
mq3 = mq1;
Quaternionx q1 = MQuaternionA(array1);
Quaternionx q2 = MQuaternionA(array2);
Quaternionx q3 = MQuaternionUA(array3unaligned);
Quaternionx q1 = mq1;
Quaternionx q2 = mq2;
Quaternionx q3 = mq3;
Quaternionx q4 = MCQuaternionUA(array3unaligned);
VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
@@ -197,6 +210,23 @@ template<typename Scalar> void mapQuaternion(void){
if(internal::packet_traits<Scalar>::Vectorizable)
VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));
#endif
VERIFY_IS_APPROX(mq1 * (mq1.inverse() * v1), v1);
VERIFY_IS_APPROX(mq1 * (mq1.conjugate() * v1), v1);
VERIFY_IS_APPROX(mcq1 * (mcq1.inverse() * v1), v1);
VERIFY_IS_APPROX(mcq1 * (mcq1.conjugate() * v1), v1);
VERIFY_IS_APPROX(mq3 * (mq3.inverse() * v1), v1);
VERIFY_IS_APPROX(mq3 * (mq3.conjugate() * v1), v1);
VERIFY_IS_APPROX(mcq3 * (mcq3.inverse() * v1), v1);
VERIFY_IS_APPROX(mcq3 * (mcq3.conjugate() * v1), v1);
VERIFY_IS_APPROX(mq1*mq2, q1*q2);
VERIFY_IS_APPROX(mq3*mq2, q3*q2);
VERIFY_IS_APPROX(mcq1*mq2, q1*q2);
VERIFY_IS_APPROX(mcq3*mq2, q3*q2);
}
template<typename Scalar> void quaternionAlignment(void){

View File

@@ -91,6 +91,12 @@ void testVectorType(const VectorType& base)
scalar.setLinSpaced(1,low,high);
VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );
VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );
// regression test for bug 526 (linear vectorized transversal)
if (size > 1) {
m.tail(size-1).setLinSpaced(low, high);
VERIFY_IS_APPROX(m(size-1), high);
}
}
template<typename MatrixType>

View File

@@ -40,7 +40,7 @@ template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int s
{
for (int i=0; i<size; ++i)
{
if (!internal::isApprox(a[i],b[i]))
if (a[i]!=b[i] && !internal::isApprox(a[i],b[i]))
{
std::cout << "[" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != " << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "\n";
return false;

View File

@@ -178,5 +178,30 @@ initSparse(double density,
}
}
template<typename Scalar> void
initSparse(double density,
Matrix<Scalar,1,Dynamic>& refVec,
SparseVector<Scalar,RowMajor>& sparseVec,
std::vector<int>* zeroCoords = 0,
std::vector<int>* nonzeroCoords = 0)
{
sparseVec.reserve(int(refVec.size()*density));
sparseVec.setZero();
for(int i=0; i<refVec.size(); i++)
{
Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
if (v!=Scalar(0))
{
sparseVec.insertBack(i) = v;
if (nonzeroCoords)
nonzeroCoords->push_back(i);
}
else if (zeroCoords)
zeroCoords->push_back(i);
refVec[i] = v;
}
}
#include <unsupported/Eigen/SparseExtra>
#endif // EIGEN_TESTSPARSE_H

View File

@@ -46,8 +46,10 @@ template<typename SparseMatrixType> void sparse_product()
double density = (std::max)(8./(rows*cols), 0.01);
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
typedef Matrix<Scalar,Dynamic,1> DenseVector;
Scalar s1 = internal::random<Scalar>();
typedef Matrix<Scalar,1,Dynamic> RowDenseVector;
typedef SparseVector<Scalar,0,Index> ColSpVector;
typedef SparseVector<Scalar,RowMajor,Index> RowSpVector;Scalar s1 = internal::random<Scalar>();
Scalar s2 = internal::random<Scalar>();
// test matrix-matrix product
@@ -117,6 +119,21 @@ template<typename SparseMatrixType> void sparse_product()
test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4);
VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6);
// sparse matrix * sparse vector
ColSpVector cv0(cols), cv1;
DenseVector dcv0(cols), dcv1;
initSparse(2*density,dcv0, cv0);
RowSpVector rv0(depth), rv1;
RowDenseVector drv0(depth), drv1(rv1);
initSparse(2*density,drv0, rv0);
VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3);
VERIFY_IS_APPROX(rv1=rv0*m3, drv1=drv0*refMat3);
VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0);
VERIFY_IS_APPROX(cv1=m3t.adjoint()*cv0, dcv1=refMat3t.adjoint()*dcv0);
VERIFY_IS_APPROX(rv1=m3*cv0, drv1=refMat3*dcv0);
}
// test matrix - diagonal product

View File

@@ -82,6 +82,12 @@ template<typename Scalar> void sparse_vector(int rows, int cols)
VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1));
VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval()));
VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1));
// sparse matrix to sparse vector
SparseMatrixType mv1;
VERIFY_IS_APPROX((mv1=v1),v1);
VERIFY_IS_APPROX(mv1,(v1=mv1));
VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));
}

View File

@@ -1,4 +1,4 @@
// This file is part of Eugenio, a lightweight C++ template library
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>

View File

@@ -62,7 +62,9 @@ void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV)
Scalar rho, rho_1, alpha;
d.setZero();
CINV.startFill(); // FIXME estimate the number of non-zeros
typedef Triplet<double> T;
std::vector<T> tripletList;
for (Index i = 0; i < rows; ++i)
{
d[i] = 1.0;
@@ -88,11 +90,12 @@ void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV)
// FIXME add a generic "prune/filter" expression for both dense and sparse object to sparse
for (Index j=0; j<l.size(); ++j)
if (l[j]<1e-15)
CINV.fill(i,j) = l[j];
tripletList.push_back(T(i,j,l(j)));
d[i] = 0.0;
}
CINV.endFill();
CINV.setFromTriplets(tripletList.begin(), tripletList.end());
}
@@ -107,6 +110,7 @@ template<typename TMatrix, typename CMatrix,
void constrained_cg(const TMatrix& A, const CMatrix& C, VectorX& x,
const VectorB& b, const VectorF& f, IterationController &iter)
{
using std::sqrt;
typedef typename TMatrix::Scalar Scalar;
typedef typename TMatrix::Index Index;
typedef Matrix<Scalar,Dynamic,1> TmpVec;