PCL
Matrix.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/Matrix.h - Released 2024-06-18T15:48:54Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_Matrix_h
53 #define __PCL_Matrix_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/Container.h>
61 #include <pcl/Exception.h>
62 #include <pcl/Math.h>
63 #include <pcl/Memory.h>
64 #include <pcl/ReferenceCounter.h>
65 #include <pcl/Rotate.h> // pcl::Reverse()
66 #include <pcl/Utility.h>
67 #include <pcl/Vector.h>
68 
69 #ifndef __PCL_NO_MATRIX_STATISTICS
70 # include <pcl/Selection.h>
71 # include <pcl/Sort.h>
72 #endif
73 
74 #if !defined( __PCL_NO_MATRIX_IMAGE_RENDERING ) && !defined( __PCL_NO_MATRIX_IMAGE_CONVERSION )
75 # include <pcl/Image.h>
76 # include <pcl/ImageVariant.h>
77 #endif
78 
79 #if !defined( __PCL_NO_MATRIX_PHASE_MATRICES ) && !defined( __PCL_NO_VECTOR_INSTANTIATE )
80 # include <pcl/Complex.h>
81 #endif
82 
83 /*
84  * Valid filter kernel sizes are odd integers >= 3. This macro is used for the
85  * KernelFilter and SeparableFilter classes to ensure validity of filter
86  * matrices and vectors.
87  */
88 #define PCL_VALID_KERNEL_SIZE( n ) (n ? Max( 3, n|1 ) : 0)
89 
90 namespace pcl
91 {
92 
93 // ----------------------------------------------------------------------------
94 
121 template <typename T>
122 class PCL_CLASS GenericMatrix : public DirectContainer<T>
123 {
124 public:
125 
129  using element = T;
130 
135 
142 
149 
155  {
156  m_data = new Data;
157  }
158 
168  GenericMatrix( int rows, int cols )
169  {
170  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
171  m_data = new Data( rows, cols );
172  }
173 
181  GenericMatrix( const element& x, int rows, int cols )
182  {
183  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
184  m_data = new Data( rows, cols );
185  pcl::Fill( m_data->Begin(), m_data->End(), x );
186  }
187 
201  template <typename T1>
202  GenericMatrix( const T1* a, int rows, int cols )
203  {
204  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
205  m_data = new Data( rows, cols );
206  if ( a != nullptr )
207  {
208  block_iterator __restrict__ i = m_data->Begin();
209  const_block_iterator __restrict__ j = m_data->End();
210  const T1* __restrict__ k = a;
211  PCL_IVDEP
212  for ( ; i < j; ++i, ++k )
213  *i = element( *k );
214  }
215  }
216 
227  template <typename T1>
228  GenericMatrix( const T1& a00, const T1& a01,
229  const T1& a10, const T1& a11 )
230  {
231  m_data = new Data( 2, 2 );
232  block_iterator __restrict__ v = m_data->Begin();
233  v[0] = element( a00 ); v[1] = element( a01 );
234  v[2] = element( a10 ); v[3] = element( a11 );
235  }
236 
248  template <typename T1>
249  GenericMatrix( const T1& a00, const T1& a01, const T1& a02,
250  const T1& a10, const T1& a11, const T1& a12,
251  const T1& a20, const T1& a21, const T1& a22 )
252  {
253  m_data = new Data( 3, 3 );
254  block_iterator __restrict__ v = m_data->Begin();
255  v[0] = element( a00 ); v[1] = element( a01 ); v[2] = element( a02 );
256  v[3] = element( a10 ); v[4] = element( a11 ); v[5] = element( a12 );
257  v[6] = element( a20 ); v[7] = element( a21 ); v[8] = element( a22 );
258  }
259 
265  : m_data( x.m_data )
266  {
267  m_data->Attach();
268  }
269 
274  : m_data( x.m_data )
275  {
276  x.m_data = nullptr;
277  }
278 
301  GenericMatrix( const GenericMatrix& x, int i0, int j0, int rows, int cols )
302  {
303  i0 = Range( i0, 0, Max( 0, x.Rows()-1 ) );
304  j0 = Range( j0, 0, Max( 0, x.Cols()-1 ) );
305  rows = Range( rows, 0, Max( 0, x.Rows()-i0 ) );
306  cols = Range( cols, 0, Max( 0, x.Cols()-j0 ) );
307  m_data = new Data( rows, cols );
308  for ( int i = 0; i < m_data->Rows(); ++i, ++i0 )
309  for ( int j = 0; j < m_data->Cols(); ++j, ++j0 )
310  m_data->v[i][j] = x.m_data->v[i0][j0];
311  }
312 
313 #ifndef __PCL_NO_MATRIX_IMAGE_CONVERSION
314 
351  template <class P>
352  GenericMatrix( const GenericImage<P>& image, const Rect& rect = Rect( 0 ), int channel = -1 )
353  {
354  GenericMatrix M = FromImage( image, rect, channel );
355  pcl::Swap( m_data, M.m_data );
356  }
357 
372  GenericMatrix( const ImageVariant& image, const Rect& rect = Rect( 0 ), int channel = -1 )
373  {
374  GenericMatrix M = FromImage( image, rect, channel );
375  pcl::Swap( m_data, M.m_data );
376  }
377 
378 #endif // !__PCL_NO_MATRIX_IMAGE_CONVERSION
379 
384  virtual ~GenericMatrix()
385  {
386  if ( m_data != nullptr )
387  {
388  DetachFromData();
389  m_data = nullptr;
390  }
391  }
392 
396  void Clear()
397  {
398  if ( !IsEmpty() )
399  if ( m_data->IsUnique() )
400  m_data->Deallocate();
401  else
402  {
403  Data* newData = new Data( 0, 0 );
404  DetachFromData();
405  m_data = newData;
406  }
407  }
408 
421  GenericMatrix& operator =( const GenericMatrix& x )
422  {
423  Assign( x );
424  return *this;
425  }
426 
439  void Assign( const GenericMatrix& x )
440  {
441  x.m_data->Attach();
442  DetachFromData();
443  m_data = x.m_data;
444  }
445 
449  GenericMatrix& operator =( GenericMatrix&& x )
450  {
451  Transfer( x );
452  return *this;
453  }
454 
468  {
469  DetachFromData();
470  m_data = x.m_data;
471  x.m_data = nullptr;
472  }
473 
487  {
488  DetachFromData();
489  m_data = x.m_data;
490  x.m_data = nullptr;
491  }
492 
499  friend void Swap( GenericMatrix& x1, GenericMatrix& x2 ) noexcept
500  {
501  pcl::Swap( x1.m_data, x2.m_data );
502  }
503 
512  GenericMatrix& operator =( const element& x )
513  {
514  if ( !IsUnique() )
515  {
516  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
517  DetachFromData();
518  m_data = newData;
519  }
520  pcl::Fill( m_data->Begin(), m_data->End(), x );
521  return *this;
522  }
523 
524 #define IMPLEMENT_SCALAR_ASSIGN_OP( op ) \
525  if ( IsUnique() ) \
526  { \
527  block_iterator __restrict__ i = m_data->Begin(); \
528  const_block_iterator __restrict__ j = m_data->End(); \
529  PCL_IVDEP \
530  for ( ; i < j; ++i ) \
531  *i op##= x; \
532  } \
533  else \
534  { \
535  Data* newData = new Data( m_data->Rows(), m_data->Cols() ); \
536  block_iterator __restrict__ i = newData->Begin(); \
537  const_block_iterator __restrict__ j = newData->End(); \
538  const_block_iterator __restrict__ k = m_data->Begin(); \
539  PCL_IVDEP \
540  for ( ; i < j; ++i, ++k ) \
541  *i = *k op x; \
542  DetachFromData(); \
543  m_data = newData; \
544  } \
545  return *this;
546 
555  GenericMatrix& operator +=( const element& x )
556  {
557  IMPLEMENT_SCALAR_ASSIGN_OP( + )
558  }
559 
568  GenericMatrix& operator -=( const element& x )
569  {
570  IMPLEMENT_SCALAR_ASSIGN_OP( - )
571  }
572 
581  GenericMatrix& operator *=( const element& x )
582  {
583  IMPLEMENT_SCALAR_ASSIGN_OP( * )
584  }
585 
594  GenericMatrix& operator /=( const element& x )
595  {
596  IMPLEMENT_SCALAR_ASSIGN_OP( / )
597  }
598 
607  GenericMatrix& operator ^=( const element& x )
608  {
609  if ( IsUnique() )
610  {
611  block_iterator __restrict__ i = m_data->Begin();
612  const_block_iterator __restrict__ j = m_data->End();
613  PCL_IVDEP
614  for ( ; i < j; ++i )
615  *i = pcl::Pow( *i, x );
616  }
617  else
618  {
619  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
620  block_iterator __restrict__ i = newData->Begin();
621  const_block_iterator __restrict__ j = newData->End();
622  const_block_iterator __restrict__ k = m_data->Begin();
623  PCL_IVDEP
624  for ( ; i < j; ++i, ++k )
625  *i = pcl::Pow( *k, x );
626  DetachFromData();
627  m_data = newData;
628  }
629  return *this;
630  }
631 
632 #undef IMPLEMENT_SCALAR_ASSIGN_OP
633 
634 #ifndef __PCL_NO_MATRIX_ELEMENT_WISE_ARITHMETIC_OPERATIONS
635 
636 #define IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( op ) \
637  if ( IsUnique() ) \
638  { \
639  block_iterator __restrict__ i = m_data->Begin(); \
640  const_block_iterator __restrict__ j = pcl::Min( m_data->End(), \
641  m_data->Begin() + x.NumberOfElements() ); \
642  const_block_iterator __restrict__ k = x.m_data->Begin(); \
643  PCL_IVDEP \
644  for ( ; i < j; ++i, ++k ) \
645  *i op##= *k; \
646  } \
647  else \
648  { \
649  Data* newData = new Data( m_data->Rows(), m_data->Cols() ); \
650  block_iterator __restrict__ i = newData->Begin(); \
651  const_block_iterator __restrict__ j = pcl::Min( newData->End(), \
652  newData->Begin() + x.NumberOfElements() ); \
653  const_block_iterator __restrict__ k = x.m_data->Begin(); \
654  const_block_iterator __restrict__ t = m_data->Begin(); \
655  PCL_IVDEP \
656  for ( ; i < j; ++i, ++k, ++t ) \
657  *i = *t op *k; \
658  DetachFromData(); \
659  m_data = newData; \
660  } \
661  return *this;
662 
675  GenericMatrix& operator +=( const GenericMatrix& x )
676  {
677  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( + )
678  }
679 
692  GenericMatrix& operator -=( const GenericMatrix& x )
693  {
694  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( - )
695  }
696 
709  GenericMatrix& operator *=( const GenericMatrix& x )
710  {
711  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( * )
712  }
713 
726  GenericMatrix& operator /=( const GenericMatrix& x )
727  {
728  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( / )
729  }
730 
742  GenericMatrix& operator ^=( const GenericMatrix& x )
743  {
744  if ( IsUnique() )
745  {
746  block_iterator __restrict__ i = m_data->Begin();
747  const_block_iterator __restrict__ j = pcl::Min( m_data->End(),
748  m_data->Begin() + x.NumberOfElements() );
749  const_block_iterator __restrict__ k = x.m_data->Begin();
750  PCL_IVDEP
751  for ( ; i < j; ++i, ++k )
752  *i = pcl::Pow( *i, *k );
753  }
754  else
755  {
756  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
757  block_iterator __restrict__ i = newData->Begin();
758  const_block_iterator __restrict__ j = pcl::Min( newData->End(),
759  newData->Begin() + x.NumberOfElements() );
760  const_block_iterator __restrict__ k = x.m_data->Begin();
761  const_block_iterator __restrict__ t = m_data->Begin();
762  PCL_IVDEP
763  for ( ; i < j; ++i, ++k, ++t )
764  *i = pcl::Pow( *t, *k );
765  DetachFromData();
766  m_data = newData;
767  }
768  return *this;
769  }
770 
771 #undef IMPLEMENT_ELEMENT_WISE_ASSIGN_OP
772 
773 #endif // __PCL_NO_MATRIX_ELEMENT_WISE_ARITHMETIC_OPERATIONS
774 
781  {
782  GenericMatrix R( m_data->Rows(), m_data->Cols() );
783  block_iterator __restrict__ i = R.m_data->Begin();
784  const_block_iterator __restrict__ j = R.m_data->End();
785  const_block_iterator __restrict__ k = m_data->Begin();
786  PCL_IVDEP
787  for ( ; i < j; ++i, ++k )
788  *i = *k * *k;
789  return R;
790  }
791 
798  void SetSqr()
799  {
800  if ( IsUnique() )
801  {
802  block_iterator __restrict__ i = m_data->Begin();
803  const_block_iterator __restrict__ j = m_data->End();
804  PCL_IVDEP
805  for ( ; i < j; ++i )
806  *i *= *i;
807  }
808  else
809  {
810  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
811  block_iterator __restrict__ i = newData->Begin();
812  const_block_iterator __restrict__ j = newData->End();
813  const_block_iterator __restrict__ k = m_data->Begin();
814  PCL_IVDEP
815  for ( ; i < j; ++i, ++k )
816  *i = *k * *k;
817  DetachFromData();
818  m_data = newData;
819  }
820  }
821 
828  {
829  GenericMatrix R( m_data->Rows(), m_data->Cols() );
830  block_iterator __restrict__ i = R.m_data->Begin();
831  const_block_iterator __restrict__ j = R.m_data->End();
832  const_block_iterator __restrict__ k = m_data->Begin();
833  PCL_IVDEP
834  for ( ; i < j; ++i, ++k )
835  *i = pcl::Sqrt( *k );
836  return R;
837  }
838 
845  void SetSqrt()
846  {
847  if ( IsUnique() )
848  {
849  block_iterator __restrict__ i = m_data->Begin();
850  const_block_iterator __restrict__ j = m_data->End();
851  PCL_IVDEP
852  for ( ; i < j; ++i )
853  *i = pcl::Sqrt( *i );
854  }
855  else
856  {
857  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
858  block_iterator __restrict__ i = newData->Begin();
859  const_block_iterator __restrict__ j = newData->End();
860  const_block_iterator __restrict__ k = m_data->Begin();
861  PCL_IVDEP
862  for ( ; i < j; ++i, ++k )
863  *i = pcl::Sqrt( *k );
864  DetachFromData();
865  m_data = newData;
866  }
867  }
868 
875  {
876  GenericMatrix R( m_data->Rows(), m_data->Cols() );
877  block_iterator __restrict__ i = R.m_data->Begin();
878  const_block_iterator __restrict__ j = R.m_data->End();
879  const_block_iterator __restrict__ k = m_data->Begin();
880  PCL_IVDEP
881  for ( ; i < j; ++i, ++k )
882  *i = pcl::Abs( *k );
883  return R;
884  }
885 
892  void SetAbs()
893  {
894  if ( IsUnique() )
895  {
896  block_iterator __restrict__ i = m_data->Begin();
897  const_block_iterator __restrict__ j = m_data->End();
898  PCL_IVDEP
899  for ( ; i < j; ++i )
900  *i = pcl::Abs( *i );
901  }
902  else
903  {
904  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
905  block_iterator __restrict__ i = newData->Begin();
906  const_block_iterator __restrict__ j = newData->End();
907  const_block_iterator __restrict__ k = m_data->Begin();
908  PCL_IVDEP
909  for ( ; i < j; ++i, ++k )
910  *i = pcl::Abs( *k );
911  DetachFromData();
912  m_data = newData;
913  }
914  }
915 
919  bool IsUnique() const noexcept
920  {
921  return m_data->IsUnique();
922  }
923 
928  bool IsAliasOf( const GenericMatrix& x ) const noexcept
929  {
930  return m_data == x.m_data;
931  }
932 
941  {
942  if ( !IsUnique() )
943  {
944  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
945  const_block_iterator __restrict__ i = m_data->Begin();
946  const_block_iterator __restrict__ j = m_data->End();
947  block_iterator __restrict__ k = newData->Begin();
948  PCL_IVDEP
949  for ( ; i < j; ++i, ++k )
950  *k = *i;
951  DetachFromData();
952  m_data = newData;
953  }
954  }
955 
960  int Rows() const noexcept
961  {
962  return m_data->Rows();
963  }
964 
969  int Cols() const noexcept
970  {
971  return m_data->Cols();
972  }
973 
980  int Columns() const noexcept
981  {
982  return Cols();
983  }
984 
1000  bool IsValid() const noexcept
1001  {
1002  return m_data != nullptr;
1003  }
1004 
1009  bool IsEmpty() const noexcept
1010  {
1011  return Rows() == 0 || Cols() == 0;
1012  }
1013 
1019  operator bool() const noexcept
1020  {
1021  return !IsEmpty();
1022  }
1023 
1028  size_type NumberOfElements() const noexcept
1029  {
1030  return m_data->NumberOfElements();
1031  }
1032 
1037  size_type Size() const noexcept
1038  {
1039  return m_data->Size();
1040  }
1041 
1049  bool operator ==( const GenericMatrix& x ) const noexcept
1050  {
1051  return IsAliasOf( x ) || SameDimensions( x ) && pcl::Equal( Begin(), x.Begin(), x.End() );
1052  }
1053 
1063  bool operator <( const GenericMatrix& x ) const noexcept
1064  {
1065  return !IsAliasOf( x ) && pcl::Compare( Begin(), End(), x.Begin(), x.End() ) < 0;
1066  }
1067 
1072  bool SameDimensions( const GenericMatrix& x ) const noexcept
1073  {
1074  return Rows() == x.Rows() && Cols() == x.Cols();
1075  }
1076 
1086  bool SameElements( const GenericMatrix& x ) const noexcept
1087  {
1088  if ( unlikely( IsAliasOf( x ) ) )
1089  return true;
1090  if ( unlikely( NumberOfElements() != x.NumberOfElements() ) )
1091  return false;
1092  const_block_iterator __restrict__ i = Begin();
1093  const_block_iterator __restrict__ j = End();
1094  const_block_iterator __restrict__ k = x.Begin();
1095  PCL_IVDEP
1096  for ( ; i < j; ++i, ++k )
1097  if ( *i != *k )
1098  return false;
1099  return true;
1100  }
1101 
1108  element& Element( int i, int j )
1109  {
1110  EnsureUnique();
1111  return m_data->Element( i, j );
1112  }
1113 
1118  const element& Element( int i, int j ) const noexcept
1119  {
1120  return m_data->Element( i, j );
1121  }
1122 
1132  block_iterator operator []( int i )
1133  {
1134  EnsureUnique();
1135  return m_data->v[i];
1136  }
1137 
1144  const_block_iterator operator []( int i ) const noexcept
1145  {
1146  return m_data->v[i];
1147  }
1148 
1162  {
1163  EnsureUnique();
1164  return m_data->Begin();
1165  }
1166 
1176  const_block_iterator Begin() const noexcept
1177  {
1178  return m_data->Begin();
1179  }
1180 
1185  {
1186  return Begin();
1187  }
1188 
1196  {
1197  return Begin();
1198  }
1199 
1207  {
1208  return Begin();
1209  }
1210 
1224  {
1225  EnsureUnique();
1226  return m_data->End();
1227  }
1228 
1239  const_block_iterator End() const noexcept
1240  {
1241  return m_data->End();
1242  }
1243 
1248  {
1249  return End();
1250  }
1251 
1271  {
1272  return m_data->v;
1273  }
1274 
1285  block_iterator RowPtr( int i ) noexcept
1286  {
1287  return m_data->v[i];
1288  }
1289 
1290 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1295  {
1296  return Begin();
1297  }
1298 
1302  const_block_iterator begin() const noexcept
1303  {
1304  return Begin();
1305  }
1306 
1311  {
1312  return End();
1313  }
1314 
1318  const_block_iterator end() const noexcept
1319  {
1320  return End();
1321  }
1322 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1323 
1327  vector RowVector( int i ) const
1328  {
1329  vector r( m_data->Cols() );
1330  for ( int j = 0; j < m_data->Cols(); ++j )
1331  r[j] = m_data->v[i][j];
1332  return r;
1333  }
1334 
1338  vector ColumnVector( int j ) const
1339  {
1340  vector c( m_data->Rows() );
1341  for ( int i = 0; i < m_data->Rows(); ++i )
1342  c[i] = m_data->v[i][j];
1343  return c;
1344  }
1345 
1351  vector ColVector( int j ) const
1352  {
1353  return ColumnVector( j );
1354  }
1355 
1360  template <class V>
1361  void SetRow( int i, const V& r )
1362  {
1363  EnsureUnique();
1364  for ( int j = 0; j < m_data->Cols() && j < r.Length(); ++j )
1365  m_data->v[i][j] = element( r[j] );
1366  }
1367 
1372  template <class V>
1373  void SetColumn( int j, const V& c )
1374  {
1375  EnsureUnique();
1376  for ( int i = 0; i < m_data->Rows() && i < c.Length(); ++i )
1377  m_data->v[i][j] = element( c[i] );
1378  }
1379 
1386  template <class V>
1387  void SetCol( int j, const V& c )
1388  {
1389  SetColumn( j, c );
1390  }
1391 
1398  {
1399  GenericMatrix R( element( 0 ), r.Length(), r.Length() );
1400  for ( int j = 0; j < r.Length(); ++j )
1401  R.m_data->v[0][j] = r[j];
1402  return R;
1403  }
1404 
1411  {
1412  GenericMatrix C( element( 0 ), c.Length(), c.Length() );
1413  for ( int i = 0; i < c.Length(); ++i )
1414  C.m_data->v[i][0] = c[i];
1415  return C;
1416  }
1417 
1422  {
1423  return FromColumnVector( c );
1424  }
1425 
1432  static GenericMatrix UnitMatrix( int n )
1433  {
1434  GenericMatrix One( element( 0 ), n, n );
1435  for ( int i = 0; i < n; ++i )
1436  One[i][i] = element( 1 );
1437  return One;
1438  }
1439 
1447  {
1448  GenericMatrix Tr( m_data->Cols(), m_data->Rows() );
1449  for ( int i = 0; i < m_data->Rows(); ++i )
1450  for ( int j = 0; j < m_data->Cols(); ++j )
1451  Tr.m_data->v[j][i] = m_data->v[i][j];
1452  return Tr;
1453  }
1454 
1466 
1477  void Invert();
1478 
1486  void Flip()
1487  {
1488  EnsureUnique();
1489  pcl::Reverse( m_data->Begin(), m_data->End() );
1490  }
1491 
1497  {
1498  GenericMatrix Tf( m_data->Cols(), m_data->Rows() );
1499  pcl::CopyReversed( Tf.m_data->End(), m_data->Begin(), m_data->End() );
1500  return Tf;
1501  }
1502 
1519  static GenericMatrix Translation( double dx, double dy )
1520  {
1521  return GenericMatrix( element( 1 ), element( 0 ), element( dx ),
1522  element( 0 ), element( 1 ), element( dy ),
1523  element( 0 ), element( 0 ), element( 1 ) );
1524  }
1525 
1540  template <class V>
1541  static GenericMatrix Translation( const V& delta )
1542  {
1543  return GenericMatrix( element( 1 ), element( 0 ), element( double( delta[0] ) ),
1544  element( 0 ), element( 1 ), element( double( delta[1] ) ),
1545  element( 0 ), element( 0 ), element( 1 ) );
1546  }
1547 
1568  void Translate( double dx, double dy )
1569  {
1570  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1571  EnsureUnique();
1572  block_iterator __restrict__ A0 = m_data->v[0];
1573  block_iterator __restrict__ A1 = m_data->v[1];
1574  block_iterator __restrict__ A2 = m_data->v[2];
1575  A0[2] = element( A0[2] + A0[0]*dx + A0[1]*dy );
1576  A1[2] = element( A1[2] + A1[0]*dx + A1[1]*dy );
1577  A2[2] = element( A2[2] + A2[0]*dx + A2[1]*dy );
1578  }
1579 
1588  template <class V>
1589  void Translate( const V& delta )
1590  {
1591  Translate( double( delta[0] ), double( delta[1] ) );
1592  }
1593 
1600  GenericMatrix Translated( double dx, double dy ) const
1601  {
1602  GenericMatrix R( *this );
1603  R.Translate( dx, dy );
1604  return R;
1605  }
1606 
1616  template <class V>
1617  GenericMatrix Translated( const V& delta ) const
1618  {
1619  return Translated( double( delta[0] ), double( delta[1] ) );
1620  }
1621 
1642  static GenericMatrix RotationX( double sphi, double cphi )
1643  {
1644  return GenericMatrix( element( 1 ), element( 0 ), element( 0 ),
1645  element( 0 ), element( +cphi ), element( +sphi ),
1646  element( 0 ), element( -sphi ), element( +cphi ) );
1647  }
1648 
1657  static GenericMatrix RotationX( double phi )
1658  {
1659  double sphi, cphi;
1660  SinCos( phi, sphi, cphi );
1661  return RotationX( sphi, cphi );
1662  }
1663 
1684  static GenericMatrix RotationY( double sphi, double cphi )
1685  {
1686  return GenericMatrix( element( +cphi ), element( 0 ), element( -sphi ),
1687  element( 0 ), element( 1 ), element( 0 ),
1688  element( +sphi ), element( 0 ), element( +cphi ) );
1689  }
1690 
1699  static GenericMatrix RotationY( double phi )
1700  {
1701  double sphi, cphi;
1702  SinCos( phi, sphi, cphi );
1703  return RotationY( sphi, cphi );
1704  }
1705 
1726  static GenericMatrix RotationZ( double sphi, double cphi )
1727  {
1728  return GenericMatrix( element( +cphi ), element( +sphi ), element( 0 ),
1729  element( -sphi ), element( +cphi ), element( 0 ),
1730  element( 0 ), element( 0 ), element( 1 ) );
1731  }
1732 
1741  static GenericMatrix RotationZ( double phi )
1742  {
1743  double sphi, cphi;
1744  SinCos( phi, sphi, cphi );
1745  return RotationZ( sphi, cphi );
1746  }
1747 
1771  void RotateX( double sphi, double cphi )
1772  {
1773  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1774  EnsureUnique();
1775  block_iterator __restrict__ A1 = m_data->v[1];
1776  block_iterator __restrict__ A2 = m_data->v[2];
1777  double a10 = cphi*A1[0] + sphi*A2[0];
1778  double a11 = cphi*A1[1] + sphi*A2[1];
1779  double a12 = cphi*A1[2] + sphi*A2[2];
1780  double a20 = -sphi*A1[0] + cphi*A2[0];
1781  double a21 = -sphi*A1[1] + cphi*A2[1];
1782  double a22 = -sphi*A1[2] + cphi*A2[2];
1783  A1[0] = element( a10 );
1784  A1[1] = element( a11 );
1785  A1[2] = element( a12 );
1786  A2[0] = element( a20 );
1787  A2[1] = element( a21 );
1788  A2[2] = element( a22 );
1789  }
1790 
1799  void RotateX( double phi )
1800  {
1801  double sphi, cphi;
1802  SinCos( phi, sphi, cphi );
1803  RotateX( sphi, cphi );
1804  }
1805 
1811  GenericMatrix RotatedX( double sphi, double cphi ) const
1812  {
1813  GenericMatrix R( *this );
1814  R.RotateX( sphi, cphi );
1815  return R;
1816  }
1817 
1822  GenericMatrix RotatedX( double phi ) const
1823  {
1824  GenericMatrix R( *this );
1825  R.RotateX( phi );
1826  return R;
1827  }
1828 
1852  void RotateY( double sphi, double cphi )
1853  {
1854  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1855  EnsureUnique();
1856  block_iterator __restrict__ A0 = m_data->v[0];
1857  block_iterator __restrict__ A2 = m_data->v[2];
1858  double a00 = cphi*A0[0] - sphi*A2[0];
1859  double a01 = cphi*A0[1] - sphi*A2[1];
1860  double a02 = cphi*A0[2] - sphi*A2[2];
1861  double a20 = sphi*A0[0] + cphi*A2[0];
1862  double a21 = sphi*A0[1] + cphi*A2[1];
1863  double a22 = sphi*A0[2] + cphi*A2[2];
1864  A0[0] = a00;
1865  A0[1] = a01;
1866  A0[2] = a02;
1867  A2[0] = a20;
1868  A2[1] = a21;
1869  A2[2] = a22;
1870  }
1871 
1880  void RotateY( double phi )
1881  {
1882  double sphi, cphi;
1883  SinCos( phi, sphi, cphi );
1884  RotateY( sphi, cphi );
1885  }
1886 
1892  GenericMatrix RotatedY( double sphi, double cphi ) const
1893  {
1894  GenericMatrix R( *this );
1895  R.RotateY( sphi, cphi );
1896  return R;
1897  }
1898 
1903  GenericMatrix RotatedY( double phi ) const
1904  {
1905  GenericMatrix R( *this );
1906  R.RotateY( phi );
1907  return R;
1908  }
1909 
1933  void RotateZ( double sphi, double cphi )
1934  {
1935  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1936  EnsureUnique();
1937  block_iterator __restrict__ A0 = m_data->v[0];
1938  block_iterator __restrict__ A1 = m_data->v[1];
1939  double a00 = cphi*A0[0] + sphi*A1[0];
1940  double a01 = cphi*A0[1] + sphi*A1[1];
1941  double a02 = cphi*A0[2] + sphi*A1[2];
1942  double a10 = -sphi*A0[0] + cphi*A1[0];
1943  double a11 = -sphi*A0[1] + cphi*A1[1];
1944  double a12 = -sphi*A0[2] + cphi*A1[2];
1945  A0[0] = a00;
1946  A0[1] = a01;
1947  A0[2] = a02;
1948  A1[0] = a10;
1949  A1[1] = a11;
1950  A1[2] = a12;
1951  }
1952 
1961  void RotateZ( double phi )
1962  {
1963  double sphi, cphi;
1964  SinCos( phi, sphi, cphi );
1965  RotateZ( sphi, cphi );
1966  }
1967 
1973  GenericMatrix RotatedZ( double sphi, double cphi ) const
1974  {
1975  GenericMatrix R( *this );
1976  R.RotateZ( sphi, cphi );
1977  return R;
1978  }
1979 
1984  GenericMatrix RotatedZ( double phi ) const
1985  {
1986  GenericMatrix R( *this );
1987  R.RotateZ( phi );
1988  return R;
1989  }
1990 
2003  void Truncate( const element& f0 = element( 0 ), const element& f1 = element( 1 ) )
2004  {
2005  EnsureUnique();
2006  block_iterator __restrict__ i = m_data->Begin();
2007  block_iterator __restrict__ j = m_data->End();
2008  PCL_IVDEP
2009  for ( ; i < j; ++i )
2010  if ( *i < f0 )
2011  *i = f0;
2012  else if ( *i > f1 )
2013  *i = f1;
2014  }
2015 
2019  GenericMatrix Truncated( const element& f0 = element( 0 ), const element& f1 = element( 1 ) ) const
2020  {
2021  GenericMatrix R( *this );
2022  R.Truncate( f0, f1 );
2023  return R;
2024  }
2025 
2041  void Rescale( const element& f0 = element( 0 ), const element& f1 = element( 1 ) )
2042  {
2043  element v0 = MinElement();
2044  element v1 = MaxElement();
2045  if ( v0 != f0 || v1 != f1 )
2046  {
2047  EnsureUnique();
2048  if ( v0 != v1 )
2049  {
2050  if ( f0 != f1 )
2051  {
2052  block_iterator __restrict__ i = m_data->Begin();
2053  block_iterator __restrict__ j = m_data->End();
2054  double d = (double( f1 ) - double( f0 ))/(double( v1 ) - double( v0 ));
2055  if ( f0 == element( 0 ) )
2056  {
2057  PCL_IVDEP
2058  for ( ; i < j; ++i )
2059  *i = element( d*(*i - v0) );
2060  }
2061  else
2062  {
2063  PCL_IVDEP
2064  for ( ; i < j; ++i )
2065  *i = element( d*(*i - v0) + f0 );
2066  }
2067  }
2068  else
2069  pcl::Fill( m_data->Begin(), m_data->End(), f0 );
2070  }
2071  else
2072  pcl::Fill( m_data->Begin(), m_data->End(), pcl::Range( v0, f0, f1 ) );
2073  }
2074  }
2075 
2079  GenericMatrix Rescaled( const element& f0 = element( 0 ), const element& f1 = element( 1 ) ) const
2080  {
2081  GenericMatrix R( *this );
2082  R.Rescale( f0, f1 );
2083  return R;
2084  }
2085 
2089  void Sort()
2090  {
2091  EnsureUnique();
2092  pcl::Sort( m_data->Begin(), m_data->End() );
2093  }
2094 
2099  {
2100  GenericMatrix R( *this );
2101  R.Sort();
2102  return R;
2103  }
2104 
2109  {
2110  EnsureUnique();
2111  pcl::Sort( m_data->Begin(), m_data->End(),
2112  []( const element& a, const element& b ){ return b < a; } );
2113  }
2114 
2119  {
2120  GenericMatrix R( *this );
2121  R.ReverseSort();
2122  return R;
2123  }
2124 
2130  template <class BP>
2131  void Sort( BP p )
2132  {
2133  EnsureUnique();
2134  pcl::Sort( m_data->Begin(), m_data->End(), p );
2135  }
2136 
2141  template <class BP>
2142  GenericMatrix Sorted( BP p ) const
2143  {
2144  GenericMatrix R( *this );
2145  R.Sort( p );
2146  return R;
2147  }
2148 
2154  const_block_iterator Find( const element& x ) const noexcept
2155  {
2156  const_block_iterator p = pcl::LinearSearch( m_data->Begin(), m_data->End(), x );
2157  return (p != m_data->End()) ? p : nullptr;
2158  }
2159 
2165  const_block_iterator FindFirst( const element& x ) const noexcept
2166  {
2167  return Find( x );
2168  }
2169 
2174  const_block_iterator FindLast( const element& x ) const noexcept
2175  {
2176  const_block_iterator p = pcl::LinearSearchLast( m_data->Begin(), m_data->End(), x );
2177  return (p != m_data->End()) ? p : nullptr;
2178  }
2179 
2183  bool Contains( const element& x ) const noexcept
2184  {
2185  return pcl::LinearSearch( m_data->Begin(), m_data->End(), x ) != m_data->End();
2186  }
2187 
2188 #ifndef __PCL_NO_MATRIX_STATISTICS
2189 
2194  element MinElement() const noexcept
2195  {
2196  if ( !IsEmpty() )
2197  return *MinItem( m_data->Begin(), m_data->End() );
2198  return element( 0 );
2199  }
2200 
2207  element MinElement( Point& p ) const noexcept
2208  {
2209  if ( !IsEmpty() )
2210  {
2211  const_block_iterator m = MinItem( m_data->Begin(), m_data->End() );
2212  distance_type d = m - m_data->Begin();
2213  p.y = int( d/m_data->Cols() );
2214  p.x = int( d%m_data->Cols() );
2215  return *m;
2216  }
2217  p = 0;
2218  return element( 0 );
2219  }
2220 
2225  element MaxElement() const noexcept
2226  {
2227  if ( !IsEmpty() )
2228  return *MaxItem( m_data->Begin(), m_data->End() );
2229  return element( 0 );
2230  }
2231 
2238  element MaxElement( Point& p ) const noexcept
2239  {
2240  if ( !IsEmpty() )
2241  {
2242  const_block_iterator m = MaxItem( m_data->Begin(), m_data->End() );
2243  int d = m - m_data->Begin();
2244  p.y = d/m_data->Cols();
2245  p.x = d%m_data->Cols();
2246  return *m;
2247  }
2248  p = 0;
2249  return element( 0 );
2250  }
2251 
2257  double Sum() const noexcept
2258  {
2259  return pcl::Sum( m_data->Begin(), m_data->End() );
2260  }
2261 
2268  double StableSum() const noexcept
2269  {
2270  return pcl::StableSum( m_data->Begin(), m_data->End() );
2271  }
2272 
2278  double Modulus() const noexcept
2279  {
2280  return pcl::Modulus( m_data->Begin(), m_data->End() );
2281  }
2282 
2289  double StableModulus() const noexcept
2290  {
2291  return pcl::StableModulus( m_data->Begin(), m_data->End() );
2292  }
2293 
2299  double SumOfSquares() const noexcept
2300  {
2301  return pcl::SumOfSquares( m_data->Begin(), m_data->End() );
2302  }
2303 
2310  double StableSumOfSquares() const noexcept
2311  {
2312  return pcl::StableSumOfSquares( m_data->Begin(), m_data->End() );
2313  }
2314 
2320  double Mean() const noexcept
2321  {
2322  return pcl::Mean( m_data->Begin(), m_data->End() );
2323  }
2324 
2331  double StableMean() const noexcept
2332  {
2333  return pcl::StableMean( m_data->Begin(), m_data->End() );
2334  }
2335 
2343  double TrimmedMean( distance_type l = 1, distance_type h = 1 ) const noexcept
2344  {
2345  return pcl::TrimmedMean( m_data->Begin(), m_data->End(), l, h );
2346  }
2347 
2355  double TrimmedMeanOfSquares( distance_type l = 1, distance_type h = 1 ) const noexcept
2356  {
2357  return pcl::TrimmedMeanOfSquares( m_data->Begin(), m_data->End(), l, h );
2358  }
2359 
2365  double Variance() const noexcept
2366  {
2367  return pcl::Variance( m_data->Begin(), m_data->End() );
2368  }
2369 
2376  double StdDev() const noexcept
2377  {
2378  return pcl::StdDev( m_data->Begin(), m_data->End() );
2379  }
2380 
2386  double Median() const
2387  {
2388  return pcl::Median( m_data->Begin(), m_data->End() );
2389  }
2390 
2405  double AvgDev( double center ) const noexcept
2406  {
2407  return pcl::AvgDev( m_data->Begin(), m_data->End(), center );
2408  }
2409 
2425  double StableAvgDev( double center ) const noexcept
2426  {
2427  return pcl::StableAvgDev( m_data->Begin(), m_data->End(), center );
2428  }
2429 
2442  double AvgDev() const
2443  {
2444  return pcl::AvgDev( m_data->Begin(), m_data->End() );
2445  }
2446 
2460  double StableAvgDev() const
2461  {
2462  return pcl::StableAvgDev( m_data->Begin(), m_data->End() );
2463  }
2464 
2471  TwoSidedEstimate TwoSidedAvgDev( double center ) const noexcept
2472  {
2473  return pcl::TwoSidedAvgDev( m_data->Begin(), m_data->End(), center );
2474  }
2475 
2482  {
2483  return pcl::TwoSidedAvgDev( m_data->Begin(), m_data->End() );
2484  }
2485 
2497  double MAD( double center ) const
2498  {
2499  return pcl::MAD( m_data->Begin(), m_data->End(), center );
2500  }
2501 
2512  double MAD() const
2513  {
2514  return pcl::MAD( m_data->Begin(), m_data->End() );
2515  }
2516 
2523  TwoSidedEstimate TwoSidedMAD( double center ) const
2524  {
2525  return pcl::TwoSidedMAD( m_data->Begin(), m_data->End(), center );
2526  }
2527 
2534  {
2535  return pcl::TwoSidedMAD( m_data->Begin(), m_data->End() );
2536  }
2537 
2573  double BiweightMidvariance( double center, double sigma, int k = 9, bool reducedLength = false ) const noexcept
2574  {
2575  return pcl::BiweightMidvariance( m_data->Begin(), m_data->End(), center, sigma, k, reducedLength );
2576  }
2577 
2607  double BiweightMidvariance( int k = 9, bool reducedLength = false ) const
2608  {
2609  double center = Median();
2610  return BiweightMidvariance( center, MAD( center ), k, reducedLength );
2611  }
2612 
2628  int k = 9, bool reducedLength = false ) const noexcept
2629  {
2630  return pcl::TwoSidedBiweightMidvariance( m_data->Begin(), m_data->End(), center, sigma, k, reducedLength );
2631  }
2632 
2639  TwoSidedEstimate TwoSidedBiweightMidvariance( int k = 9, bool reducedLength = false ) const
2640  {
2641  double center = Median();
2642  return TwoSidedBiweightMidvariance( center, TwoSidedMAD( center ), k, reducedLength );
2643  }
2644 
2667  double BendMidvariance( double center, double beta = 0.2 ) const
2668  {
2669  return pcl::BendMidvariance( m_data->Begin(), m_data->End(), center, beta );
2670  }
2671 
2691  double BendMidvariance( double beta = 0.2 ) const
2692  {
2693  return pcl::BendMidvariance( m_data->Begin(), m_data->End(), Median(), beta );
2694  }
2695 
2719  double Sn() const
2720  {
2721  GenericMatrix A( *this );
2722  return pcl::Sn( A.Begin(), A.End() );
2723  }
2724 
2747  double Qn() const
2748  {
2749  GenericMatrix A( *this );
2750  return pcl::Qn( A.Begin(), A.End() );
2751  }
2752 
2753 #endif // !__PCL_NO_MATRIX_STATISTICS
2754 
2763  uint64 Hash64( uint64 seed = 0 ) const noexcept
2764  {
2765  return pcl::Hash64( m_data->Begin(), m_data->Size(), seed );
2766  }
2767 
2776  uint32 Hash32( uint32 seed = 0 ) const noexcept
2777  {
2778  return pcl::Hash32( m_data->Begin(), m_data->Size(), seed );
2779  }
2780 
2785  uint64 Hash( uint64 seed = 0 ) const noexcept
2786  {
2787  return Hash64( seed );
2788  }
2789 
2806  template <class S, typename SP>
2807  S& ToSeparated( S& s, SP separator ) const
2808  {
2809  const_block_iterator i = m_data->Begin(), j = m_data->End();
2810  if ( i < j )
2811  {
2812  s.Append( S( *i ) );
2813  if ( ++i < j )
2814  do
2815  {
2816  s.Append( separator );
2817  s.Append( S( *i ) );
2818  }
2819  while ( ++i < j );
2820  }
2821  return s;
2822  }
2823 
2846  template <class S, typename SP, class AF>
2847  S& ToSeparated( S& s, SP separator, AF append ) const
2848  {
2849  const_block_iterator i = m_data->Begin(), j = m_data->End();
2850  if ( i < j )
2851  {
2852  append( s, S( *i ) );
2853  if ( ++i < j )
2854  {
2855  S p( separator );
2856  do
2857  {
2858  append( s, p );
2859  append( s, S( *i ) );
2860  }
2861  while ( ++i < j );
2862  }
2863  }
2864  return s;
2865  }
2866 
2875  template <class S>
2876  S& ToCommaSeparated( S& s ) const
2877  {
2878  return ToSeparated( s, ',' );
2879  }
2880 
2889  template <class S>
2890  S& ToSpaceSeparated( S& s ) const
2891  {
2892  return ToSeparated( s, ' ' );
2893  }
2894 
2903  template <class S>
2904  S& ToTabSeparated( S& s ) const
2905  {
2906  return ToSeparated( s, '\t' );
2907  }
2908 
2909 #ifndef __PCL_NO_MATRIX_PHASE_MATRICES
2910 
2916  {
2917  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
2918  throw Error( "Invalid matrix dimensions in PhaseCorrelationMatrix()" );
2919  GenericMatrix R( A.Rows(), A.Cols() );
2920  PhaseCorrelationMatrix( R.Begin(), R.End(), A.Begin(), B.Begin() );
2921  return R;
2922  }
2923 
2929  {
2930  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
2931  throw Error( "Invalid matrix dimensions in CrossPowerSpectrumMatrix()" );
2932  GenericMatrix R( A.Rows(), A.Cols() );
2933  CrossPowerSpectrumMatrix( R.Begin(), R.End(), A.Begin(), B.Begin() );
2934  return R;
2935  }
2936 
2937 #endif // !__PCL_NO_MATRIX_PHASE_MATRICES
2938 
2939 #ifndef __PCL_NO_MATRIX_IMAGE_RENDERING
2940 
2959  template <class P>
2960  void ToImage( GenericImage<P>& image ) const
2961  {
2962  image.AllocateData( Cols(), Rows() );
2963  typename P::sample* __restrict__ v = *image;
2964  const_block_iterator __restrict__ i = m_data->Begin();
2965  const_block_iterator __restrict__ j = m_data->End();
2966  PCL_IVDEP
2967  for ( ; i < j; ++i, ++v )
2968  *v = P::ToSample( *i );
2969  }
2970 
2986  void ToImage( ImageVariant& image ) const
2987  {
2988  if ( !image )
2989  image.CreateFloatImage();
2990 
2991  if ( image.IsFloatSample() )
2992  switch ( image.BitsPerSample() )
2993  {
2994  case 32: ToImage( static_cast<Image&>( *image ) ); break;
2995  case 64: ToImage( static_cast<DImage&>( *image ) ); break;
2996  }
2997  else if ( image.IsComplexSample() )
2998  switch ( image.BitsPerSample() )
2999  {
3000  case 32: ToImage( static_cast<ComplexImage&>( *image ) ); break;
3001  case 64: ToImage( static_cast<DComplexImage&>( *image ) ); break;
3002  }
3003  else
3004  switch ( image.BitsPerSample() )
3005  {
3006  case 8: ToImage( static_cast<UInt8Image&>( *image ) ); break;
3007  case 16: ToImage( static_cast<UInt16Image&>( *image ) ); break;
3008  case 32: ToImage( static_cast<UInt32Image&>( *image ) ); break;
3009  }
3010  }
3011 
3012 #endif // !__PCL_NO_MATRIX_IMAGE_RENDERING
3013 
3014 #ifndef __PCL_NO_MATRIX_IMAGE_CONVERSION
3015 
3053  template <class P>
3054  static GenericMatrix FromImage( const GenericImage<P>& image, const Rect& rect = Rect( 0 ), int channel = -1 )
3055  {
3056  Rect r = rect;
3057  if ( !image.ParseSelection( r, channel ) )
3058  return GenericMatrix();
3059 
3060  if ( r == image.Bounds() )
3061  {
3062  GenericMatrix M( image.Height(), image.Width() );
3063  const typename P::sample* __restrict__ v = image[channel];
3064  block_iterator __restrict__ i = M.m_data->Begin();
3065  const_block_iterator __restrict__ j = M.m_data->End();
3066  PCL_IVDEP
3067  for ( ; i < j; ++i, ++v )
3068  P::FromSample( *i, *v );
3069  return M;
3070  }
3071  else
3072  {
3073  int w = r.Width();
3074  int h = r.Height();
3075  GenericMatrix M( h, w );
3076  block_iterator __restrict__ m = M.m_data->Begin();
3077  PCL_IVDEP
3078  for ( int i = r.y0; i < r.y1; ++i )
3079  {
3080  const typename P::sample* __restrict__ v = image.PixelAddress( r.x0, i, channel );
3081  PCL_IVDEP
3082  for ( int j = 0; j < w; ++j )
3083  P::FromSample( *m++, *v++ );
3084  }
3085  return M;
3086  }
3087  }
3088 
3103  static GenericMatrix FromImage( const ImageVariant& image, const Rect& rect = Rect( 0 ), int channel = -1 )
3104  {
3105  if ( image )
3106  if ( image.IsFloatSample() )
3107  switch ( image.BitsPerSample() )
3108  {
3109  case 32: return FromImage( static_cast<const Image&>( *image ), rect, channel );
3110  case 64: return FromImage( static_cast<const DImage&>( *image ), rect, channel );
3111  }
3112  else if ( image.IsComplexSample() )
3113  switch ( image.BitsPerSample() )
3114  {
3115  case 32: return FromImage( static_cast<const ComplexImage&>( *image ), rect, channel );
3116  case 64: return FromImage( static_cast<const DComplexImage&>( *image ), rect, channel );
3117  }
3118  else
3119  switch ( image.BitsPerSample() )
3120  {
3121  case 8: return FromImage( static_cast<const UInt8Image&>( *image ), rect, channel );
3122  case 16: return FromImage( static_cast<const UInt16Image&>( *image ), rect, channel );
3123  case 32: return FromImage( static_cast<const UInt32Image&>( *image ), rect, channel );
3124  }
3125 
3126  return GenericMatrix();
3127  }
3128 
3129 #endif // !__PCL_NO_MATRIX_IMAGE_CONVERSION
3130 
3131 private:
3132 
3138  struct Data : public ReferenceCounter
3139  {
3140  int n = 0;
3141  int m = 0;
3142  block_iterator* v = nullptr;
3143 
3144  Data() = default;
3145 
3146  Data( int rows, int cols )
3147  {
3148  if ( rows > 0 && cols > 0 )
3149  Allocate( rows, cols );
3150  }
3151 
3152  ~Data()
3153  {
3154  Deallocate();
3155  }
3156 
3157  int Rows() const noexcept
3158  {
3159  return n;
3160  }
3161 
3162  int Cols() const noexcept
3163  {
3164  return m;
3165  }
3166 
3167  size_type NumberOfElements() const noexcept
3168  {
3169  return size_type( n )*size_type( m );
3170  }
3171 
3172  size_type Size() const noexcept
3173  {
3174  return NumberOfElements()*sizeof( element );
3175  }
3176 
3177  block_iterator Begin() const
3178  {
3179  block_iterator p = (v != nullptr) ? *v : nullptr;
3180  if ( likely( std::is_scalar<element>::value ) )
3181  return reinterpret_cast<block_iterator>( PCL_ASSUME_ALIGNED_32( p ) );
3182  return p;
3183  }
3184 
3185  block_iterator End() const noexcept
3186  {
3187  return (v != nullptr) ? *v + NumberOfElements() : nullptr;
3188  }
3189 
3190  element& Element( int i, int j ) const noexcept
3191  {
3192  return v[i][j];
3193  }
3194 
3195  void Allocate( int rows, int cols )
3196  {
3197  n = rows;
3198  m = cols;
3199  v = new block_iterator[ n ];
3200  if ( likely( std::is_scalar<element>::value ) )
3201  {
3202  *v = reinterpret_cast<block_iterator>( PCL_ALIGNED_MALLOC( Size(), 32 ) );
3203  if ( unlikely( *v == nullptr ) )
3204  {
3205  delete [] v;
3206  v = nullptr;
3207  n = m = 0;
3208  throw std::bad_alloc();
3209  }
3210  }
3211  else
3212  *v = new element[ NumberOfElements() ];
3213  for ( int i = 1; i < n; ++i )
3214  v[i] = v[i-1] + m;
3215  }
3216 
3217  void Deallocate()
3218  {
3219  PCL_PRECONDITION( refCount == 0 )
3220  if ( v != nullptr )
3221  {
3222  if ( likely( std::is_scalar<element>::value ) )
3223  PCL_ALIGNED_FREE( *v );
3224  else
3225  delete [] *v;
3226  delete [] v;
3227  v = nullptr;
3228  n = m = 0;
3229  }
3230  }
3231  };
3232 
3237  Data* m_data = nullptr;
3238 
3243  void DetachFromData()
3244  {
3245  if ( !m_data->Detach() )
3246  delete m_data;
3247  }
3248 
3253  static bool Invert( block_iterator* Ai, const_block_iterator const* A, int n ) noexcept
3254  {
3255  switch ( n )
3256  {
3257  case 1:
3258  if ( 1 + **A == 1 )
3259  return false;
3260  **Ai = 1/(**A);
3261  break;
3262  case 2:
3263  {
3264  const_block_iterator __restrict__ A0 = A[0];
3265  const_block_iterator __restrict__ A1 = A[1];
3266  element d = A0[0]*A1[1] - A0[1]*A1[0];
3267  if ( 1 + d == 1 )
3268  return false;
3269  Ai[0][0] = A1[1]/d;
3270  Ai[0][1] = -A0[1]/d;
3271  Ai[1][0] = -A1[0]/d;
3272  Ai[1][1] = A0[0]/d;
3273  }
3274  break;
3275  case 3:
3276  {
3277  const_block_iterator __restrict__ A0 = A[0];
3278  const_block_iterator __restrict__ A1 = A[1];
3279  const_block_iterator __restrict__ A2 = A[2];
3280  element d1 = A1[1]*A2[2] - A1[2]*A2[1];
3281  element d2 = A1[2]*A2[0] - A1[0]*A2[2];
3282  element d3 = A1[0]*A2[1] - A1[1]*A2[0];
3283  element d = A0[0]*d1 + A0[1]*d2 + A0[2]*d3;
3284  if ( 1 + d == 1 )
3285  return false;
3286  Ai[0][0] = d1/d;
3287  Ai[0][1] = (A2[1]*A0[2] - A2[2]*A0[1])/d;
3288  Ai[0][2] = (A0[1]*A1[2] - A0[2]*A1[1])/d;
3289  Ai[1][0] = d2/d;
3290  Ai[1][1] = (A2[2]*A0[0] - A2[0]*A0[2])/d;
3291  Ai[1][2] = (A0[2]*A1[0] - A0[0]*A1[2])/d;
3292  Ai[2][0] = d3/d;
3293  Ai[2][1] = (A2[0]*A0[1] - A2[1]*A0[0])/d;
3294  Ai[2][2] = (A0[0]*A1[1] - A0[1]*A1[0])/d;
3295  }
3296  break;
3297  default: // ?!
3298  return false;
3299  }
3300  return true;
3301  }
3302 };
3303 
3304 // ### N.B.: Visual C++ is unable to compile the next two member functions if
3305 // the following external function declarations are placed within the
3306 // member function bodies. This forces us to implement them after the
3307 // GenericMatrix<> class declaration.
3308 
3309 void PCL_FUNC InPlaceGaussJordan( GenericMatrix<double>&, GenericMatrix<double>& );
3310 void PCL_FUNC InPlaceGaussJordan( GenericMatrix<float>&, GenericMatrix<float>& );
3311 
3312 template <typename T> inline
3314 {
3315  if ( Rows() != Cols() || Rows() == 0 )
3316  throw Error( "Invalid matrix inversion: Non-square or empty matrix." );
3317 
3318  /*
3319  * - Use direct formulae to invert 1x1, 2x2 and 3x3 matrices.
3320  * - Use Gauss-Jordan elimination to invert 4x4 and larger matrices.
3321  */
3322  if ( Rows() < 4 )
3323  {
3324  GenericMatrix Ai( Rows(), Rows() );
3325  if ( !Invert( Ai.m_data->v, m_data->v, Rows() ) )
3326  throw Error( "Invalid matrix inversion: Singular matrix." );
3327  return Ai;
3328  }
3329  else
3330  {
3331  GenericMatrix Ai( *this );
3332  GenericMatrix B = UnitMatrix( Rows() );
3333  InPlaceGaussJordan( Ai, B );
3334  return Ai;
3335  }
3336 }
3337 
3338 template <typename T> inline
3340 {
3341  if ( Rows() <= 3 )
3342  Transfer( Inverse() );
3343  else
3344  {
3345  if ( Rows() != Cols() || Rows() == 0 )
3346  throw Error( "Invalid matrix inversion: Non-square or empty matrix." );
3347  EnsureUnique();
3348  GenericMatrix B = UnitMatrix( Rows() );
3349  InPlaceGaussJordan( *this, B );
3350  }
3351 }
3352 
3353 // ----------------------------------------------------------------------------
3354 
3370 template <typename T> inline
3372 {
3373  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
3374  throw Error( "Invalid matrix addition." );
3375  GenericMatrix<T> R( A.Rows(), A.Cols() );
3376  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3377  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3378  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3379  typename GenericMatrix<T>::const_block_iterator __restrict__ t = B.Begin();
3380  PCL_IVDEP
3381  for ( ; i < j; ++i, ++k, ++t )
3382  *i = *k + *t;
3383  return R;
3384 }
3385 
3391 template <typename T> inline
3393 {
3394  GenericMatrix<T> R( A.Rows(), A.Cols() );
3395  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3396  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3397  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3398  PCL_IVDEP
3399  for ( ; i < j; ++i, ++k )
3400  *i = *k + x;
3401  return R;
3402 }
3403 
3412 template <typename T> inline
3414 {
3415  return A + x;
3416 }
3417 
3418 // ----------------------------------------------------------------------------
3419 
3428 template <typename T> inline
3430 {
3431  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
3432  throw Error( "Invalid matrix subtraction." );
3433  GenericMatrix<T> R( A.Rows(), A.Cols() );
3434  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3435  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3436  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3437  typename GenericMatrix<T>::const_block_iterator __restrict__ t = B.Begin();
3438  PCL_IVDEP
3439  for ( ; i < j; ++i, ++k, ++t )
3440  *i = *k - *t;
3441  return R;
3442 }
3443 
3449 template <typename T> inline
3451 {
3452  GenericMatrix<T> R( A.Rows(), A.Cols() );
3453  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3454  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3455  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3456  PCL_IVDEP
3457  for ( ; i < j; ++i, ++k )
3458  *i = *k - x;
3459  return R;
3460 }
3461 
3471 template <typename T> inline
3473 {
3474  GenericMatrix<T> R( A.Rows(), A.Cols() );
3475  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3476  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3477  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3478  PCL_IVDEP
3479  for ( ; i < j; ++i, ++k )
3480  *i = x - *k;
3481  return R;
3482 }
3483 
3484 // ----------------------------------------------------------------------------
3485 
3498 template <typename T> inline
3500 {
3501  int n = A.Rows();
3502  int m = B.Cols();
3503  int p = A.Cols();
3504  if ( B.Rows() != p )
3505  throw Error( "Invalid matrix multiplication." );
3506  GenericMatrix<T> R( n, m );
3507  for ( int i = 0; i < n; ++i )
3508  for ( int j = 0; j < m; ++j )
3509  {
3510  T rij = 0;
3511  for ( int k = 0; k < p; ++k )
3512  rij += A[i][k] * B[k][j];
3513  R[i][j] = rij;
3514  }
3515  return R;
3516 }
3517 
3530 template <typename T> inline
3532 {
3533  int n = A.Cols();
3534  int m = A.Rows();
3535  if ( x.Length() != n )
3536  throw Error( "Invalid matrix-vector multiplication." );
3537  GenericVector<T> r( m );
3538  for ( int i = 0; i < m; ++i )
3539  {
3540  T ri = 0;
3541  for ( int j = 0; j < n; ++j )
3542  ri += A[i][j] * x[j];
3543  r[i] = ri;
3544  }
3545  return r;
3546 }
3547 
3553 template <typename T> inline
3555 {
3556  GenericMatrix<T> R( A.Rows(), A.Cols() );
3557  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3558  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3559  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3560  PCL_IVDEP
3561  for ( ; i < j; ++i, ++k )
3562  *i = *k * x;
3563  return R;
3564 }
3565 
3574 template <typename T> inline
3576 {
3577  return A * x;
3578 }
3579 
3580 // ----------------------------------------------------------------------------
3581 
3587 template <typename T> inline
3589 {
3590  GenericMatrix<T> R( A.Rows(), A.Cols() );
3591  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3592  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3593  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3594  PCL_IVDEP
3595  for ( ; i < j; ++i, ++k )
3596  *i = *k / x;
3597  return R;
3598 }
3599 
3608 template <typename T> inline
3610 {
3611  GenericMatrix<T> R( A.Rows(), A.Cols() );
3612  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3613  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3614  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3615  PCL_IVDEP
3616  for ( ; i < j; ++i, ++k )
3617  *i = x / *k;
3618  return R;
3619 }
3620 
3621 // ----------------------------------------------------------------------------
3622 
3628 template <typename T> inline
3630 {
3631  GenericMatrix<T> R( A.Rows(), A.Cols() );
3632  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3633  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3634  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3635  PCL_IVDEP
3636  for ( ; i < j; ++i, ++k )
3637  *i = pcl::Pow( *k, x );
3638  return R;
3639 }
3640 
3649 template <typename T> inline
3651 {
3652  GenericMatrix<T> R( A.Rows(), A.Cols() );
3653  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3654  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3655  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3656  PCL_IVDEP
3657  for ( ; i < j; ++i, ++k )
3658  *i = pcl::Pow( x, *k );
3659  return R;
3660 }
3661 
3662 // ----------------------------------------------------------------------------
3663 
3664 #ifndef __PCL_NO_MATRIX_INSTANTIATE
3665 
3677 using I8Matrix = GenericMatrix<int8>;
3678 
3687 using CharMatrix = I8Matrix;
3688 
3696 using UI8Matrix = GenericMatrix<uint8>;
3697 
3706 using ByteMatrix = UI8Matrix;
3707 
3715 using I16Matrix = GenericMatrix<int16>;
3716 
3724 using UI16Matrix = GenericMatrix<uint16>;
3725 
3733 using I32Matrix = GenericMatrix<int32>;
3734 
3743 using IMatrix = I32Matrix;
3744 
3752 using UI32Matrix = GenericMatrix<uint32>;
3753 
3762 using UIMatrix = UI32Matrix;
3763 
3771 using I64Matrix = GenericMatrix<int64>;
3772 
3780 using UI64Matrix = GenericMatrix<uint64>;
3781 
3789 using F32Matrix = GenericMatrix<float>;
3790 
3799 using FMatrix = F32Matrix;
3800 
3808 using F64Matrix = GenericMatrix<double>;
3809 
3818 using DMatrix = F64Matrix;
3819 
3828 using Matrix = DMatrix;
3829 
3837 using C32Matrix = GenericMatrix<Complex32>;
3838 
3846 using C64Matrix = GenericMatrix<Complex64>;
3847 
3848 #ifndef _MSC_VER
3849 
3861 using F80Matrix = GenericMatrix<long double>;
3862 
3874 using LDMatrix = F80Matrix;
3875 
3876 #endif // !_MSC_VER
3877 
3878 #endif // !__PCL_NO_MATRIX_INSTANTIATE
3879 
3880 // ----------------------------------------------------------------------------
3881 
3882 } // pcl
3883 
3884 #endif // __PCL_Matrix_h
3885 
3886 // ----------------------------------------------------------------------------
3887 // EOF pcl/Matrix.h - Released 2024-06-18T15:48:54Z
bool ParseSelection(Rect &rect, int &firstChannel, int &lastChannel) const noexcept
8-bit unsigned integer matrix.
32-bit floating point complex matrix.
64-bit floating point complex matrix.
8-bit signed integer matrix.
64-bit floating point real matrix.
Root base class of all PCL containers of objects.
Definition: Container.h:78
A simple exception with an associated error message.
Definition: Exception.h:239
32-bit floating point real matrix.
64-bit floating point real matrix.
80-bit extended precision floating point real matrix.
32-bit floating point real matrix.
Implements a generic, two-dimensional, shared or local image.
Definition: Image.h:278
sample * PixelAddress(int x, int y, int channel=0)
Definition: Image.h:6864
GenericImage & AllocateData(int width, int height, int numberOfChannels=1, color_space colorSpace=ColorSpace::Gray)
Definition: Image.h:6484
Generic dynamic matrix of arbitrary dimensions.
Definition: Matrix.h:123
const_block_iterator End() const noexcept
Definition: Matrix.h:1239
double Modulus() const noexcept
Definition: Matrix.h:2278
element MaxElement(Point &p) const noexcept
Definition: Matrix.h:2238
int Cols() const noexcept
Definition: Matrix.h:969
void Rescale(const element &f0=element(0), const element &f1=element(1))
Definition: Matrix.h:2041
static GenericMatrix UnitMatrix(int n)
Definition: Matrix.h:1432
static GenericMatrix RotationZ(double phi)
Definition: Matrix.h:1741
double Variance() const noexcept
Definition: Matrix.h:2365
double TrimmedMean(distance_type l=1, distance_type h=1) const noexcept
Definition: Matrix.h:2343
GenericMatrix Sqrt() const
Definition: Matrix.h:827
void RotateZ(double sphi, double cphi)
Definition: Matrix.h:1933
GenericMatrix Sorted(BP p) const
Definition: Matrix.h:2142
uint64 Hash64(uint64 seed=0) const noexcept
Definition: Matrix.h:2763
vector ColVector(int j) const
Definition: Matrix.h:1351
void Truncate(const element &f0=element(0), const element &f1=element(1))
Definition: Matrix.h:2003
element MinElement() const noexcept
Definition: Matrix.h:2194
void SetSqrt()
Definition: Matrix.h:845
vector ColumnVector(int j) const
Definition: Matrix.h:1338
size_type Size() const noexcept
Definition: Matrix.h:1037
bool Contains(const element &x) const noexcept
Definition: Matrix.h:2183
double AvgDev() const
Definition: Matrix.h:2442
GenericMatrix Transpose() const
Definition: Matrix.h:1446
const_block_iterator FindLast(const element &x) const noexcept
Definition: Matrix.h:2174
void Translate(double dx, double dy)
Definition: Matrix.h:1568
bool IsEmpty() const noexcept
Definition: Matrix.h:1009
GenericMatrix ReverseSorted() const
Definition: Matrix.h:2118
static GenericMatrix Translation(const V &delta)
Definition: Matrix.h:1541
static GenericMatrix RotationY(double sphi, double cphi)
Definition: Matrix.h:1684
void Transfer(GenericMatrix &&x)
Definition: Matrix.h:486
void EnsureUnique()
Definition: Matrix.h:940
element & Element(int i, int j)
Definition: Matrix.h:1108
GenericMatrix Flipped() const
Definition: Matrix.h:1496
GenericMatrix Translated(double dx, double dy) const
Definition: Matrix.h:1600
void SetColumn(int j, const V &c)
Definition: Matrix.h:1373
double StableAvgDev() const
Definition: Matrix.h:2460
TwoSidedEstimate TwoSidedAvgDev(double center) const noexcept
Definition: Matrix.h:2471
GenericMatrix(const T1 *a, int rows, int cols)
Definition: Matrix.h:202
GenericMatrix(const GenericMatrix &x, int i0, int j0, int rows, int cols)
Definition: Matrix.h:301
double StableModulus() const noexcept
Definition: Matrix.h:2289
block_iterator RowPtr(int i) noexcept
Definition: Matrix.h:1285
const_block_iterator ConstEnd() const noexcept
Definition: Matrix.h:1247
block_iterator End()
Definition: Matrix.h:1223
double Sn() const
Definition: Matrix.h:2719
GenericMatrix RotatedY(double phi) const
Definition: Matrix.h:1903
block_iterator end()
Definition: Matrix.h:1310
void SetRow(int i, const V &r)
Definition: Matrix.h:1361
void ToImage(ImageVariant &image) const
Definition: Matrix.h:2986
GenericMatrix Rescaled(const element &f0=element(0), const element &f1=element(1)) const
Definition: Matrix.h:2079
const_block_iterator begin() const noexcept
Definition: Matrix.h:1302
element * block_iterator
Definition: Matrix.h:141
static GenericMatrix RotationY(double phi)
Definition: Matrix.h:1699
bool SameElements(const GenericMatrix &x) const noexcept
Definition: Matrix.h:1086
uint64 Hash(uint64 seed=0) const noexcept
Definition: Matrix.h:2785
const_block_iterator ConstBegin() const noexcept
Definition: Matrix.h:1184
void RotateY(double phi)
Definition: Matrix.h:1880
double Sum() const noexcept
Definition: Matrix.h:2257
void RotateY(double sphi, double cphi)
Definition: Matrix.h:1852
void RotateX(double sphi, double cphi)
Definition: Matrix.h:1771
void RotateZ(double phi)
Definition: Matrix.h:1961
block_iterator begin()
Definition: Matrix.h:1294
TwoSidedEstimate TwoSidedMAD(double center) const
Definition: Matrix.h:2523
TwoSidedEstimate TwoSidedBiweightMidvariance(double center, const TwoSidedEstimate &sigma, int k=9, bool reducedLength=false) const noexcept
Definition: Matrix.h:2627
GenericMatrix Inverse() const
Definition: Matrix.h:3313
element MinElement(Point &p) const noexcept
Definition: Matrix.h:2207
vector RowVector(int i) const
Definition: Matrix.h:1327
void ReverseSort()
Definition: Matrix.h:2108
block_iterator Begin()
Definition: Matrix.h:1161
double SumOfSquares() const noexcept
Definition: Matrix.h:2299
const_block_iterator Begin() const noexcept
Definition: Matrix.h:1176
double StdDev() const noexcept
Definition: Matrix.h:2376
const element & Element(int i, int j) const noexcept
Definition: Matrix.h:1118
GenericMatrix(const T1 &a00, const T1 &a01, const T1 &a10, const T1 &a11)
Definition: Matrix.h:228
double StableSumOfSquares() const noexcept
Definition: Matrix.h:2310
bool IsValid() const noexcept
Definition: Matrix.h:1000
static GenericMatrix FromColumnVector(const vector &c)
Definition: Matrix.h:1410
int Columns() const noexcept
Definition: Matrix.h:980
GenericMatrix RotatedX(double phi) const
Definition: Matrix.h:1822
GenericMatrix(const GenericImage< P > &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:352
GenericMatrix Sorted() const
Definition: Matrix.h:2098
GenericMatrix Translated(const V &delta) const
Definition: Matrix.h:1617
double StableMean() const noexcept
Definition: Matrix.h:2331
size_type NumberOfElements() const noexcept
Definition: Matrix.h:1028
void Sort(BP p)
Definition: Matrix.h:2131
GenericMatrix RotatedZ(double phi) const
Definition: Matrix.h:1984
double StableAvgDev(double center) const noexcept
Definition: Matrix.h:2425
GenericMatrix(const T1 &a00, const T1 &a01, const T1 &a02, const T1 &a10, const T1 &a11, const T1 &a12, const T1 &a20, const T1 &a21, const T1 &a22)
Definition: Matrix.h:249
void RotateX(double phi)
Definition: Matrix.h:1799
double AvgDev(double center) const noexcept
Definition: Matrix.h:2405
double BendMidvariance(double center, double beta=0.2) const
Definition: Matrix.h:2667
void ToImage(GenericImage< P > &image) const
Definition: Matrix.h:2960
static GenericMatrix RotationX(double phi)
Definition: Matrix.h:1657
TwoSidedEstimate TwoSidedAvgDev() const
Definition: Matrix.h:2481
GenericMatrix(const ImageVariant &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:372
GenericMatrix(const element &x, int rows, int cols)
Definition: Matrix.h:181
GenericMatrix RotatedY(double sphi, double cphi) const
Definition: Matrix.h:1892
static GenericMatrix Translation(double dx, double dy)
Definition: Matrix.h:1519
const_block_iterator end() const noexcept
Definition: Matrix.h:1318
static GenericMatrix RotationX(double sphi, double cphi)
Definition: Matrix.h:1642
void Assign(const GenericMatrix &x)
Definition: Matrix.h:439
block_iterator * DataPtr() noexcept
Definition: Matrix.h:1270
static GenericMatrix FromImage(const ImageVariant &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:3103
static GenericMatrix FromRowVector(const vector &r)
Definition: Matrix.h:1397
uint32 Hash32(uint32 seed=0) const noexcept
Definition: Matrix.h:2776
static GenericMatrix FromImage(const GenericImage< P > &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:3054
GenericMatrix(GenericMatrix &&x)
Definition: Matrix.h:273
GenericMatrix(const GenericMatrix &x)
Definition: Matrix.h:264
friend void Swap(GenericMatrix &x1, GenericMatrix &x2) noexcept
Definition: Matrix.h:499
GenericMatrix(int rows, int cols)
Definition: Matrix.h:168
element MaxElement() const noexcept
Definition: Matrix.h:2225
double MAD() const
Definition: Matrix.h:2512
bool IsAliasOf(const GenericMatrix &x) const noexcept
Definition: Matrix.h:928
double BendMidvariance(double beta=0.2) const
Definition: Matrix.h:2691
int Rows() const noexcept
Definition: Matrix.h:960
static GenericMatrix FromColVector(const vector &c)
Definition: Matrix.h:1421
static GenericMatrix RotationZ(double sphi, double cphi)
Definition: Matrix.h:1726
double Mean() const noexcept
Definition: Matrix.h:2320
double Median() const
Definition: Matrix.h:2386
void Transfer(GenericMatrix &x)
Definition: Matrix.h:467
double BiweightMidvariance(int k=9, bool reducedLength=false) const
Definition: Matrix.h:2607
double TrimmedMeanOfSquares(distance_type l=1, distance_type h=1) const noexcept
Definition: Matrix.h:2355
const element * const_block_iterator
Definition: Matrix.h:148
TwoSidedEstimate TwoSidedMAD() const
Definition: Matrix.h:2533
double Qn() const
Definition: Matrix.h:2747
double BiweightMidvariance(double center, double sigma, int k=9, bool reducedLength=false) const noexcept
Definition: Matrix.h:2573
bool IsUnique() const noexcept
Definition: Matrix.h:919
const_block_iterator FindFirst(const element &x) const noexcept
Definition: Matrix.h:2165
GenericMatrix RotatedX(double sphi, double cphi) const
Definition: Matrix.h:1811
GenericMatrix RotatedZ(double sphi, double cphi) const
Definition: Matrix.h:1973
const_block_iterator Find(const element &x) const noexcept
Definition: Matrix.h:2154
GenericMatrix Abs() const
Definition: Matrix.h:874
TwoSidedEstimate TwoSidedBiweightMidvariance(int k=9, bool reducedLength=false) const
Definition: Matrix.h:2639
GenericMatrix Sqr() const
Definition: Matrix.h:780
void SetCol(int j, const V &c)
Definition: Matrix.h:1387
virtual ~GenericMatrix()
Definition: Matrix.h:384
GenericMatrix Truncated(const element &f0=element(0), const element &f1=element(1)) const
Definition: Matrix.h:2019
bool SameDimensions(const GenericMatrix &x) const noexcept
Definition: Matrix.h:1072
double StableSum() const noexcept
Definition: Matrix.h:2268
void Translate(const V &delta)
Definition: Matrix.h:1589
double MAD(double center) const
Definition: Matrix.h:2497
A generic point in the two-dimensional space.
Definition: Point.h:100
A generic rectangle in the two-dimensional space.
Definition: Rectangle.h:314
component y1
Vertical coordinate of the lower right corner.
Definition: Rectangle.h:335
component y0
Vertical coordinate of the upper left corner.
Definition: Rectangle.h:333
component x0
Horizontal coordinate of the upper left corner.
Definition: Rectangle.h:332
component Width() const noexcept
Definition: Rectangle.h:635
component Height() const noexcept
Definition: Rectangle.h:644
Generic vector of arbitrary length.
Definition: Vector.h:107
int Length() const noexcept
Definition: Vector.h:1784
16-bit signed integer matrix.
32-bit signed integer matrix.
64-bit integer matrix.
8-bit signed integer matrix.
32-bit signed integer matrix.
int Width() const noexcept
Definition: ImageGeometry.h:90
int Height() const noexcept
Definition: ImageGeometry.h:98
Rect Bounds() const noexcept
Acts like a union for all types of images in PCL, with optional class-wide ownership of transported i...
Definition: ImageVariant.h:322
bool IsFloatSample() const noexcept
Definition: ImageVariant.h:441
bool IsComplexSample() const noexcept
Definition: ImageVariant.h:449
int BitsPerSample() const noexcept
Definition: ImageVariant.h:458
ImageVariant & CreateFloatImage(int bitSize=32)
80-bit extended precision floating point real matrix.
64-bit floating point real matrix.
Thread-safe reference counter for copy-on-write data structures.
16-bit unsigned integer matrix.
32-bit unsigned integer matrix.
64-bit unsigned integer matrix.
8-bit unsigned integer matrix.
Unsigned integer matrix.
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2267
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2278
Complex< T1 > operator-(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:504
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:548
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:464
Complex< T1 > operator/(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:592
Complex< T1 > Pow(const Complex< T1 > &c, T2 x) noexcept
Definition: Complex.h:747
Complex< T > Sqrt(const Complex< T > &c) noexcept
Definition: Complex.h:674
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
uint64 Hash64(const void *data, size_type size, uint64 seed=0) noexcept
Definition: Math.h:4750
uint32 Hash32(const void *data, size_type size, uint32 seed=0) noexcept
Definition: Math.h:4904
GenericImage< P > operator^(const GenericImage< P > &image, T scalar)
Definition: Image.h:17571
void PCL_FUNC InPlaceGaussJordan(Matrix &A, Matrix &B)
void SinCos(T x, T &sx, T &cx) noexcept
Definition: Math.h:1030
void PhaseCorrelationMatrix(Complex< T > *__restrict__ i, const Complex< T > *__restrict__ j, const Complex< T > *__restrict__ a, const Complex< T > *__restrict__ b) noexcept
Definition: Complex.h:983
static GenericMatrix PhaseCorrelationMatrix(const GenericMatrix &A, const GenericMatrix &B)
Definition: Matrix.h:2915
void CrossPowerSpectrumMatrix(Complex< T > *__restrict__ i, const Complex< T > *__restrict__ j, const Complex< T > *__restrict__ a, const Complex< T > *__restrict__ b) noexcept
Definition: Complex.h:1015
static GenericMatrix CrossPowerSpectrumMatrix(const GenericMatrix &A, const GenericMatrix &B)
Definition: Matrix.h:2928
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
Definition: Point.h:1459
unsigned long long uint64
Definition: Defs.h:682
unsigned int uint32
Definition: Defs.h:666
FI LinearSearch(FI i, FI j, const T &v) noexcept
Definition: Search.h:91
BI LinearSearchLast(BI i, BI j, const T &v) noexcept
Definition: Search.h:129
ptrdiff_t distance_type
Definition: Defs.h:615
size_t size_type
Definition: Defs.h:609
void Sort(BI i, BI j)
Definition: Sort.h:520
double Qn(T *__restrict__ x, T *__restrict__ xn)
Definition: Math.h:4170
double BendMidvariance(const T *__restrict__ x, const T *__restrict__ xn, double center, double beta=0.2)
Definition: Math.h:4480
TwoSidedEstimate TwoSidedMAD(const T *__restrict__ i, const T *__restrict__ j, double center)
Definition: Math.h:3837
double MAD(const T *__restrict__ i, const T *__restrict__ j, double center)
Definition: Math.h:3776
double StableModulus(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2636
double SumOfSquares(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2661
double StableMean(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2728
double TrimmedMean(const T *__restrict__ i, const T *__restrict__ j, distance_type l=1, distance_type h=1)
Definition: Math.h:3242
double StableSum(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2592
double Variance(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:2753
TwoSidedEstimate TwoSidedBiweightMidvariance(const T *__restrict__ x, const T *__restrict__ xn, double center, const TwoSidedEstimate &sigma, int k=9, bool reducedLength=false) noexcept
Definition: Math.h:4404
double Sum(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2573
double StableSumOfSquares(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2683
double BiweightMidvariance(const T *__restrict__ x, const T *__restrict__ xn, double center, double sigma, int k=9, bool reducedLength=false) noexcept
Definition: Math.h:4341
double StdDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:2813
double TrimmedMeanOfSquares(const T *__restrict__ i, const T *__restrict__ j, distance_type l=1, distance_type h=1)
Definition: Math.h:3319
double AvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3404
double Mean(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2709
double StableAvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3436
double Median(const T *__restrict__ i, const T *__restrict__ j)
Definition: Math.h:2878
TwoSidedEstimate TwoSidedAvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3717
double Modulus(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2617
double Sn(T *__restrict__ x, T *__restrict__ xn)
Definition: Math.h:3924
constexpr const T & Min(const T &a, const T &b) noexcept
Definition: Utility.h:90
FI MinItem(FI i, FI j) noexcept
Definition: Utility.h:441
bool Equal(FI1 i1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:592
int Compare(FI1 i1, FI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:639
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
Definition: Utility.h:190
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
FI MaxItem(FI i, FI j) noexcept
Definition: Utility.h:479
PCL root namespace.
Definition: AbstractImage.h:77
Two-sided descriptive statistical estimate.
Definition: Math.h:3528