530 lines
15 KiB
C++
530 lines
15 KiB
C++
//===-- test_funcs.cpp - test duals/dual ------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the cppduals project.
|
|
// https://gitlab.com/tesch1/cppduals
|
|
//
|
|
// See https://gitlab.com/tesch1/cppduals/blob/master/LICENSE.txt for
|
|
// license information.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// (c)2019 Michael Tesch. tesch1@gmail.com
|
|
//
|
|
/**
|
|
* \file test_eigen Dual number Eigen integration tests
|
|
*
|
|
* (c)2019 Michael Tesch. tesch1@gmail.com
|
|
*/
|
|
|
|
#include <duals/dual_eigen>
|
|
#include "type_name.hpp"
|
|
#include <Eigen/Dense>
|
|
#include <Eigen/Sparse>
|
|
#include <Eigen/StdVector>
|
|
|
|
#include <unsupported/Eigen/MatrixFunctions>
|
|
//#include <unsupported/Eigen/AutoDiff>
|
|
#include "eexpokit/padm.hpp"
|
|
#include "gtest/gtest.h"
|
|
|
|
using duals::rpart;
|
|
using duals::dpart;
|
|
using duals::dualf;
|
|
using duals::duald;
|
|
using duals::dualld;
|
|
using duals::hyperdualf;
|
|
using duals::hyperduald;
|
|
using duals::hyperdualld;
|
|
using duals::is_dual;
|
|
using duals::is_complex;
|
|
using duals::dual_traits;
|
|
using namespace duals::literals;
|
|
|
|
typedef long double ldouble;
|
|
typedef std::complex<float> complexf;
|
|
typedef std::complex<double> complexd;
|
|
typedef std::complex<long double> complexld;
|
|
typedef std::complex<dualf> cdualf;
|
|
typedef std::complex<duald> cduald;
|
|
typedef std::complex<dualld> cdualld;
|
|
|
|
template <class eT, int N=Eigen::Dynamic, int K = N> using emtx = Eigen::Matrix<eT, N, K>;
|
|
template <class eT> using smtx = Eigen::SparseMatrix<eT>;
|
|
|
|
template <int N=2, int K = N> using ecf = Eigen::Matrix<complexf, N, K> ;
|
|
template <int N=2, int K = N> using edf = Eigen::Matrix<dualf, N, K> ;
|
|
template <int N=2, int K = N> using ecdf = Eigen::Matrix<cdualf, N, K> ;
|
|
|
|
#define _EXPECT_TRUE(...) {typedef __VA_ARGS__ tru; EXPECT_TRUE(tru::value); static_assert(tru::value, "sa"); }
|
|
#define _EXPECT_FALSE(...) {typedef __VA_ARGS__ fal; EXPECT_FALSE(fal::value); static_assert(!fal::value, "sa"); }
|
|
#define EXPECT_DEQ(A,B) EXPECT_EQ(rpart(A), rpart(B)); EXPECT_EQ(dpart(A), dpart(B))
|
|
#define ASSERT_DEQ(A,B) ASSERT_EQ(rpart(A), rpart(B)); ASSERT_EQ(dpart(A), dpart(B))
|
|
#define EXPECT_DNE(A,B) EXPECT_NE(rpart(A), rpart(B)); EXPECT_NE(dpart(A), dpart(B))
|
|
#define EXPECT_DNEAR(A,B,tol) \
|
|
EXPECT_NEAR(rpart(A), rpart(B),tol); \
|
|
EXPECT_NEAR(dpart(A), dpart(B),tol)
|
|
|
|
|
|
TEST(Eigen, NumTraits) {
|
|
//::testing::StaticAssertTypeEq<Eigen::NumTraits<duals::dual<float>>::Real, float>();
|
|
_EXPECT_TRUE(std::is_same<typename Eigen::NumTraits<duals::dual<float>>::Real, dualf>);
|
|
_EXPECT_TRUE(std::is_same<typename Eigen::NumTraits<cdualf>::Real, dualf>);
|
|
|
|
EXPECT_EQ(Eigen::NumTraits<duals::dual<float>>::dummy_precision(),
|
|
Eigen::NumTraits<float>::dummy_precision());
|
|
EXPECT_EQ(Eigen::NumTraits<duals::dual<float>>::digits10(),
|
|
Eigen::NumTraits<float>::digits10());
|
|
|
|
EXPECT_EQ(Eigen::NumTraits<cdualf>::dummy_precision(),
|
|
Eigen::NumTraits<float>::dummy_precision());
|
|
}
|
|
|
|
TEST(Eigen, construction)
|
|
{
|
|
emtx<double> ed;
|
|
emtx<float> ef;
|
|
emtx<complexd> ecd;
|
|
emtx<complexf> ecf;
|
|
emtx<duald> edd;
|
|
emtx<dualf> edf_;
|
|
emtx<cduald> ecdd;
|
|
emtx<cdualf> ecdf_;
|
|
}
|
|
|
|
TEST(Eigen, sparse)
|
|
{
|
|
smtx<double> ed;
|
|
smtx<float> ef;
|
|
smtx<complexd> ecd;
|
|
smtx<complexf> ecf;
|
|
smtx<duald> edd;
|
|
smtx<dualf> edf_;
|
|
smtx<cduald> ecdd;
|
|
smtx<cdualf> ecdf_;
|
|
}
|
|
|
|
TEST(Eigen, expr_type_dense) {
|
|
emtx<double> ed;
|
|
emtx<float> ef;
|
|
emtx<complexd> ecd;
|
|
emtx<complexf> ecf;
|
|
emtx<duald> edd;
|
|
emtx<dualf> edf_;
|
|
emtx<cduald> ecdd;
|
|
emtx<cdualf> ecdf_;
|
|
|
|
//_EXPECT_TRUE(std::is_base_of<Eigen::EigenBase<U>,U >::value);
|
|
|
|
//_EXPECT_TRUE(std::is_same<std::common_type<emtx<dualf>,dualf>::type, emtx<dualf>>);
|
|
ecf = ecf * 1;
|
|
#define PO_EXPR_TYPE(...) typename std::decay<decltype( __VA_ARGS__ )>::type::PlainObject
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf*1), emtx<complexf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf + ecf), emtx<complexf>>);
|
|
//_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf * edf_), emtx<cdualf>>); [1]
|
|
//_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf * 1_ef), emtx<cdualf>>); [1]
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf * cdualf(1,2)), emtx<cdualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edf_ * 2), emtx<dualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edf_ * cdualf(2,2)), emtx<cdualf>>);
|
|
static_assert(!duals::can_promote<dualf, emtx<dualf>>::value, "nope");
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edf_ * 2_ef), emtx<dualf>>);
|
|
//_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edf_ * 2_e), emtx<duald>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecf * complexf(1,2)), emtx<complexf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecdf_ * 1), emtx<cdualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecdf_ * 2_ef), emtx<cdualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecdf_ * complexf(1,2)), emtx<cdualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ecdf_ * cdualf(1_ef,2_ef)), emtx<cdualf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edd * 1_e), emtx<duald>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(edd * 1_ef), emtx<duald>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(ed*1), emtx<double>>);
|
|
|
|
auto a1 = ecf * 1;
|
|
auto a2 = ecf * ecf;
|
|
//auto a3 = ecf * edf_; [1]
|
|
//auto a4 = ecf * 1_ef; [1]
|
|
auto a5 = ecf * cdualf(1,2);
|
|
auto a6 = edf_ * 2;
|
|
auto a7 = edf_ * 2_ef;
|
|
auto a8 = ecf * complexf(1,2);
|
|
auto a9 = ecdf_ * 1;
|
|
ecdf_ = ecdf_ * complexf(1,2);
|
|
ecdf_ = ecdf_ * cdualf(1_ef,2_ef);
|
|
auto a12 = edd * 1_e;
|
|
auto a13 = ed * 1;
|
|
auto A1 = a1.eval(); A1 += A1;
|
|
auto A2 = a2.eval(); A2 += A2;
|
|
//auto A3 = a3.eval(); A3 += A3; [1]
|
|
//auto A4 = a4.eval(); A4 += A4; [1]
|
|
auto A5 = a5.eval(); A5 += A5;
|
|
auto A6 = a6.eval(); A6 += A6;
|
|
auto A7 = a7.eval(); A7 += A7;
|
|
auto A8 = a8.eval(); A8 += A8;
|
|
auto A9 = a9.eval(); A9 += A9;
|
|
auto A12 = a12.eval(); A12 += A12;
|
|
auto A13 = a13.eval(); A13 += A13;
|
|
}
|
|
|
|
TEST(init, Constant) {
|
|
edf<3> a = edf<3>::Constant(3,3, 5 + 8_ef);
|
|
ecdf<3> b = ecdf<3>::Constant(3,3, cdualf(4,2 + 3_ef));
|
|
|
|
EXPECT_EQ(a(1,1), 5 + 8_ef);
|
|
EXPECT_EQ(b(0,1), cdualf(4,2 + 3_ef));
|
|
EXPECT_TRUE((a.array() < 6).all());
|
|
EXPECT_FALSE((a.array() != 5 + 8_ef).any());
|
|
EXPECT_EQ((a.array() == 5 + 8_ef).count(), 9);
|
|
}
|
|
|
|
TEST(init, setIdentity) {
|
|
edf<3> a = edf<3>::Constant(3,3, 5 + 8_ef);
|
|
ecdf<3> b = ecdf<3>::Constant(3,3, cdualf(4,2 + 3_ef));
|
|
a.setIdentity();
|
|
b.setIdentity();
|
|
|
|
EXPECT_EQ(a(0,0), 1);
|
|
EXPECT_EQ(a(0,1), 0);
|
|
EXPECT_EQ(a(0,2), 0);
|
|
EXPECT_EQ(a(1,0), 0);
|
|
EXPECT_EQ(a(1,1), 1);
|
|
EXPECT_EQ(a(1,2), 0);
|
|
EXPECT_EQ(a(2,0), 0);
|
|
EXPECT_EQ(a(2,1), 0);
|
|
EXPECT_EQ(a(2,2), 1);
|
|
|
|
EXPECT_EQ(b(0,0).real(), 1);
|
|
EXPECT_EQ(b(0,1).real(), 0);
|
|
EXPECT_EQ(b(0,2).real(), 0);
|
|
EXPECT_EQ(b(1,0).real(), 0);
|
|
EXPECT_EQ(b(1,1).real(), 1);
|
|
EXPECT_EQ(b(1,2).real(), 0);
|
|
EXPECT_EQ(b(2,0).real(), 0);
|
|
EXPECT_EQ(b(2,1).real(), 0);
|
|
EXPECT_EQ(b(2,2).real(), 1);
|
|
}
|
|
|
|
TEST(init, setZero) {
|
|
edf<3> a = edf<3>::Constant(3,3, 5 + 8_ef);
|
|
ecdf<3> b = ecdf<3>::Constant(3,3, cdualf(4,2 + 3_ef));
|
|
|
|
EXPECT_EQ(a(1,1), 5 + 8_ef);
|
|
|
|
a.setZero();
|
|
b.setZero();
|
|
|
|
EXPECT_EQ(a(0,0), 0);
|
|
EXPECT_EQ(a(0,1), 0);
|
|
EXPECT_EQ(a(0,2), 0);
|
|
EXPECT_EQ(a(1,0), 0);
|
|
EXPECT_EQ(a(1,1), 0);
|
|
EXPECT_EQ(a(1,2), 0);
|
|
EXPECT_EQ(a(2,0), 0);
|
|
EXPECT_EQ(a(2,1), 0);
|
|
EXPECT_EQ(a(2,2), 0);
|
|
|
|
EXPECT_EQ(b(0,0).real(), 0);
|
|
EXPECT_EQ(b(0,1).real(), 0);
|
|
EXPECT_EQ(b(0,2).real(), 0);
|
|
EXPECT_EQ(b(1,0).real(), 0);
|
|
EXPECT_EQ(b(1,1).real(), 0);
|
|
EXPECT_EQ(b(1,2).real(), 0);
|
|
EXPECT_EQ(b(2,0).real(), 0);
|
|
EXPECT_EQ(b(2,1).real(), 0);
|
|
EXPECT_EQ(b(2,2).real(), 0);
|
|
EXPECT_EQ(b(0,0).imag(), 0);
|
|
EXPECT_EQ(b(0,1).imag(), 0);
|
|
EXPECT_EQ(b(0,2).imag(), 0);
|
|
EXPECT_EQ(b(1,0).imag(), 0);
|
|
EXPECT_EQ(b(1,1).imag(), 0);
|
|
EXPECT_EQ(b(1,2).imag(), 0);
|
|
EXPECT_EQ(b(2,0).imag(), 0);
|
|
EXPECT_EQ(b(2,1).imag(), 0);
|
|
EXPECT_EQ(b(2,2).imag(), 0);
|
|
}
|
|
|
|
TEST(init, LinSpaced) {
|
|
ecf<3,1> a = ecf<3,1>::LinSpaced(3, 4, complexf(6,7));
|
|
EXPECT_EQ(a(0).real(), 4);
|
|
EXPECT_EQ(a(1).real(), 5);
|
|
EXPECT_EQ(a(2).real(), 6);
|
|
|
|
edf<3,1> b = edf<3,1>::LinSpaced(3, 4, 6 + 6_ef);
|
|
EXPECT_EQ(b(0), 4);
|
|
EXPECT_EQ(b(1), 5 + 3_ef);
|
|
EXPECT_EQ(b(2), 6 + 6_ef);
|
|
}
|
|
|
|
TEST(init, Random) {
|
|
complexf c = emtx<complexf,1>::Random()(0,0);
|
|
EXPECT_NE(c.real(), 0);
|
|
EXPECT_NE(c.imag(), 0);
|
|
|
|
typedef dualf Rt;
|
|
using duals::random;
|
|
|
|
Rt b = emtx<Rt,1>::Random()(0,0);
|
|
EXPECT_NE(b.rpart(), 0);
|
|
//EXPECT_NE(b.dpart(), 0); //
|
|
|
|
edf<3> j = edf<3>::Random(3,3);
|
|
EXPECT_NE(j(1,2).rpart(), 0);
|
|
//EXPECT_NE(j(2,0).dpart(), 0); //
|
|
|
|
ecdf<3> k = ecdf<3>::Random(3,3);
|
|
EXPECT_NE(k(0,1).real().rpart(), 0);
|
|
//EXPECT_NE(k(1,1).imag().dpart(), 0); //
|
|
|
|
using duals::randos::random2;
|
|
dualf x = random2<dualf>();
|
|
EXPECT_NE(x.rpart(), 0);
|
|
EXPECT_NE(x.dpart(), 0);
|
|
|
|
duald y = random2<duald>();
|
|
EXPECT_NE(y.rpart(), 0);
|
|
EXPECT_NE(y.dpart(), 0);
|
|
|
|
//EXPECT_NE(k(1,1).imag().dpart(), 0); //
|
|
}
|
|
|
|
TEST(assign, ops) {
|
|
emtx<double> ed;
|
|
emtx<float> ef;
|
|
emtx<complexd> ecd;
|
|
emtx<complexf> ecf;
|
|
emtx<duald> edd;
|
|
emtx<dualf> edf_;
|
|
emtx<cduald> ecdd;
|
|
emtx<cdualf> ecdf_;
|
|
|
|
ed *= 2;
|
|
ef *= 2;
|
|
|
|
//ecd *= 2;
|
|
//ecf *= 2;
|
|
//ecd *= 2_e;
|
|
//ecf *= 2_ef;
|
|
|
|
edd *= 2;
|
|
edf_ *= 2;
|
|
edd *= 2_e;
|
|
edf_ *= 2_ef;
|
|
//ecdd *= 2;
|
|
// ecdf_ *= 2;
|
|
}
|
|
|
|
TEST(Array, math) {
|
|
int N = 5;
|
|
|
|
emtx<float> x(N,1);
|
|
emtx<float> y(N,1);
|
|
emtx<float> z(N,1);
|
|
|
|
x.array() += 1;
|
|
x += y + z;
|
|
x *= 2;
|
|
|
|
emtx<duald> a(N,1);
|
|
emtx<duald> A(N,1);
|
|
emtx<duald> c(N,1);
|
|
a.array() = 1 + 1_e;
|
|
a.array() += 3_e;
|
|
a.array() = 0;
|
|
a.array() += 1;
|
|
A.array() += 2;
|
|
c = a + A;
|
|
c = a * 2;
|
|
c = a * 2_e;
|
|
c = 2 * a;
|
|
c = (3 + 2_e) * a;
|
|
c *= 3;
|
|
c *= 3_e;
|
|
EXPECT_EQ(c(N-1), 27_e);
|
|
}
|
|
|
|
TEST(access, CwiseRpartOp) {
|
|
// on float matrices (pass-through)
|
|
emtx<float,3> a, b = emtx<float,3>::Random();
|
|
a = b.unaryExpr(duals::CwiseRpartOp<float>());
|
|
EXPECT_NE(a.norm(), 0);
|
|
|
|
// on dual<float> matrices
|
|
emtx<dualf,3> d;
|
|
a = d.unaryExpr(duals::CwiseRpartOp<dualf>());
|
|
a = d.unaryExpr(duals::CwiseDpartOp<dualf>());
|
|
a = rpart(d);
|
|
a = dpart(d);
|
|
|
|
// on complex<dual<float>> matrices
|
|
emtx<complexf,3> g, f = emtx<complexf,3>::Random();
|
|
emtx<cdualf,3> e;
|
|
e.array() = f.array().cast<cdualf>() - 1_ef * f.array().cast<cdualf>();
|
|
g = e.unaryExpr(duals::CwiseRpartOp<cdualf>());
|
|
EXPECT_EQ((f-g).norm(), 0);
|
|
g = f.unaryExpr(duals::CwiseRpartOp<complexf>());
|
|
EXPECT_EQ((f-g).norm(), 0);
|
|
g = rpart(f);
|
|
EXPECT_EQ((f-g).norm(), 0);
|
|
|
|
g = e.unaryExpr(duals::CwiseDpartOp<cdualf>());
|
|
EXPECT_EQ((f+g).norm(), 0);
|
|
g = f.unaryExpr(duals::CwiseDpartOp<complexf>());
|
|
EXPECT_EQ((g).norm(), 0);
|
|
g = dpart(f);
|
|
EXPECT_EQ((g).norm(), 0);
|
|
}
|
|
|
|
TEST(access, CwiseDpartOp) {
|
|
// on float matrices (pass-through)
|
|
emtx<float,3> a, b = emtx<float,3>::Random();
|
|
a = b.unaryExpr(duals::CwiseDpartOp<float>());
|
|
EXPECT_EQ(a.norm(), 0);
|
|
|
|
// on dual<float> matrices
|
|
emtx<dualf,3> d = b - 1_ef * b;
|
|
a = d.unaryExpr(duals::CwiseDpartOp<dualf>());
|
|
EXPECT_NE(a.norm(), 0);
|
|
EXPECT_EQ((a+b).norm(), 0);
|
|
|
|
// on complex<dual<float>> matrices
|
|
emtx<complexf,3> g, f = emtx<complexf,3>::Random();
|
|
emtx<cdualf,3> e;
|
|
e.array() = f.array().cast<cdualf>() - 1_ef * f.array().cast<cdualf>();
|
|
|
|
g = e.unaryExpr(duals::CwiseDpartOp<cdualf>());
|
|
EXPECT_EQ((g+f).norm(), 0);
|
|
d = e.real();
|
|
EXPECT_NE(d.norm(), 0);
|
|
}
|
|
|
|
TEST(measure, norm) {
|
|
typedef emtx<complexf, 3> MatrixC;
|
|
MatrixC c = (MatrixC() << 1,2,3, 4,5,6, 7,8,9).finished();
|
|
|
|
EXPECT_EQ(c.cwiseAbs().colwise().sum().maxCoeff(), complexf(18));
|
|
//EXPECT_EQ(c.maxCoeff(), complexf(9));
|
|
|
|
//typedef duald Rt;
|
|
typedef dualf Rt;
|
|
//typedef cdualf Rt;
|
|
typedef emtx<Rt, 3> MatrixD;
|
|
Rt b = 1+0_ef;
|
|
b = 3;
|
|
Rt d(1);
|
|
MatrixD x;
|
|
x.array() = d;
|
|
MatrixD a = (MatrixD() << 1,2,3, 4,5+5_ef,6, 7,8,9).finished();
|
|
//typename MatrixD::Index index;
|
|
|
|
EXPECT_EQ(a.sum(), 45 + 5_ef);
|
|
EXPECT_EQ(x.sum(), 9);
|
|
EXPECT_NEAR(rpart(a.norm()), 16.8819430161341337282, 1e-5);
|
|
EXPECT_NEAR(rpart(a.mean()), 5, 1e-5);
|
|
EXPECT_NEAR(dpart(a.mean()), 0.555555555555555, 1e-5);
|
|
EXPECT_EQ(a.minCoeff(), 1);
|
|
EXPECT_EQ(a.maxCoeff(), 9);
|
|
EXPECT_EQ(a.trace(), 15 + 5_ef);
|
|
EXPECT_EQ(a.squaredNorm(), 285+0_e);
|
|
EXPECT_EQ(a.lpNorm<1>(), 45 + 5_ef);
|
|
//EXPECT_EQ(a.lpNorm<Eigen::Infinity>(), 9);
|
|
// 1-norm
|
|
//EXPECT_EQ(a.colwise().lpNorm<1>().maxCoeff(), 45 + 5_ef);
|
|
EXPECT_EQ(a.cwiseAbs().colwise().sum().maxCoeff(), 18);
|
|
|
|
}
|
|
|
|
TEST(dual_decay, stat) {
|
|
emtx<float> ef;
|
|
emtx<complexd> ecd;
|
|
emtx<complexf> ecf;
|
|
emtx<duald> edd;
|
|
emtx<dualf> edf_;
|
|
emtx<cduald> ecdd;
|
|
emtx<cdualf> ecdf_;
|
|
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(rpart(ef)), emtx<float>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(dpart(ef)), emtx<float>>);
|
|
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(rpart(edf_)), emtx<float>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(dpart(edf_)), emtx<float>>);
|
|
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(rpart(ecdf_)), emtx<complexf>>);
|
|
_EXPECT_TRUE(std::is_same<PO_EXPR_TYPE(dpart(ecdf_)), emtx<complexf>>);
|
|
}
|
|
|
|
TEST(dpart, matrix) {
|
|
emtx<float,3> a = emtx<float,3>::Random(3,3);
|
|
emtx<float,3> b = emtx<float,3>::Random(3,3);
|
|
emtx<float,3> c = emtx<float,3>::Random(3,3);
|
|
emtx<float,3> d = emtx<float,3>::Random(3,3);
|
|
emtx<dualf,3> A = a + 1_ef * b;
|
|
emtx<dualf,3> B = c + 1_ef * d;
|
|
emtx<cdualf,3> AA;
|
|
emtx<complexf,3> BB,CC;
|
|
AA.real() = A;
|
|
AA.imag() = B;
|
|
BB.real() = a;
|
|
BB.imag() = c;
|
|
CC.real() = b;
|
|
CC.imag() = d;
|
|
|
|
EXPECT_EQ((rpart(A) - a).norm(),0);
|
|
EXPECT_EQ((dpart(A) - b).norm(),0);
|
|
|
|
EXPECT_EQ((rpart(AA) - BB).norm(),0);
|
|
EXPECT_EQ((dpart(AA) - CC).norm(),0);
|
|
}
|
|
|
|
TEST(eigen, exp_typechecks) {
|
|
typedef emtx<dualf,3> Mat;
|
|
typedef emtx<duald,3> Matd;
|
|
EXPECT_FALSE(Eigen::internal::is_exp_known_type<typename Mat::Scalar>::value);
|
|
EXPECT_FALSE(Eigen::internal::is_exp_known_type<typename Matd::Scalar>::value);
|
|
|
|
typedef emtx<cdualf,3> Matc;
|
|
typedef emtx<cduald,3> Matcd;
|
|
EXPECT_FALSE(Eigen::internal::is_exp_known_type<typename Matc::Scalar>::value);
|
|
EXPECT_FALSE(Eigen::internal::is_exp_known_type<typename Matcd::Scalar>::value);
|
|
}
|
|
|
|
const bool _exp = true;
|
|
const bool _padm = false;
|
|
|
|
#define TEST_EXP(SCALAR_T, SIDE, EXP_OR_PADM) \
|
|
TEST(func, exp_##SCALAR_T##_##SIDE##EXP_OR_PADM) { \
|
|
emtx<SCALAR_T, SIDE> a,b; \
|
|
a = emtx<SCALAR_T, SIDE>::Random(); \
|
|
a.setZero(); \
|
|
if (EXP_OR_PADM == _exp) a = a.exp(); \
|
|
else a = eexpokit::padm(a); \
|
|
EXPECT_LT((a - emtx<SCALAR_T, SIDE>::Identity()).norm(), 1e-6) << "a=" << a << "\n"; \
|
|
}
|
|
|
|
#define TEST_EXP_SIZES(SCALAR_T, EXP_OR_PADM) \
|
|
TEST_EXP(SCALAR_T, 3, EXP_OR_PADM) \
|
|
TEST_EXP(SCALAR_T, 4, EXP_OR_PADM) \
|
|
TEST_EXP(SCALAR_T, 17, EXP_OR_PADM)
|
|
|
|
#define TEST_EXP_SIZES_EOP(SCALAR_T) \
|
|
TEST_EXP_SIZES(SCALAR_T, _padm) \
|
|
TEST_EXP_SIZES(SCALAR_T, _exp)
|
|
|
|
// just make sure padm is working
|
|
TEST_EXP_SIZES_EOP(float)
|
|
TEST_EXP_SIZES_EOP(double)
|
|
TEST_EXP_SIZES_EOP(ldouble)
|
|
TEST_EXP_SIZES_EOP(complexf)
|
|
TEST_EXP_SIZES_EOP(complexd)
|
|
TEST_EXP_SIZES_EOP(complexld)
|
|
|
|
/* testing engine */
|
|
#define QUOTE(...) STRFY(__VA_ARGS__)
|
|
#define STRFY(...) #__VA_ARGS__
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
std::cout << "OPT_FLAGS=" << QUOTE(OPT_FLAGS) << "\n";
|
|
std::cout << "INSTRUCTIONSET=" << Eigen::SimdInstructionSetsInUse() << "\n";
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
std::cout.precision(20);
|
|
std::cerr.precision(20);
|
|
return RUN_ALL_TESTS();
|
|
}
|