You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.5 KiB

  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@inria.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. #define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5
  11. #include "main.h"
  12. #include <QtCore/QVector>
  13. #include <Eigen/Geometry>
  14. #include <Eigen/QtAlignedMalloc>
  15. template<typename MatrixType>
  16. void check_qtvector_matrix(const MatrixType& m)
  17. {
  18. typedef typename MatrixType::Index Index;
  19. Index rows = m.rows();
  20. Index cols = m.cols();
  21. MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
  22. QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);
  23. for(int i = 0; i < 20; i++)
  24. {
  25. VERIFY_IS_APPROX(w[i], y);
  26. }
  27. v[5] = x;
  28. w[6] = v[5];
  29. VERIFY_IS_APPROX(w[6], v[5]);
  30. v = w;
  31. for(int i = 0; i < 20; i++)
  32. {
  33. VERIFY_IS_APPROX(w[i], v[i]);
  34. }
  35. v.resize(21);
  36. v[20] = x;
  37. VERIFY_IS_APPROX(v[20], x);
  38. v.fill(y,22);
  39. VERIFY_IS_APPROX(v[21], y);
  40. v.push_back(x);
  41. VERIFY_IS_APPROX(v[22], x);
  42. VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
  43. // do a lot of push_back such that the vector gets internally resized
  44. // (with memory reallocation)
  45. MatrixType* ref = &w[0];
  46. for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
  47. v.push_back(w[i%w.size()]);
  48. for(int i=23; i<v.size(); ++i)
  49. {
  50. VERIFY(v[i]==w[(i-23)%w.size()]);
  51. }
  52. }
  53. template<typename TransformType>
  54. void check_qtvector_transform(const TransformType&)
  55. {
  56. typedef typename TransformType::MatrixType MatrixType;
  57. TransformType x(MatrixType::Random()), y(MatrixType::Random());
  58. QVector<TransformType> v(10), w(20, y);
  59. v[5] = x;
  60. w[6] = v[5];
  61. VERIFY_IS_APPROX(w[6], v[5]);
  62. v = w;
  63. for(int i = 0; i < 20; i++)
  64. {
  65. VERIFY_IS_APPROX(w[i], v[i]);
  66. }
  67. v.resize(21);
  68. v[20] = x;
  69. VERIFY_IS_APPROX(v[20], x);
  70. v.fill(y,22);
  71. VERIFY_IS_APPROX(v[21], y);
  72. v.push_back(x);
  73. VERIFY_IS_APPROX(v[22], x);
  74. VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
  75. // do a lot of push_back such that the vector gets internally resized
  76. // (with memory reallocation)
  77. TransformType* ref = &w[0];
  78. for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
  79. v.push_back(w[i%w.size()]);
  80. for(unsigned int i=23; int(i)<v.size(); ++i)
  81. {
  82. VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());
  83. }
  84. }
  85. template<typename QuaternionType>
  86. void check_qtvector_quaternion(const QuaternionType&)
  87. {
  88. typedef typename QuaternionType::Coefficients Coefficients;
  89. QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
  90. QVector<QuaternionType> v(10), w(20, y);
  91. v[5] = x;
  92. w[6] = v[5];
  93. VERIFY_IS_APPROX(w[6], v[5]);
  94. v = w;
  95. for(int i = 0; i < 20; i++)
  96. {
  97. VERIFY_IS_APPROX(w[i], v[i]);
  98. }
  99. v.resize(21);
  100. v[20] = x;
  101. VERIFY_IS_APPROX(v[20], x);
  102. v.fill(y,22);
  103. VERIFY_IS_APPROX(v[21], y);
  104. v.push_back(x);
  105. VERIFY_IS_APPROX(v[22], x);
  106. VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
  107. // do a lot of push_back such that the vector gets internally resized
  108. // (with memory reallocation)
  109. QuaternionType* ref = &w[0];
  110. for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
  111. v.push_back(w[i%w.size()]);
  112. for(unsigned int i=23; int(i)<v.size(); ++i)
  113. {
  114. VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());
  115. }
  116. }
  117. void test_qtvector()
  118. {
  119. // some non vectorizable fixed sizes
  120. CALL_SUBTEST(check_qtvector_matrix(Vector2f()));
  121. CALL_SUBTEST(check_qtvector_matrix(Matrix3f()));
  122. CALL_SUBTEST(check_qtvector_matrix(Matrix3d()));
  123. // some vectorizable fixed sizes
  124. CALL_SUBTEST(check_qtvector_matrix(Matrix2f()));
  125. CALL_SUBTEST(check_qtvector_matrix(Vector4f()));
  126. CALL_SUBTEST(check_qtvector_matrix(Matrix4f()));
  127. CALL_SUBTEST(check_qtvector_matrix(Matrix4d()));
  128. // some dynamic sizes
  129. CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1)));
  130. CALL_SUBTEST(check_qtvector_matrix(VectorXd(20)));
  131. CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20)));
  132. CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10)));
  133. // some Transform
  134. CALL_SUBTEST(check_qtvector_transform(Affine2f()));
  135. CALL_SUBTEST(check_qtvector_transform(Affine3f()));
  136. CALL_SUBTEST(check_qtvector_transform(Affine3d()));
  137. //CALL_SUBTEST(check_qtvector_transform(Transform4d()));
  138. // some Quaternion
  139. CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
  140. CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
  141. }