2017-01-24 17:55:12 +08:00
|
|
|
// This file is part of Eigen, a lightweight C++ template library
|
|
|
|
// for linear algebra.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
|
|
//
|
|
|
|
// 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/.
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
Move Eigen::all,last,lastp1,lastN to Eigen::placeholders::.
These names are so common, IMO they should not exist directly in the
`Eigen::` namespace. This prevents us from using the `last` or `all`
names for any parameters or local variables, otherwise spitting out
warnings about shadowing or hiding the global values. Many external
projects (and our own examples) also heavily use
```
using namespace Eigen;
```
which means these conflict with external libraries as well, e.g.
`std::fill(first,last,value)`.
It seems originally these were placed in a separate namespace
`Eigen::placeholders`, which has since been deprecated. I propose
to un-deprecate this, and restore the original locations.
These symbols are also imported into `Eigen::indexing`, which
additionally imports `fix` and `seq`. An alternative is to remove the
`placeholders` namespace and stick with `indexing`.
NOTE: this is an API-breaking change.
Fixes #2321.
2021-09-16 05:10:29 +08:00
|
|
|
using Eigen::placeholders::all;
|
|
|
|
using Eigen::placeholders::last;
|
|
|
|
using Eigen::placeholders::lastp1;
|
|
|
|
|
2017-01-24 17:55:12 +08:00
|
|
|
template <typename T1, typename T2>
|
|
|
|
bool is_same_symb(const T1& a, const T2& b, Index size) {
|
|
|
|
return a.eval(last = size - 1) == b.eval(last = size - 1);
|
|
|
|
}
|
|
|
|
|
2018-07-12 15:59:00 +08:00
|
|
|
template <typename T>
|
|
|
|
void check_is_symbolic(const T&) {
|
2018-09-15 20:16:20 +08:00
|
|
|
STATIC_CHECK((symbolic::is_symbolic<T>::value))
|
2018-07-12 15:59:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void check_isnot_symbolic(const T&) {
|
2018-09-15 20:16:20 +08:00
|
|
|
STATIC_CHECK((!symbolic::is_symbolic<T>::value))
|
2018-07-12 15:59:00 +08:00
|
|
|
}
|
2017-01-24 17:55:12 +08:00
|
|
|
|
|
|
|
#define VERIFY_EQ_INT(A, B) VERIFY_IS_APPROX(int(A), int(B))
|
|
|
|
|
|
|
|
void check_symbolic_index() {
|
2018-07-12 15:59:00 +08:00
|
|
|
check_is_symbolic(last);
|
2018-09-15 20:35:10 +08:00
|
|
|
check_is_symbolic(lastp1);
|
2018-07-12 15:59:00 +08:00
|
|
|
check_is_symbolic(last + 1);
|
2018-09-15 20:35:10 +08:00
|
|
|
check_is_symbolic(last - lastp1);
|
|
|
|
check_is_symbolic(2 * last - lastp1 / 2);
|
2018-07-12 15:59:00 +08:00
|
|
|
check_isnot_symbolic(fix<3>());
|
|
|
|
|
2017-01-24 17:55:12 +08:00
|
|
|
Index size = 100;
|
|
|
|
|
|
|
|
// First, let's check FixedInt arithmetic:
|
|
|
|
VERIFY(is_same_type((fix<5>() - fix<3>()) * fix<9>() / (-fix<3>()), fix<-(5 - 3) * 9 / 3>()));
|
|
|
|
VERIFY(is_same_type((fix<5>() - fix<3>()) * fix<9>() / fix<2>(), fix<(5 - 3) * 9 / 2>()));
|
|
|
|
VERIFY(is_same_type(fix<9>() / fix<2>(), fix<9 / 2>()));
|
|
|
|
VERIFY(is_same_type(fix<9>() % fix<2>(), fix<9 % 2>()));
|
|
|
|
VERIFY(is_same_type(fix<9>() & fix<2>(), fix<9 & 2>()));
|
|
|
|
VERIFY(is_same_type(fix<9>() | fix<2>(), fix<9 | 2>()));
|
|
|
|
VERIFY(is_same_type(fix<9>() / 2, int(9 / 2)));
|
|
|
|
|
2018-09-15 20:35:10 +08:00
|
|
|
VERIFY(is_same_symb(lastp1 - 1, last, size));
|
2021-08-30 23:06:55 +08:00
|
|
|
VERIFY(is_same_symb(lastp1 - fix<1>(), last, size));
|
2017-01-24 17:55:12 +08:00
|
|
|
|
|
|
|
VERIFY_IS_EQUAL(((last * 5 - 2) / 3).eval(last = size - 1), ((size - 1) * 5 - 2) / 3);
|
2021-08-30 23:06:55 +08:00
|
|
|
VERIFY_IS_EQUAL(((last * fix<5>() - fix<2>()) / fix<3>()).eval(last = size - 1), ((size - 1) * 5 - 2) / 3);
|
2018-09-15 20:35:10 +08:00
|
|
|
VERIFY_IS_EQUAL((-last * lastp1).eval(last = size - 1), -(size - 1) * size);
|
|
|
|
VERIFY_IS_EQUAL((lastp1 - 3 * last).eval(last = size - 1), size - 3 * (size - 1));
|
|
|
|
VERIFY_IS_EQUAL(((lastp1 - 3 * last) / lastp1).eval(last = size - 1), (size - 3 * (size - 1)) / size);
|
2017-01-24 23:27:51 +08:00
|
|
|
|
|
|
|
{
|
2018-09-15 20:16:20 +08:00
|
|
|
struct x_tag {};
|
|
|
|
static const symbolic::SymbolExpr<x_tag> x;
|
|
|
|
struct y_tag {};
|
|
|
|
static const symbolic::SymbolExpr<y_tag> y;
|
|
|
|
struct z_tag {};
|
|
|
|
static const symbolic::SymbolExpr<z_tag> z;
|
2017-01-24 23:27:51 +08:00
|
|
|
|
|
|
|
VERIFY_IS_APPROX(int(((x + 3) / y + z).eval(x = 6, y = 3, z = -13)), (6 + 3) / 3 + (-13));
|
|
|
|
}
|
2017-01-24 17:55:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EIGEN_DECLARE_TEST(symbolic_index) { CALL_SUBTEST_1(check_symbolic_index()); }
|