Home | History | Annotate | Download | only in test
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5
     12 
     13 #include "main.h"
     14 #include <QtCore/QVector>
     15 #include <Eigen/Geometry>
     16 #include <Eigen/QtAlignedMalloc>
     17 
     18 template<typename MatrixType>
     19 void check_qtvector_matrix(const MatrixType& m)
     20 {
     21   typedef typename MatrixType::Index Index;
     22 
     23   Index rows = m.rows();
     24   Index cols = m.cols();
     25   MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
     26   QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);
     27   for(int i = 0; i < 20; i++)
     28   {
     29     VERIFY_IS_APPROX(w[i], y);
     30   }
     31   v[5] = x;
     32   w[6] = v[5];
     33   VERIFY_IS_APPROX(w[6], v[5]);
     34   v = w;
     35   for(int i = 0; i < 20; i++)
     36   {
     37     VERIFY_IS_APPROX(w[i], v[i]);
     38   }
     39 
     40   v.resize(21);
     41   v[20] = x;
     42   VERIFY_IS_APPROX(v[20], x);
     43   v.fill(y,22);
     44   VERIFY_IS_APPROX(v[21], y);
     45   v.push_back(x);
     46   VERIFY_IS_APPROX(v[22], x);
     47   VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
     48 
     49   // do a lot of push_back such that the vector gets internally resized
     50   // (with memory reallocation)
     51   MatrixType* ref = &w[0];
     52   for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
     53     v.push_back(w[i%w.size()]);
     54   for(int i=23; i<v.size(); ++i)
     55   {
     56     VERIFY(v[i]==w[(i-23)%w.size()]);
     57   }
     58 }
     59 
     60 template<typename TransformType>
     61 void check_qtvector_transform(const TransformType&)
     62 {
     63   typedef typename TransformType::MatrixType MatrixType;
     64   TransformType x(MatrixType::Random()), y(MatrixType::Random());
     65   QVector<TransformType> v(10), w(20, y);
     66   v[5] = x;
     67   w[6] = v[5];
     68   VERIFY_IS_APPROX(w[6], v[5]);
     69   v = w;
     70   for(int i = 0; i < 20; i++)
     71   {
     72     VERIFY_IS_APPROX(w[i], v[i]);
     73   }
     74 
     75   v.resize(21);
     76   v[20] = x;
     77   VERIFY_IS_APPROX(v[20], x);
     78   v.fill(y,22);
     79   VERIFY_IS_APPROX(v[21], y);
     80   v.push_back(x);
     81   VERIFY_IS_APPROX(v[22], x);
     82   VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
     83 
     84   // do a lot of push_back such that the vector gets internally resized
     85   // (with memory reallocation)
     86   TransformType* ref = &w[0];
     87   for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
     88     v.push_back(w[i%w.size()]);
     89   for(unsigned int i=23; int(i)<v.size(); ++i)
     90   {
     91     VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());
     92   }
     93 }
     94 
     95 template<typename QuaternionType>
     96 void check_qtvector_quaternion(const QuaternionType&)
     97 {
     98   typedef typename QuaternionType::Coefficients Coefficients;
     99   QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
    100   QVector<QuaternionType> v(10), w(20, y);
    101   v[5] = x;
    102   w[6] = v[5];
    103   VERIFY_IS_APPROX(w[6], v[5]);
    104   v = w;
    105   for(int i = 0; i < 20; i++)
    106   {
    107     VERIFY_IS_APPROX(w[i], v[i]);
    108   }
    109 
    110   v.resize(21);
    111   v[20] = x;
    112   VERIFY_IS_APPROX(v[20], x);
    113   v.fill(y,22);
    114   VERIFY_IS_APPROX(v[21], y);
    115   v.push_back(x);
    116   VERIFY_IS_APPROX(v[22], x);
    117   VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
    118 
    119   // do a lot of push_back such that the vector gets internally resized
    120   // (with memory reallocation)
    121   QuaternionType* ref = &w[0];
    122   for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
    123     v.push_back(w[i%w.size()]);
    124   for(unsigned int i=23; int(i)<v.size(); ++i)
    125   {
    126     VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());
    127   }
    128 }
    129 
    130 void test_qtvector()
    131 {
    132   // some non vectorizable fixed sizes
    133   CALL_SUBTEST(check_qtvector_matrix(Vector2f()));
    134   CALL_SUBTEST(check_qtvector_matrix(Matrix3f()));
    135   CALL_SUBTEST(check_qtvector_matrix(Matrix3d()));
    136 
    137   // some vectorizable fixed sizes
    138   CALL_SUBTEST(check_qtvector_matrix(Matrix2f()));
    139   CALL_SUBTEST(check_qtvector_matrix(Vector4f()));
    140   CALL_SUBTEST(check_qtvector_matrix(Matrix4f()));
    141   CALL_SUBTEST(check_qtvector_matrix(Matrix4d()));
    142 
    143   // some dynamic sizes
    144   CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1)));
    145   CALL_SUBTEST(check_qtvector_matrix(VectorXd(20)));
    146   CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20)));
    147   CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10)));
    148 
    149   // some Transform
    150   CALL_SUBTEST(check_qtvector_transform(Affine2f()));
    151   CALL_SUBTEST(check_qtvector_transform(Affine3f()));
    152   CALL_SUBTEST(check_qtvector_transform(Affine3d()));
    153   //CALL_SUBTEST(check_qtvector_transform(Transform4d()));
    154 
    155   // some Quaternion
    156   CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
    157   CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
    158 }
    159