1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra. Eigen itself is part of the KDE project.
3//
4// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@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
15#include <Eigen/Geometry>
16#include <Eigen/QtAlignedMalloc>
17
18#include <QtCore/QVector>
19
20template<typename MatrixType>
21void check_qtvector_matrix(const MatrixType& m)
22{
23  int rows = m.rows();
24  int 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
60template<typename TransformType>
61void 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
95template<typename QuaternionType>
96void 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
130void test_eigen2_qtvector()
131{
132  // some non vectorizable fixed sizes
133  CALL_SUBTEST_1(check_qtvector_matrix(Vector2f()));
134  CALL_SUBTEST_1(check_qtvector_matrix(Matrix3f()));
135  CALL_SUBTEST_1(check_qtvector_matrix(Matrix3d()));
136
137  // some vectorizable fixed sizes
138  CALL_SUBTEST_2(check_qtvector_matrix(Matrix2f()));
139  CALL_SUBTEST_2(check_qtvector_matrix(Vector4f()));
140  CALL_SUBTEST_2(check_qtvector_matrix(Matrix4f()));
141  CALL_SUBTEST_2(check_qtvector_matrix(Matrix4d()));
142
143  // some dynamic sizes
144  CALL_SUBTEST_3(check_qtvector_matrix(MatrixXd(1,1)));
145  CALL_SUBTEST_3(check_qtvector_matrix(VectorXd(20)));
146  CALL_SUBTEST_3(check_qtvector_matrix(RowVectorXf(20)));
147  CALL_SUBTEST_3(check_qtvector_matrix(MatrixXcf(10,10)));
148
149  // some Transform
150  CALL_SUBTEST_4(check_qtvector_transform(Transform2f()));
151  CALL_SUBTEST_4(check_qtvector_transform(Transform3f()));
152  CALL_SUBTEST_4(check_qtvector_transform(Transform3d()));
153  //CALL_SUBTEST_4(check_qtvector_transform(Transform4d()));
154
155  // some Quaternion
156  CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));
157  CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));
158}
159