PCL
Matrix.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.8.5
6 // ----------------------------------------------------------------------------
7 // pcl/Matrix.h - Released 2024-12-28T16:53:48Z
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 
133 
137 
141  using element = T;
142 
147 
154 
161 
167  {
168  m_data = new Data;
169  }
170 
180  GenericMatrix( int rows, int cols )
181  {
182  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
183  m_data = new Data( rows, cols );
184  }
185 
193  GenericMatrix( const element& x, int rows, int cols )
194  {
195  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
196  m_data = new Data( rows, cols );
197  pcl::Fill( m_data->Begin(), m_data->End(), x );
198  }
199 
213  template <typename T1>
214  GenericMatrix( const T1* a, int rows, int cols )
215  {
216  PCL_PRECONDITION( rows >= 0 && cols >= 0 )
217  m_data = new Data( rows, cols );
218  if ( a != nullptr )
219  {
220  block_iterator __restrict__ i = m_data->Begin();
221  const_block_iterator __restrict__ j = m_data->End();
222  const T1* __restrict__ k = a;
223  PCL_IVDEP
224  for ( ; i < j; ++i, ++k )
225  *i = element( *k );
226  }
227  }
228 
239  template <typename T1>
240  GenericMatrix( const T1& a00, const T1& a01,
241  const T1& a10, const T1& a11 )
242  {
243  m_data = new Data( 2, 2 );
244  block_iterator __restrict__ v = m_data->Begin();
245  v[0] = element( a00 ); v[1] = element( a01 );
246  v[2] = element( a10 ); v[3] = element( a11 );
247  }
248 
260  template <typename T1>
261  GenericMatrix( const T1& a00, const T1& a01, const T1& a02,
262  const T1& a10, const T1& a11, const T1& a12,
263  const T1& a20, const T1& a21, const T1& a22 )
264  {
265  m_data = new Data( 3, 3 );
266  block_iterator __restrict__ v = m_data->Begin();
267  v[0] = element( a00 ); v[1] = element( a01 ); v[2] = element( a02 );
268  v[3] = element( a10 ); v[4] = element( a11 ); v[5] = element( a12 );
269  v[6] = element( a20 ); v[7] = element( a21 ); v[8] = element( a22 );
270  }
271 
277  : m_data( x.m_data )
278  {
279  m_data->Attach();
280  }
281 
286  : m_data( x.m_data )
287  {
288  x.m_data = nullptr;
289  }
290 
313  GenericMatrix( const GenericMatrix& x, int i0, int j0, int rows, int cols )
314  {
315  i0 = Range( i0, 0, Max( 0, x.Rows()-1 ) );
316  j0 = Range( j0, 0, Max( 0, x.Cols()-1 ) );
317  rows = Range( rows, 0, Max( 0, x.Rows()-i0 ) );
318  cols = Range( cols, 0, Max( 0, x.Cols()-j0 ) );
319  m_data = new Data( rows, cols );
320  for ( int i = 0; i < m_data->Rows(); ++i, ++i0 )
321  for ( int j = 0; j < m_data->Cols(); ++j, ++j0 )
322  m_data->v[i][j] = x.m_data->v[i0][j0];
323  }
324 
325 #ifndef __PCL_NO_MATRIX_IMAGE_CONVERSION
326 
363  template <class P>
364  GenericMatrix( const GenericImage<P>& image, const Rect& rect = Rect( 0 ), int channel = -1 )
365  {
366  GenericMatrix M = FromImage( image, rect, channel );
367  pcl::Swap( m_data, M.m_data );
368  }
369 
384  GenericMatrix( const ImageVariant& image, const Rect& rect = Rect( 0 ), int channel = -1 )
385  {
386  GenericMatrix M = FromImage( image, rect, channel );
387  pcl::Swap( m_data, M.m_data );
388  }
389 
390 #endif // !__PCL_NO_MATRIX_IMAGE_CONVERSION
391 
396  virtual ~GenericMatrix()
397  {
398  if ( m_data != nullptr )
399  {
400  DetachFromData();
401  m_data = nullptr;
402  }
403  }
404 
408  void Clear()
409  {
410  if ( !IsEmpty() )
411  if ( m_data->IsUnique() )
412  m_data->Deallocate();
413  else
414  {
415  Data* newData = new Data( 0, 0 );
416  DetachFromData();
417  m_data = newData;
418  }
419  }
420 
433  GenericMatrix& operator =( const GenericMatrix& x )
434  {
435  Assign( x );
436  return *this;
437  }
438 
451  void Assign( const GenericMatrix& x )
452  {
453  x.m_data->Attach();
454  DetachFromData();
455  m_data = x.m_data;
456  }
457 
461  GenericMatrix& operator =( GenericMatrix&& x )
462  {
463  Transfer( x );
464  return *this;
465  }
466 
480  {
481  if ( &x != this )
482  {
483  DetachFromData();
484  m_data = x.m_data;
485  x.m_data = nullptr;
486  }
487  }
488 
502  {
503  if ( &x != this )
504  {
505  DetachFromData();
506  m_data = x.m_data;
507  x.m_data = nullptr;
508  }
509  }
510 
517  friend void Swap( GenericMatrix& x1, GenericMatrix& x2 ) noexcept
518  {
519  pcl::Swap( x1.m_data, x2.m_data );
520  }
521 
530  GenericMatrix& operator =( const element& x )
531  {
532  if ( !IsUnique() )
533  {
534  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
535  DetachFromData();
536  m_data = newData;
537  }
538  pcl::Fill( m_data->Begin(), m_data->End(), x );
539  return *this;
540  }
541 
542 #define IMPLEMENT_SCALAR_ASSIGN_OP( op ) \
543  if ( IsUnique() ) \
544  { \
545  block_iterator __restrict__ i = m_data->Begin(); \
546  const_block_iterator __restrict__ j = m_data->End(); \
547  PCL_IVDEP \
548  for ( ; i < j; ++i ) \
549  *i op##= x; \
550  } \
551  else \
552  { \
553  Data* newData = new Data( m_data->Rows(), m_data->Cols() ); \
554  block_iterator __restrict__ i = newData->Begin(); \
555  const_block_iterator __restrict__ j = newData->End(); \
556  const_block_iterator __restrict__ k = m_data->Begin(); \
557  PCL_IVDEP \
558  for ( ; i < j; ++i, ++k ) \
559  *i = *k op x; \
560  DetachFromData(); \
561  m_data = newData; \
562  } \
563  return *this;
564 
573  GenericMatrix& operator +=( const element& x )
574  {
575  IMPLEMENT_SCALAR_ASSIGN_OP( + )
576  }
577 
586  GenericMatrix& operator -=( const element& x )
587  {
588  IMPLEMENT_SCALAR_ASSIGN_OP( - )
589  }
590 
599  GenericMatrix& operator *=( const element& x )
600  {
601  IMPLEMENT_SCALAR_ASSIGN_OP( * )
602  }
603 
612  GenericMatrix& operator /=( const element& x )
613  {
614  IMPLEMENT_SCALAR_ASSIGN_OP( / )
615  }
616 
625  GenericMatrix& operator ^=( const element& x )
626  {
627  if ( IsUnique() )
628  {
629  block_iterator __restrict__ i = m_data->Begin();
630  const_block_iterator __restrict__ j = m_data->End();
631  PCL_IVDEP
632  for ( ; i < j; ++i )
633  *i = pcl::Pow( *i, x );
634  }
635  else
636  {
637  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
638  block_iterator __restrict__ i = newData->Begin();
639  const_block_iterator __restrict__ j = newData->End();
640  const_block_iterator __restrict__ k = m_data->Begin();
641  PCL_IVDEP
642  for ( ; i < j; ++i, ++k )
643  *i = pcl::Pow( *k, x );
644  DetachFromData();
645  m_data = newData;
646  }
647  return *this;
648  }
649 
650 #undef IMPLEMENT_SCALAR_ASSIGN_OP
651 
652 #ifndef __PCL_NO_MATRIX_ELEMENT_WISE_ARITHMETIC_OPERATIONS
653 
654 #define IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( op ) \
655  if ( IsUnique() ) \
656  { \
657  block_iterator __restrict__ i = m_data->Begin(); \
658  const_block_iterator __restrict__ j = pcl::Min( m_data->End(), \
659  m_data->Begin() + x.NumberOfElements() ); \
660  const_block_iterator __restrict__ k = x.m_data->Begin(); \
661  PCL_IVDEP \
662  for ( ; i < j; ++i, ++k ) \
663  *i op##= *k; \
664  } \
665  else \
666  { \
667  Data* newData = new Data( m_data->Rows(), m_data->Cols() ); \
668  block_iterator __restrict__ i = newData->Begin(); \
669  const_block_iterator __restrict__ j = pcl::Min( newData->End(), \
670  newData->Begin() + x.NumberOfElements() ); \
671  const_block_iterator __restrict__ k = x.m_data->Begin(); \
672  const_block_iterator __restrict__ t = m_data->Begin(); \
673  PCL_IVDEP \
674  for ( ; i < j; ++i, ++k, ++t ) \
675  *i = *t op *k; \
676  DetachFromData(); \
677  m_data = newData; \
678  } \
679  return *this;
680 
693  GenericMatrix& operator +=( const GenericMatrix& x )
694  {
695  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( + )
696  }
697 
710  GenericMatrix& operator -=( const GenericMatrix& x )
711  {
712  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( - )
713  }
714 
727  GenericMatrix& operator *=( const GenericMatrix& x )
728  {
729  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( * )
730  }
731 
744  GenericMatrix& operator /=( const GenericMatrix& x )
745  {
746  IMPLEMENT_ELEMENT_WISE_ASSIGN_OP( / )
747  }
748 
760  GenericMatrix& operator ^=( const GenericMatrix& x )
761  {
762  if ( IsUnique() )
763  {
764  block_iterator __restrict__ i = m_data->Begin();
765  const_block_iterator __restrict__ j = pcl::Min( m_data->End(),
766  m_data->Begin() + x.NumberOfElements() );
767  const_block_iterator __restrict__ k = x.m_data->Begin();
768  PCL_IVDEP
769  for ( ; i < j; ++i, ++k )
770  *i = pcl::Pow( *i, *k );
771  }
772  else
773  {
774  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
775  block_iterator __restrict__ i = newData->Begin();
776  const_block_iterator __restrict__ j = pcl::Min( newData->End(),
777  newData->Begin() + x.NumberOfElements() );
778  const_block_iterator __restrict__ k = x.m_data->Begin();
779  const_block_iterator __restrict__ t = m_data->Begin();
780  PCL_IVDEP
781  for ( ; i < j; ++i, ++k, ++t )
782  *i = pcl::Pow( *t, *k );
783  DetachFromData();
784  m_data = newData;
785  }
786  return *this;
787  }
788 
789 #undef IMPLEMENT_ELEMENT_WISE_ASSIGN_OP
790 
791 #endif // __PCL_NO_MATRIX_ELEMENT_WISE_ARITHMETIC_OPERATIONS
792 
799  {
800  GenericMatrix R( m_data->Rows(), m_data->Cols() );
801  block_iterator __restrict__ i = R.m_data->Begin();
802  const_block_iterator __restrict__ j = R.m_data->End();
803  const_block_iterator __restrict__ k = m_data->Begin();
804  PCL_IVDEP
805  for ( ; i < j; ++i, ++k )
806  *i = *k * *k;
807  return R;
808  }
809 
816  void SetSqr()
817  {
818  if ( IsUnique() )
819  {
820  block_iterator __restrict__ i = m_data->Begin();
821  const_block_iterator __restrict__ j = m_data->End();
822  PCL_IVDEP
823  for ( ; i < j; ++i )
824  *i *= *i;
825  }
826  else
827  {
828  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
829  block_iterator __restrict__ i = newData->Begin();
830  const_block_iterator __restrict__ j = newData->End();
831  const_block_iterator __restrict__ k = m_data->Begin();
832  PCL_IVDEP
833  for ( ; i < j; ++i, ++k )
834  *i = *k * *k;
835  DetachFromData();
836  m_data = newData;
837  }
838  }
839 
846  {
847  GenericMatrix R( m_data->Rows(), m_data->Cols() );
848  block_iterator __restrict__ i = R.m_data->Begin();
849  const_block_iterator __restrict__ j = R.m_data->End();
850  const_block_iterator __restrict__ k = m_data->Begin();
851  PCL_IVDEP
852  for ( ; i < j; ++i, ++k )
853  *i = pcl::Sqrt( *k );
854  return R;
855  }
856 
863  void SetSqrt()
864  {
865  if ( IsUnique() )
866  {
867  block_iterator __restrict__ i = m_data->Begin();
868  const_block_iterator __restrict__ j = m_data->End();
869  PCL_IVDEP
870  for ( ; i < j; ++i )
871  *i = pcl::Sqrt( *i );
872  }
873  else
874  {
875  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
876  block_iterator __restrict__ i = newData->Begin();
877  const_block_iterator __restrict__ j = newData->End();
878  const_block_iterator __restrict__ k = m_data->Begin();
879  PCL_IVDEP
880  for ( ; i < j; ++i, ++k )
881  *i = pcl::Sqrt( *k );
882  DetachFromData();
883  m_data = newData;
884  }
885  }
886 
893  {
894  GenericMatrix R( m_data->Rows(), m_data->Cols() );
895  block_iterator __restrict__ i = R.m_data->Begin();
896  const_block_iterator __restrict__ j = R.m_data->End();
897  const_block_iterator __restrict__ k = m_data->Begin();
898  PCL_IVDEP
899  for ( ; i < j; ++i, ++k )
900  *i = pcl::Abs( *k );
901  return R;
902  }
903 
910  void SetAbs()
911  {
912  if ( IsUnique() )
913  {
914  block_iterator __restrict__ i = m_data->Begin();
915  const_block_iterator __restrict__ j = m_data->End();
916  PCL_IVDEP
917  for ( ; i < j; ++i )
918  *i = pcl::Abs( *i );
919  }
920  else
921  {
922  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
923  block_iterator __restrict__ i = newData->Begin();
924  const_block_iterator __restrict__ j = newData->End();
925  const_block_iterator __restrict__ k = m_data->Begin();
926  PCL_IVDEP
927  for ( ; i < j; ++i, ++k )
928  *i = pcl::Abs( *k );
929  DetachFromData();
930  m_data = newData;
931  }
932  }
933 
937  bool IsUnique() const noexcept
938  {
939  return m_data->IsUnique();
940  }
941 
946  bool IsAliasOf( const GenericMatrix& x ) const noexcept
947  {
948  return m_data == x.m_data;
949  }
950 
959  {
960  if ( !IsUnique() )
961  {
962  Data* newData = new Data( m_data->Rows(), m_data->Cols() );
963  const_block_iterator __restrict__ i = m_data->Begin();
964  const_block_iterator __restrict__ j = m_data->End();
965  block_iterator __restrict__ k = newData->Begin();
966  PCL_IVDEP
967  for ( ; i < j; ++i, ++k )
968  *k = *i;
969  DetachFromData();
970  m_data = newData;
971  }
972  }
973 
978  int Rows() const noexcept
979  {
980  return m_data->Rows();
981  }
982 
987  int Cols() const noexcept
988  {
989  return m_data->Cols();
990  }
991 
998  int Columns() const noexcept
999  {
1000  return Cols();
1001  }
1002 
1018  bool IsValid() const noexcept
1019  {
1020  return m_data != nullptr;
1021  }
1022 
1027  bool IsEmpty() const noexcept
1028  {
1029  return Rows() == 0 || Cols() == 0;
1030  }
1031 
1037  operator bool() const noexcept
1038  {
1039  return !IsEmpty();
1040  }
1041 
1046  size_type NumberOfElements() const noexcept
1047  {
1048  return m_data->NumberOfElements();
1049  }
1050 
1055  size_type Size() const noexcept
1056  {
1057  return m_data->Size();
1058  }
1059 
1067  bool operator ==( const GenericMatrix& x ) const noexcept
1068  {
1069  return IsAliasOf( x ) || SameDimensions( x ) && pcl::Equal( Begin(), x.Begin(), x.End() );
1070  }
1071 
1081  bool operator <( const GenericMatrix& x ) const noexcept
1082  {
1083  return !IsAliasOf( x ) && pcl::Compare( Begin(), End(), x.Begin(), x.End() ) < 0;
1084  }
1085 
1090  bool SameDimensions( const GenericMatrix& x ) const noexcept
1091  {
1092  return Rows() == x.Rows() && Cols() == x.Cols();
1093  }
1094 
1104  bool SameElements( const GenericMatrix& x ) const noexcept
1105  {
1106  if ( unlikely( IsAliasOf( x ) ) )
1107  return true;
1108  if ( unlikely( NumberOfElements() != x.NumberOfElements() ) )
1109  return false;
1110  const_block_iterator __restrict__ i = Begin();
1111  const_block_iterator __restrict__ j = End();
1112  const_block_iterator __restrict__ k = x.Begin();
1113  PCL_IVDEP
1114  for ( ; i < j; ++i, ++k )
1115  if ( *i != *k )
1116  return false;
1117  return true;
1118  }
1119 
1126  element& Element( int i, int j )
1127  {
1128  EnsureUnique();
1129  return m_data->Element( i, j );
1130  }
1131 
1136  const element& Element( int i, int j ) const noexcept
1137  {
1138  return m_data->Element( i, j );
1139  }
1140 
1150  block_iterator operator []( int i )
1151  {
1152  EnsureUnique();
1153  return m_data->v[i];
1154  }
1155 
1162  const_block_iterator operator []( int i ) const noexcept
1163  {
1164  return m_data->v[i];
1165  }
1166 
1180  {
1181  EnsureUnique();
1182  return m_data->Begin();
1183  }
1184 
1194  const_block_iterator Begin() const noexcept
1195  {
1196  return m_data->Begin();
1197  }
1198 
1203  {
1204  return Begin();
1205  }
1206 
1214  {
1215  return Begin();
1216  }
1217 
1225  {
1226  return Begin();
1227  }
1228 
1242  {
1243  EnsureUnique();
1244  return m_data->End();
1245  }
1246 
1257  const_block_iterator End() const noexcept
1258  {
1259  return m_data->End();
1260  }
1261 
1266  {
1267  return End();
1268  }
1269 
1289  {
1290  return m_data->v;
1291  }
1292 
1303  block_iterator RowPtr( int i ) noexcept
1304  {
1305  return m_data->v[i];
1306  }
1307 
1308 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1313  {
1314  return Begin();
1315  }
1316 
1320  const_block_iterator begin() const noexcept
1321  {
1322  return Begin();
1323  }
1324 
1329  {
1330  return End();
1331  }
1332 
1336  const_block_iterator end() const noexcept
1337  {
1338  return End();
1339  }
1340 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1341 
1345  vector RowVector( int i ) const
1346  {
1347  vector r( m_data->Cols() );
1348  for ( int j = 0; j < m_data->Cols(); ++j )
1349  r[j] = m_data->v[i][j];
1350  return r;
1351  }
1352 
1356  vector ColumnVector( int j ) const
1357  {
1358  vector c( m_data->Rows() );
1359  for ( int i = 0; i < m_data->Rows(); ++i )
1360  c[i] = m_data->v[i][j];
1361  return c;
1362  }
1363 
1369  vector ColVector( int j ) const
1370  {
1371  return ColumnVector( j );
1372  }
1373 
1378  template <class V>
1379  void SetRow( int i, const V& r )
1380  {
1381  EnsureUnique();
1382  for ( int j = 0; j < m_data->Cols() && j < r.Length(); ++j )
1383  m_data->v[i][j] = element( r[j] );
1384  }
1385 
1390  template <class V>
1391  void SetColumn( int j, const V& c )
1392  {
1393  EnsureUnique();
1394  for ( int i = 0; i < m_data->Rows() && i < c.Length(); ++i )
1395  m_data->v[i][j] = element( c[i] );
1396  }
1397 
1404  template <class V>
1405  void SetCol( int j, const V& c )
1406  {
1407  SetColumn( j, c );
1408  }
1409 
1416  {
1417  GenericMatrix R( element( 0 ), r.Length(), r.Length() );
1418  for ( int j = 0; j < r.Length(); ++j )
1419  R.m_data->v[0][j] = r[j];
1420  return R;
1421  }
1422 
1429  {
1430  GenericMatrix C( element( 0 ), c.Length(), c.Length() );
1431  for ( int i = 0; i < c.Length(); ++i )
1432  C.m_data->v[i][0] = c[i];
1433  return C;
1434  }
1435 
1440  {
1441  return FromColumnVector( c );
1442  }
1443 
1450  static GenericMatrix UnitMatrix( int n )
1451  {
1452  GenericMatrix One( element( 0 ), n, n );
1453  for ( int i = 0; i < n; ++i )
1454  One[i][i] = element( 1 );
1455  return One;
1456  }
1457 
1465  {
1466  GenericMatrix Tr( m_data->Cols(), m_data->Rows() );
1467  for ( int i = 0; i < m_data->Rows(); ++i )
1468  for ( int j = 0; j < m_data->Cols(); ++j )
1469  Tr.m_data->v[j][i] = m_data->v[i][j];
1470  return Tr;
1471  }
1472 
1484 
1495  void Invert();
1496 
1504  void Flip()
1505  {
1506  EnsureUnique();
1507  pcl::Reverse( m_data->Begin(), m_data->End() );
1508  }
1509 
1515  {
1516  GenericMatrix Tf( m_data->Cols(), m_data->Rows() );
1517  pcl::CopyReversed( Tf.m_data->End(), m_data->Begin(), m_data->End() );
1518  return Tf;
1519  }
1520 
1537  static GenericMatrix Translation( double dx, double dy )
1538  {
1539  return GenericMatrix( element( 1 ), element( 0 ), element( dx ),
1540  element( 0 ), element( 1 ), element( dy ),
1541  element( 0 ), element( 0 ), element( 1 ) );
1542  }
1543 
1558  template <class V>
1559  static GenericMatrix Translation( const V& delta )
1560  {
1561  return GenericMatrix( element( 1 ), element( 0 ), element( double( delta[0] ) ),
1562  element( 0 ), element( 1 ), element( double( delta[1] ) ),
1563  element( 0 ), element( 0 ), element( 1 ) );
1564  }
1565 
1586  void Translate( double dx, double dy )
1587  {
1588  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1589  EnsureUnique();
1590  block_iterator __restrict__ A0 = m_data->v[0];
1591  block_iterator __restrict__ A1 = m_data->v[1];
1592  block_iterator __restrict__ A2 = m_data->v[2];
1593  A0[2] = element( A0[2] + A0[0]*dx + A0[1]*dy );
1594  A1[2] = element( A1[2] + A1[0]*dx + A1[1]*dy );
1595  A2[2] = element( A2[2] + A2[0]*dx + A2[1]*dy );
1596  }
1597 
1606  template <class V>
1607  void Translate( const V& delta )
1608  {
1609  Translate( double( delta[0] ), double( delta[1] ) );
1610  }
1611 
1618  GenericMatrix Translated( double dx, double dy ) const
1619  {
1620  GenericMatrix R( *this );
1621  R.Translate( dx, dy );
1622  return R;
1623  }
1624 
1634  template <class V>
1635  GenericMatrix Translated( const V& delta ) const
1636  {
1637  return Translated( double( delta[0] ), double( delta[1] ) );
1638  }
1639 
1660  static GenericMatrix RotationX( double sphi, double cphi )
1661  {
1662  return GenericMatrix( element( 1 ), element( 0 ), element( 0 ),
1663  element( 0 ), element( +cphi ), element( +sphi ),
1664  element( 0 ), element( -sphi ), element( +cphi ) );
1665  }
1666 
1675  static GenericMatrix RotationX( double phi )
1676  {
1677  double sphi, cphi;
1678  SinCos( phi, sphi, cphi );
1679  return RotationX( sphi, cphi );
1680  }
1681 
1702  static GenericMatrix RotationY( double sphi, double cphi )
1703  {
1704  return GenericMatrix( element( +cphi ), element( 0 ), element( -sphi ),
1705  element( 0 ), element( 1 ), element( 0 ),
1706  element( +sphi ), element( 0 ), element( +cphi ) );
1707  }
1708 
1717  static GenericMatrix RotationY( double phi )
1718  {
1719  double sphi, cphi;
1720  SinCos( phi, sphi, cphi );
1721  return RotationY( sphi, cphi );
1722  }
1723 
1744  static GenericMatrix RotationZ( double sphi, double cphi )
1745  {
1746  return GenericMatrix( element( +cphi ), element( +sphi ), element( 0 ),
1747  element( -sphi ), element( +cphi ), element( 0 ),
1748  element( 0 ), element( 0 ), element( 1 ) );
1749  }
1750 
1759  static GenericMatrix RotationZ( double phi )
1760  {
1761  double sphi, cphi;
1762  SinCos( phi, sphi, cphi );
1763  return RotationZ( sphi, cphi );
1764  }
1765 
1789  void RotateX( double sphi, double cphi )
1790  {
1791  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1792  EnsureUnique();
1793  block_iterator __restrict__ A1 = m_data->v[1];
1794  block_iterator __restrict__ A2 = m_data->v[2];
1795  double a10 = cphi*A1[0] + sphi*A2[0];
1796  double a11 = cphi*A1[1] + sphi*A2[1];
1797  double a12 = cphi*A1[2] + sphi*A2[2];
1798  double a20 = -sphi*A1[0] + cphi*A2[0];
1799  double a21 = -sphi*A1[1] + cphi*A2[1];
1800  double a22 = -sphi*A1[2] + cphi*A2[2];
1801  A1[0] = element( a10 );
1802  A1[1] = element( a11 );
1803  A1[2] = element( a12 );
1804  A2[0] = element( a20 );
1805  A2[1] = element( a21 );
1806  A2[2] = element( a22 );
1807  }
1808 
1817  void RotateX( double phi )
1818  {
1819  double sphi, cphi;
1820  SinCos( phi, sphi, cphi );
1821  RotateX( sphi, cphi );
1822  }
1823 
1829  GenericMatrix RotatedX( double sphi, double cphi ) const
1830  {
1831  GenericMatrix R( *this );
1832  R.RotateX( sphi, cphi );
1833  return R;
1834  }
1835 
1840  GenericMatrix RotatedX( double phi ) const
1841  {
1842  GenericMatrix R( *this );
1843  R.RotateX( phi );
1844  return R;
1845  }
1846 
1870  void RotateY( double sphi, double cphi )
1871  {
1872  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1873  EnsureUnique();
1874  block_iterator __restrict__ A0 = m_data->v[0];
1875  block_iterator __restrict__ A2 = m_data->v[2];
1876  double a00 = cphi*A0[0] - sphi*A2[0];
1877  double a01 = cphi*A0[1] - sphi*A2[1];
1878  double a02 = cphi*A0[2] - sphi*A2[2];
1879  double a20 = sphi*A0[0] + cphi*A2[0];
1880  double a21 = sphi*A0[1] + cphi*A2[1];
1881  double a22 = sphi*A0[2] + cphi*A2[2];
1882  A0[0] = a00;
1883  A0[1] = a01;
1884  A0[2] = a02;
1885  A2[0] = a20;
1886  A2[1] = a21;
1887  A2[2] = a22;
1888  }
1889 
1898  void RotateY( double phi )
1899  {
1900  double sphi, cphi;
1901  SinCos( phi, sphi, cphi );
1902  RotateY( sphi, cphi );
1903  }
1904 
1910  GenericMatrix RotatedY( double sphi, double cphi ) const
1911  {
1912  GenericMatrix R( *this );
1913  R.RotateY( sphi, cphi );
1914  return R;
1915  }
1916 
1921  GenericMatrix RotatedY( double phi ) const
1922  {
1923  GenericMatrix R( *this );
1924  R.RotateY( phi );
1925  return R;
1926  }
1927 
1951  void RotateZ( double sphi, double cphi )
1952  {
1953  PCL_PRECONDITION( Rows() == 3 && Cols() == 3 )
1954  EnsureUnique();
1955  block_iterator __restrict__ A0 = m_data->v[0];
1956  block_iterator __restrict__ A1 = m_data->v[1];
1957  double a00 = cphi*A0[0] + sphi*A1[0];
1958  double a01 = cphi*A0[1] + sphi*A1[1];
1959  double a02 = cphi*A0[2] + sphi*A1[2];
1960  double a10 = -sphi*A0[0] + cphi*A1[0];
1961  double a11 = -sphi*A0[1] + cphi*A1[1];
1962  double a12 = -sphi*A0[2] + cphi*A1[2];
1963  A0[0] = a00;
1964  A0[1] = a01;
1965  A0[2] = a02;
1966  A1[0] = a10;
1967  A1[1] = a11;
1968  A1[2] = a12;
1969  }
1970 
1979  void RotateZ( double phi )
1980  {
1981  double sphi, cphi;
1982  SinCos( phi, sphi, cphi );
1983  RotateZ( sphi, cphi );
1984  }
1985 
1991  GenericMatrix RotatedZ( double sphi, double cphi ) const
1992  {
1993  GenericMatrix R( *this );
1994  R.RotateZ( sphi, cphi );
1995  return R;
1996  }
1997 
2002  GenericMatrix RotatedZ( double phi ) const
2003  {
2004  GenericMatrix R( *this );
2005  R.RotateZ( phi );
2006  return R;
2007  }
2008 
2021  void Truncate( const element& f0 = element( 0 ), const element& f1 = element( 1 ) )
2022  {
2023  EnsureUnique();
2024  block_iterator __restrict__ i = m_data->Begin();
2025  block_iterator __restrict__ j = m_data->End();
2026  PCL_IVDEP
2027  for ( ; i < j; ++i )
2028  if ( *i < f0 )
2029  *i = f0;
2030  else if ( *i > f1 )
2031  *i = f1;
2032  }
2033 
2037  GenericMatrix Truncated( const element& f0 = element( 0 ), const element& f1 = element( 1 ) ) const
2038  {
2039  GenericMatrix R( *this );
2040  R.Truncate( f0, f1 );
2041  return R;
2042  }
2043 
2059  void Rescale( const element& f0 = element( 0 ), const element& f1 = element( 1 ) )
2060  {
2061  element v0 = MinElement();
2062  element v1 = MaxElement();
2063  if ( v0 != f0 || v1 != f1 )
2064  {
2065  EnsureUnique();
2066  if ( v0 != v1 )
2067  {
2068  if ( f0 != f1 )
2069  {
2070  block_iterator __restrict__ i = m_data->Begin();
2071  block_iterator __restrict__ j = m_data->End();
2072  double d = (double( f1 ) - double( f0 ))/(double( v1 ) - double( v0 ));
2073  if ( f0 == element( 0 ) )
2074  {
2075  PCL_IVDEP
2076  for ( ; i < j; ++i )
2077  *i = element( d*(*i - v0) );
2078  }
2079  else
2080  {
2081  PCL_IVDEP
2082  for ( ; i < j; ++i )
2083  *i = element( d*(*i - v0) + f0 );
2084  }
2085  }
2086  else
2087  pcl::Fill( m_data->Begin(), m_data->End(), f0 );
2088  }
2089  else
2090  pcl::Fill( m_data->Begin(), m_data->End(), pcl::Range( v0, f0, f1 ) );
2091  }
2092  }
2093 
2097  GenericMatrix Rescaled( const element& f0 = element( 0 ), const element& f1 = element( 1 ) ) const
2098  {
2099  GenericMatrix R( *this );
2100  R.Rescale( f0, f1 );
2101  return R;
2102  }
2103 
2107  void Sort()
2108  {
2109  EnsureUnique();
2110  pcl::Sort( m_data->Begin(), m_data->End() );
2111  }
2112 
2117  {
2118  GenericMatrix R( *this );
2119  R.Sort();
2120  return R;
2121  }
2122 
2127  {
2128  EnsureUnique();
2129  pcl::Sort( m_data->Begin(), m_data->End(),
2130  []( const element& a, const element& b ){ return b < a; } );
2131  }
2132 
2137  {
2138  GenericMatrix R( *this );
2139  R.ReverseSort();
2140  return R;
2141  }
2142 
2148  template <class BP>
2149  void Sort( BP p )
2150  {
2151  EnsureUnique();
2152  pcl::Sort( m_data->Begin(), m_data->End(), p );
2153  }
2154 
2159  template <class BP>
2160  GenericMatrix Sorted( BP p ) const
2161  {
2162  GenericMatrix R( *this );
2163  R.Sort( p );
2164  return R;
2165  }
2166 
2172  const_block_iterator Find( const element& x ) const noexcept
2173  {
2174  const_block_iterator p = pcl::LinearSearch( m_data->Begin(), m_data->End(), x );
2175  return (p != m_data->End()) ? p : nullptr;
2176  }
2177 
2183  const_block_iterator FindFirst( const element& x ) const noexcept
2184  {
2185  return Find( x );
2186  }
2187 
2192  const_block_iterator FindLast( const element& x ) const noexcept
2193  {
2194  const_block_iterator p = pcl::LinearSearchLast( m_data->Begin(), m_data->End(), x );
2195  return (p != m_data->End()) ? p : nullptr;
2196  }
2197 
2201  bool Contains( const element& x ) const noexcept
2202  {
2203  return pcl::LinearSearch( m_data->Begin(), m_data->End(), x ) != m_data->End();
2204  }
2205 
2206 #ifndef __PCL_NO_MATRIX_STATISTICS
2207 
2212  element MinElement() const noexcept
2213  {
2214  if ( !IsEmpty() )
2215  return *MinItem( m_data->Begin(), m_data->End() );
2216  return element( 0 );
2217  }
2218 
2225  element MinElement( Point& p ) const noexcept
2226  {
2227  if ( !IsEmpty() )
2228  {
2229  const_block_iterator m = MinItem( m_data->Begin(), m_data->End() );
2230  distance_type d = m - m_data->Begin();
2231  p.y = int( d/m_data->Cols() );
2232  p.x = int( d%m_data->Cols() );
2233  return *m;
2234  }
2235  p = 0;
2236  return element( 0 );
2237  }
2238 
2243  element MaxElement() const noexcept
2244  {
2245  if ( !IsEmpty() )
2246  return *MaxItem( m_data->Begin(), m_data->End() );
2247  return element( 0 );
2248  }
2249 
2256  element MaxElement( Point& p ) const noexcept
2257  {
2258  if ( !IsEmpty() )
2259  {
2260  const_block_iterator m = MaxItem( m_data->Begin(), m_data->End() );
2261  int d = m - m_data->Begin();
2262  p.y = d/m_data->Cols();
2263  p.x = d%m_data->Cols();
2264  return *m;
2265  }
2266  p = 0;
2267  return element( 0 );
2268  }
2269 
2275  double Sum() const noexcept
2276  {
2277  return pcl::Sum( m_data->Begin(), m_data->End() );
2278  }
2279 
2286  double StableSum() const noexcept
2287  {
2288  return pcl::StableSum( m_data->Begin(), m_data->End() );
2289  }
2290 
2296  double Modulus() const noexcept
2297  {
2298  return pcl::Modulus( m_data->Begin(), m_data->End() );
2299  }
2300 
2307  double StableModulus() const noexcept
2308  {
2309  return pcl::StableModulus( m_data->Begin(), m_data->End() );
2310  }
2311 
2317  double SumOfSquares() const noexcept
2318  {
2319  return pcl::SumOfSquares( m_data->Begin(), m_data->End() );
2320  }
2321 
2328  double StableSumOfSquares() const noexcept
2329  {
2330  return pcl::StableSumOfSquares( m_data->Begin(), m_data->End() );
2331  }
2332 
2338  double Mean() const noexcept
2339  {
2340  return pcl::Mean( m_data->Begin(), m_data->End() );
2341  }
2342 
2349  double StableMean() const noexcept
2350  {
2351  return pcl::StableMean( m_data->Begin(), m_data->End() );
2352  }
2353 
2361  double TrimmedMean( distance_type l = 1, distance_type h = 1 ) const noexcept
2362  {
2363  return pcl::TrimmedMean( m_data->Begin(), m_data->End(), l, h );
2364  }
2365 
2373  double TrimmedMeanOfSquares( distance_type l = 1, distance_type h = 1 ) const noexcept
2374  {
2375  return pcl::TrimmedMeanOfSquares( m_data->Begin(), m_data->End(), l, h );
2376  }
2377 
2383  double Variance() const noexcept
2384  {
2385  return pcl::Variance( m_data->Begin(), m_data->End() );
2386  }
2387 
2394  double StdDev() const noexcept
2395  {
2396  return pcl::StdDev( m_data->Begin(), m_data->End() );
2397  }
2398 
2404  double Median() const
2405  {
2406  return pcl::Median( m_data->Begin(), m_data->End() );
2407  }
2408 
2423  double AvgDev( double center ) const noexcept
2424  {
2425  return pcl::AvgDev( m_data->Begin(), m_data->End(), center );
2426  }
2427 
2443  double StableAvgDev( double center ) const noexcept
2444  {
2445  return pcl::StableAvgDev( m_data->Begin(), m_data->End(), center );
2446  }
2447 
2460  double AvgDev() const
2461  {
2462  return pcl::AvgDev( m_data->Begin(), m_data->End() );
2463  }
2464 
2478  double StableAvgDev() const
2479  {
2480  return pcl::StableAvgDev( m_data->Begin(), m_data->End() );
2481  }
2482 
2489  TwoSidedEstimate TwoSidedAvgDev( double center ) const noexcept
2490  {
2491  return pcl::TwoSidedAvgDev( m_data->Begin(), m_data->End(), center );
2492  }
2493 
2500  {
2501  return pcl::TwoSidedAvgDev( m_data->Begin(), m_data->End() );
2502  }
2503 
2515  double MAD( double center ) const
2516  {
2517  return pcl::MAD( m_data->Begin(), m_data->End(), center );
2518  }
2519 
2530  double MAD() const
2531  {
2532  return pcl::MAD( m_data->Begin(), m_data->End() );
2533  }
2534 
2541  TwoSidedEstimate TwoSidedMAD( double center ) const
2542  {
2543  return pcl::TwoSidedMAD( m_data->Begin(), m_data->End(), center );
2544  }
2545 
2552  {
2553  return pcl::TwoSidedMAD( m_data->Begin(), m_data->End() );
2554  }
2555 
2591  double BiweightMidvariance( double center, double sigma, int k = 9, bool reducedLength = false ) const noexcept
2592  {
2593  return pcl::BiweightMidvariance( m_data->Begin(), m_data->End(), center, sigma, k, reducedLength );
2594  }
2595 
2625  double BiweightMidvariance( int k = 9, bool reducedLength = false ) const
2626  {
2627  double center = Median();
2628  return BiweightMidvariance( center, MAD( center ), k, reducedLength );
2629  }
2630 
2646  int k = 9, bool reducedLength = false ) const noexcept
2647  {
2648  return pcl::TwoSidedBiweightMidvariance( m_data->Begin(), m_data->End(), center, sigma, k, reducedLength );
2649  }
2650 
2657  TwoSidedEstimate TwoSidedBiweightMidvariance( int k = 9, bool reducedLength = false ) const
2658  {
2659  double center = Median();
2660  return TwoSidedBiweightMidvariance( center, TwoSidedMAD( center ), k, reducedLength );
2661  }
2662 
2685  double BendMidvariance( double center, double beta = 0.2 ) const
2686  {
2687  return pcl::BendMidvariance( m_data->Begin(), m_data->End(), center, beta );
2688  }
2689 
2709  double BendMidvariance( double beta = 0.2 ) const
2710  {
2711  return pcl::BendMidvariance( m_data->Begin(), m_data->End(), Median(), beta );
2712  }
2713 
2737  double Sn() const
2738  {
2739  GenericMatrix A( *this );
2740  return pcl::Sn( A.Begin(), A.End() );
2741  }
2742 
2765  double Qn() const
2766  {
2767  GenericMatrix A( *this );
2768  return pcl::Qn( A.Begin(), A.End() );
2769  }
2770 
2771 #endif // !__PCL_NO_MATRIX_STATISTICS
2772 
2781  uint64 Hash64( uint64 seed = 0 ) const noexcept
2782  {
2783  return pcl::Hash64( m_data->Begin(), m_data->Size(), seed );
2784  }
2785 
2794  uint32 Hash32( uint32 seed = 0 ) const noexcept
2795  {
2796  return pcl::Hash32( m_data->Begin(), m_data->Size(), seed );
2797  }
2798 
2803  uint64 Hash( uint64 seed = 0 ) const noexcept
2804  {
2805  return Hash64( seed );
2806  }
2807 
2824  template <class S, typename SP>
2825  S& ToSeparated( S& s, SP separator ) const
2826  {
2827  const_block_iterator i = m_data->Begin(), j = m_data->End();
2828  if ( i < j )
2829  {
2830  s.Append( S( *i ) );
2831  if ( ++i < j )
2832  do
2833  {
2834  s.Append( separator );
2835  s.Append( S( *i ) );
2836  }
2837  while ( ++i < j );
2838  }
2839  return s;
2840  }
2841 
2864  template <class S, typename SP, class AF>
2865  S& ToSeparated( S& s, SP separator, AF append ) const
2866  {
2867  const_block_iterator i = m_data->Begin(), j = m_data->End();
2868  if ( i < j )
2869  {
2870  append( s, S( *i ) );
2871  if ( ++i < j )
2872  {
2873  S p( separator );
2874  do
2875  {
2876  append( s, p );
2877  append( s, S( *i ) );
2878  }
2879  while ( ++i < j );
2880  }
2881  }
2882  return s;
2883  }
2884 
2893  template <class S>
2894  S& ToCommaSeparated( S& s ) const
2895  {
2896  return ToSeparated( s, ',' );
2897  }
2898 
2907  template <class S>
2908  S& ToSpaceSeparated( S& s ) const
2909  {
2910  return ToSeparated( s, ' ' );
2911  }
2912 
2921  template <class S>
2922  S& ToTabSeparated( S& s ) const
2923  {
2924  return ToSeparated( s, '\t' );
2925  }
2926 
2927 #ifndef __PCL_NO_MATRIX_PHASE_MATRICES
2928 
2934  {
2935  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
2936  throw Error( "Invalid matrix dimensions in PhaseCorrelationMatrix()" );
2937  GenericMatrix R( A.Rows(), A.Cols() );
2938  PhaseCorrelationMatrix( R.Begin(), R.End(), A.Begin(), B.Begin() );
2939  return R;
2940  }
2941 
2947  {
2948  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
2949  throw Error( "Invalid matrix dimensions in CrossPowerSpectrumMatrix()" );
2950  GenericMatrix R( A.Rows(), A.Cols() );
2951  CrossPowerSpectrumMatrix( R.Begin(), R.End(), A.Begin(), B.Begin() );
2952  return R;
2953  }
2954 
2955 #endif // !__PCL_NO_MATRIX_PHASE_MATRICES
2956 
2957 #ifndef __PCL_NO_MATRIX_IMAGE_RENDERING
2958 
2977  template <class P>
2978  void ToImage( GenericImage<P>& image ) const
2979  {
2980  image.AllocateData( Cols(), Rows() );
2981  typename P::sample* __restrict__ v = *image;
2982  const_block_iterator __restrict__ i = m_data->Begin();
2983  const_block_iterator __restrict__ j = m_data->End();
2984  PCL_IVDEP
2985  for ( ; i < j; ++i, ++v )
2986  *v = P::ToSample( *i );
2987  }
2988 
3004  void ToImage( ImageVariant& image ) const
3005  {
3006  if ( !image )
3007  image.CreateFloatImage();
3008 
3009  if ( image.IsFloatSample() )
3010  switch ( image.BitsPerSample() )
3011  {
3012  case 32: ToImage( static_cast<Image&>( *image ) ); break;
3013  case 64: ToImage( static_cast<DImage&>( *image ) ); break;
3014  }
3015  else if ( image.IsComplexSample() )
3016  switch ( image.BitsPerSample() )
3017  {
3018  case 32: ToImage( static_cast<ComplexImage&>( *image ) ); break;
3019  case 64: ToImage( static_cast<DComplexImage&>( *image ) ); break;
3020  }
3021  else
3022  switch ( image.BitsPerSample() )
3023  {
3024  case 8: ToImage( static_cast<UInt8Image&>( *image ) ); break;
3025  case 16: ToImage( static_cast<UInt16Image&>( *image ) ); break;
3026  case 32: ToImage( static_cast<UInt32Image&>( *image ) ); break;
3027  }
3028  }
3029 
3030 #endif // !__PCL_NO_MATRIX_IMAGE_RENDERING
3031 
3032 #ifndef __PCL_NO_MATRIX_IMAGE_CONVERSION
3033 
3071  template <class P>
3072  static GenericMatrix FromImage( const GenericImage<P>& image, const Rect& rect = Rect( 0 ), int channel = -1 )
3073  {
3074  Rect r = rect;
3075  if ( !image.ParseSelection( r, channel ) )
3076  return GenericMatrix();
3077 
3078  if ( r == image.Bounds() )
3079  {
3080  GenericMatrix M( image.Height(), image.Width() );
3081  const typename P::sample* __restrict__ v = image[channel];
3082  block_iterator __restrict__ i = M.m_data->Begin();
3083  const_block_iterator __restrict__ j = M.m_data->End();
3084  PCL_IVDEP
3085  for ( ; i < j; ++i, ++v )
3086  P::FromSample( *i, *v );
3087  return M;
3088  }
3089  else
3090  {
3091  int w = r.Width();
3092  int h = r.Height();
3093  GenericMatrix M( h, w );
3094  block_iterator __restrict__ m = M.m_data->Begin();
3095  PCL_IVDEP
3096  for ( int i = r.y0; i < r.y1; ++i )
3097  {
3098  const typename P::sample* __restrict__ v = image.PixelAddress( r.x0, i, channel );
3099  PCL_IVDEP
3100  for ( int j = 0; j < w; ++j )
3101  P::FromSample( *m++, *v++ );
3102  }
3103  return M;
3104  }
3105  }
3106 
3121  static GenericMatrix FromImage( const ImageVariant& image, const Rect& rect = Rect( 0 ), int channel = -1 )
3122  {
3123  if ( image )
3124  if ( image.IsFloatSample() )
3125  switch ( image.BitsPerSample() )
3126  {
3127  case 32: return FromImage( static_cast<const Image&>( *image ), rect, channel );
3128  case 64: return FromImage( static_cast<const DImage&>( *image ), rect, channel );
3129  }
3130  else if ( image.IsComplexSample() )
3131  switch ( image.BitsPerSample() )
3132  {
3133  case 32: return FromImage( static_cast<const ComplexImage&>( *image ), rect, channel );
3134  case 64: return FromImage( static_cast<const DComplexImage&>( *image ), rect, channel );
3135  }
3136  else
3137  switch ( image.BitsPerSample() )
3138  {
3139  case 8: return FromImage( static_cast<const UInt8Image&>( *image ), rect, channel );
3140  case 16: return FromImage( static_cast<const UInt16Image&>( *image ), rect, channel );
3141  case 32: return FromImage( static_cast<const UInt32Image&>( *image ), rect, channel );
3142  }
3143 
3144  return GenericMatrix();
3145  }
3146 
3147 #endif // !__PCL_NO_MATRIX_IMAGE_CONVERSION
3148 
3149 private:
3150 
3156  struct Data : public ReferenceCounter
3157  {
3158  int n = 0;
3159  int m = 0;
3160  block_iterator* v = nullptr;
3161 
3162  Data() = default;
3163 
3164  Data( int rows, int cols )
3165  {
3166  if ( rows > 0 && cols > 0 )
3167  Allocate( rows, cols );
3168  }
3169 
3170  ~Data()
3171  {
3172  Deallocate();
3173  }
3174 
3175  int Rows() const noexcept
3176  {
3177  return n;
3178  }
3179 
3180  int Cols() const noexcept
3181  {
3182  return m;
3183  }
3184 
3185  size_type NumberOfElements() const noexcept
3186  {
3187  return size_type( n )*size_type( m );
3188  }
3189 
3190  size_type Size() const noexcept
3191  {
3192  return NumberOfElements()*sizeof( element );
3193  }
3194 
3195  block_iterator Begin() const
3196  {
3197  block_iterator p = (v != nullptr) ? *v : nullptr;
3198  if ( likely( std::is_scalar<element>::value ) )
3199  return reinterpret_cast<block_iterator>( PCL_ASSUME_ALIGNED_32( p ) );
3200  return p;
3201  }
3202 
3203  block_iterator End() const noexcept
3204  {
3205  return (v != nullptr) ? *v + NumberOfElements() : nullptr;
3206  }
3207 
3208  element& Element( int i, int j ) const noexcept
3209  {
3210  return v[i][j];
3211  }
3212 
3213  void Allocate( int rows, int cols )
3214  {
3215  n = rows;
3216  m = cols;
3217  v = new block_iterator[ n ];
3218  if ( likely( std::is_scalar<element>::value ) )
3219  {
3220  *v = reinterpret_cast<block_iterator>( PCL_ALIGNED_MALLOC( Size(), 32 ) );
3221  if ( unlikely( *v == nullptr ) )
3222  {
3223  delete [] v;
3224  v = nullptr;
3225  n = m = 0;
3226  throw std::bad_alloc();
3227  }
3228  }
3229  else
3230  *v = new element[ NumberOfElements() ];
3231  for ( int i = 1; i < n; ++i )
3232  v[i] = v[i-1] + m;
3233  }
3234 
3235  void Deallocate()
3236  {
3237  PCL_PRECONDITION( refCount == 0 )
3238  if ( v != nullptr )
3239  {
3240  if ( likely( std::is_scalar<element>::value ) )
3241  PCL_ALIGNED_FREE( *v );
3242  else
3243  delete [] *v;
3244  delete [] v;
3245  v = nullptr;
3246  n = m = 0;
3247  }
3248  }
3249  };
3250 
3255  Data* m_data = nullptr;
3256 
3261  void DetachFromData()
3262  {
3263  if ( !m_data->Detach() )
3264  delete m_data;
3265  }
3266 
3271  static bool Invert( block_iterator* Ai, const_block_iterator const* A, int n ) noexcept
3272  {
3273  switch ( n )
3274  {
3275  case 1:
3276  if ( 1 + **A == 1 )
3277  return false;
3278  **Ai = 1/(**A);
3279  break;
3280  case 2:
3281  {
3282  const_block_iterator __restrict__ A0 = A[0];
3283  const_block_iterator __restrict__ A1 = A[1];
3284  element d = A0[0]*A1[1] - A0[1]*A1[0];
3285  if ( 1 + d == 1 )
3286  return false;
3287  Ai[0][0] = A1[1]/d;
3288  Ai[0][1] = -A0[1]/d;
3289  Ai[1][0] = -A1[0]/d;
3290  Ai[1][1] = A0[0]/d;
3291  }
3292  break;
3293  case 3:
3294  {
3295  const_block_iterator __restrict__ A0 = A[0];
3296  const_block_iterator __restrict__ A1 = A[1];
3297  const_block_iterator __restrict__ A2 = A[2];
3298  element d1 = A1[1]*A2[2] - A1[2]*A2[1];
3299  element d2 = A1[2]*A2[0] - A1[0]*A2[2];
3300  element d3 = A1[0]*A2[1] - A1[1]*A2[0];
3301  element d = A0[0]*d1 + A0[1]*d2 + A0[2]*d3;
3302  if ( 1 + d == 1 )
3303  return false;
3304  Ai[0][0] = d1/d;
3305  Ai[0][1] = (A2[1]*A0[2] - A2[2]*A0[1])/d;
3306  Ai[0][2] = (A0[1]*A1[2] - A0[2]*A1[1])/d;
3307  Ai[1][0] = d2/d;
3308  Ai[1][1] = (A2[2]*A0[0] - A2[0]*A0[2])/d;
3309  Ai[1][2] = (A0[2]*A1[0] - A0[0]*A1[2])/d;
3310  Ai[2][0] = d3/d;
3311  Ai[2][1] = (A2[0]*A0[1] - A2[1]*A0[0])/d;
3312  Ai[2][2] = (A0[0]*A1[1] - A0[1]*A1[0])/d;
3313  }
3314  break;
3315  default: // ?!
3316  return false;
3317  }
3318  return true;
3319  }
3320 };
3321 
3322 // ### N.B.: Visual C++ is unable to compile the next two member functions if
3323 // the following external function declarations are placed within the
3324 // member function bodies. This forces us to implement them after the
3325 // GenericMatrix<> class declaration.
3326 
3327 void PCL_FUNC InPlaceGaussJordan( GenericMatrix<double>&, GenericMatrix<double>& );
3328 void PCL_FUNC InPlaceGaussJordan( GenericMatrix<float>&, GenericMatrix<float>& );
3329 
3330 template <typename T> inline
3332 {
3333  if ( Rows() != Cols() || Rows() == 0 )
3334  throw Error( "Invalid matrix inversion: Non-square or empty matrix." );
3335 
3336  /*
3337  * - Use direct formulae to invert 1x1, 2x2 and 3x3 matrices.
3338  * - Use Gauss-Jordan elimination to invert 4x4 and larger matrices.
3339  */
3340  if ( Rows() < 4 )
3341  {
3342  GenericMatrix Ai( Rows(), Rows() );
3343  if ( !Invert( Ai.m_data->v, m_data->v, Rows() ) )
3344  throw Error( "Invalid matrix inversion: Singular matrix." );
3345  return Ai;
3346  }
3347  else
3348  {
3349  GenericMatrix Ai( *this );
3350  GenericMatrix B = UnitMatrix( Rows() );
3351  InPlaceGaussJordan( Ai, B );
3352  return Ai;
3353  }
3354 }
3355 
3356 template <typename T> inline
3358 {
3359  if ( Rows() <= 3 )
3360  Transfer( Inverse() );
3361  else
3362  {
3363  if ( Rows() != Cols() || Rows() == 0 )
3364  throw Error( "Invalid matrix inversion: Non-square or empty matrix." );
3365  EnsureUnique();
3366  GenericMatrix B = UnitMatrix( Rows() );
3367  InPlaceGaussJordan( *this, B );
3368  }
3369 }
3370 
3371 // ----------------------------------------------------------------------------
3372 
3388 template <typename T> inline
3390 {
3391  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
3392  throw Error( "Invalid matrix addition." );
3393  GenericMatrix<T> R( A.Rows(), A.Cols() );
3394  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3395  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3396  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3397  typename GenericMatrix<T>::const_block_iterator __restrict__ t = B.Begin();
3398  PCL_IVDEP
3399  for ( ; i < j; ++i, ++k, ++t )
3400  *i = *k + *t;
3401  return R;
3402 }
3403 
3409 template <typename T> inline
3411 {
3412  GenericMatrix<T> R( A.Rows(), A.Cols() );
3413  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3414  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3415  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3416  PCL_IVDEP
3417  for ( ; i < j; ++i, ++k )
3418  *i = *k + x;
3419  return R;
3420 }
3421 
3430 template <typename T> inline
3432 {
3433  return A + x;
3434 }
3435 
3436 // ----------------------------------------------------------------------------
3437 
3446 template <typename T> inline
3448 {
3449  if ( B.Rows() != A.Rows() || B.Cols() != A.Cols() )
3450  throw Error( "Invalid matrix subtraction." );
3451  GenericMatrix<T> R( A.Rows(), A.Cols() );
3452  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3453  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3454  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3455  typename GenericMatrix<T>::const_block_iterator __restrict__ t = B.Begin();
3456  PCL_IVDEP
3457  for ( ; i < j; ++i, ++k, ++t )
3458  *i = *k - *t;
3459  return R;
3460 }
3461 
3467 template <typename T> inline
3469 {
3470  GenericMatrix<T> R( A.Rows(), A.Cols() );
3471  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3472  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3473  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3474  PCL_IVDEP
3475  for ( ; i < j; ++i, ++k )
3476  *i = *k - x;
3477  return R;
3478 }
3479 
3489 template <typename T> inline
3491 {
3492  GenericMatrix<T> R( A.Rows(), A.Cols() );
3493  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3494  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3495  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3496  PCL_IVDEP
3497  for ( ; i < j; ++i, ++k )
3498  *i = x - *k;
3499  return R;
3500 }
3501 
3502 // ----------------------------------------------------------------------------
3503 
3516 template <typename T> inline
3518 {
3519  int n = A.Rows();
3520  int m = B.Cols();
3521  int p = A.Cols();
3522  if ( B.Rows() != p )
3523  throw Error( "Invalid matrix multiplication." );
3524  GenericMatrix<T> R( n, m );
3525  for ( int i = 0; i < n; ++i )
3526  for ( int j = 0; j < m; ++j )
3527  {
3528  T rij = 0;
3529  for ( int k = 0; k < p; ++k )
3530  rij += A[i][k] * B[k][j];
3531  R[i][j] = rij;
3532  }
3533  return R;
3534 }
3535 
3548 template <typename T> inline
3550 {
3551  int n = A.Cols();
3552  int m = A.Rows();
3553  if ( x.Length() != n )
3554  throw Error( "Invalid matrix-vector multiplication." );
3555  GenericVector<T> r( m );
3556  for ( int i = 0; i < m; ++i )
3557  {
3558  T ri = 0;
3559  for ( int j = 0; j < n; ++j )
3560  ri += A[i][j] * x[j];
3561  r[i] = ri;
3562  }
3563  return r;
3564 }
3565 
3571 template <typename T> inline
3573 {
3574  GenericMatrix<T> R( A.Rows(), A.Cols() );
3575  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3576  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3577  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3578  PCL_IVDEP
3579  for ( ; i < j; ++i, ++k )
3580  *i = *k * x;
3581  return R;
3582 }
3583 
3592 template <typename T> inline
3594 {
3595  return A * x;
3596 }
3597 
3598 // ----------------------------------------------------------------------------
3599 
3605 template <typename T> inline
3607 {
3608  GenericMatrix<T> R( A.Rows(), A.Cols() );
3609  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3610  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3611  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3612  PCL_IVDEP
3613  for ( ; i < j; ++i, ++k )
3614  *i = *k / x;
3615  return R;
3616 }
3617 
3626 template <typename T> inline
3628 {
3629  GenericMatrix<T> R( A.Rows(), A.Cols() );
3630  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3631  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3632  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3633  PCL_IVDEP
3634  for ( ; i < j; ++i, ++k )
3635  *i = x / *k;
3636  return R;
3637 }
3638 
3639 // ----------------------------------------------------------------------------
3640 
3646 template <typename T> inline
3648 {
3649  GenericMatrix<T> R( A.Rows(), A.Cols() );
3650  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3651  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3652  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3653  PCL_IVDEP
3654  for ( ; i < j; ++i, ++k )
3655  *i = pcl::Pow( *k, x );
3656  return R;
3657 }
3658 
3667 template <typename T> inline
3669 {
3670  GenericMatrix<T> R( A.Rows(), A.Cols() );
3671  typename GenericMatrix<T>::block_iterator __restrict__ i = R.Begin();
3672  typename GenericMatrix<T>::const_block_iterator __restrict__ j = R.End();
3673  typename GenericMatrix<T>::const_block_iterator __restrict__ k = A.Begin();
3674  PCL_IVDEP
3675  for ( ; i < j; ++i, ++k )
3676  *i = pcl::Pow( x, *k );
3677  return R;
3678 }
3679 
3680 // ----------------------------------------------------------------------------
3681 
3682 #ifndef __PCL_NO_MATRIX_INSTANTIATE
3683 
3695 using I8Matrix = GenericMatrix<int8>;
3696 
3705 using CharMatrix = I8Matrix;
3706 
3714 using UI8Matrix = GenericMatrix<uint8>;
3715 
3724 using ByteMatrix = UI8Matrix;
3725 
3733 using I16Matrix = GenericMatrix<int16>;
3734 
3742 using UI16Matrix = GenericMatrix<uint16>;
3743 
3751 using I32Matrix = GenericMatrix<int32>;
3752 
3761 using IMatrix = I32Matrix;
3762 
3770 using UI32Matrix = GenericMatrix<uint32>;
3771 
3780 using UIMatrix = UI32Matrix;
3781 
3789 using I64Matrix = GenericMatrix<int64>;
3790 
3798 using UI64Matrix = GenericMatrix<uint64>;
3799 
3807 using F32Matrix = GenericMatrix<float>;
3808 
3817 using FMatrix = F32Matrix;
3818 
3826 using F64Matrix = GenericMatrix<double>;
3827 
3836 using DMatrix = F64Matrix;
3837 
3846 using Matrix = DMatrix;
3847 
3855 using C32Matrix = GenericMatrix<Complex32>;
3856 
3864 using C64Matrix = GenericMatrix<Complex64>;
3865 
3866 #ifndef _MSC_VER
3867 
3879 using F80Matrix = GenericMatrix<long double>;
3880 
3892 using LDMatrix = F80Matrix;
3893 
3894 #endif // !_MSC_VER
3895 
3896 #endif // !__PCL_NO_MATRIX_INSTANTIATE
3897 
3898 // ----------------------------------------------------------------------------
3899 
3900 } // pcl
3901 
3902 #endif // __PCL_Matrix_h
3903 
3904 // ----------------------------------------------------------------------------
3905 // EOF pcl/Matrix.h - Released 2024-12-28T16:53:48Z
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
const T const_item_type
Definition: Container.h:89
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:1257
double Modulus() const noexcept
Definition: Matrix.h:2296
element MaxElement(Point &p) const noexcept
Definition: Matrix.h:2256
int Cols() const noexcept
Definition: Matrix.h:987
void Rescale(const element &f0=element(0), const element &f1=element(1))
Definition: Matrix.h:2059
static GenericMatrix UnitMatrix(int n)
Definition: Matrix.h:1450
static GenericMatrix RotationZ(double phi)
Definition: Matrix.h:1759
double Variance() const noexcept
Definition: Matrix.h:2383
double TrimmedMean(distance_type l=1, distance_type h=1) const noexcept
Definition: Matrix.h:2361
GenericMatrix Sqrt() const
Definition: Matrix.h:845
void RotateZ(double sphi, double cphi)
Definition: Matrix.h:1951
GenericMatrix Sorted(BP p) const
Definition: Matrix.h:2160
uint64 Hash64(uint64 seed=0) const noexcept
Definition: Matrix.h:2781
vector ColVector(int j) const
Definition: Matrix.h:1369
void Truncate(const element &f0=element(0), const element &f1=element(1))
Definition: Matrix.h:2021
element MinElement() const noexcept
Definition: Matrix.h:2212
void SetSqrt()
Definition: Matrix.h:863
vector ColumnVector(int j) const
Definition: Matrix.h:1356
size_type Size() const noexcept
Definition: Matrix.h:1055
bool Contains(const element &x) const noexcept
Definition: Matrix.h:2201
double AvgDev() const
Definition: Matrix.h:2460
GenericMatrix Transpose() const
Definition: Matrix.h:1464
const_block_iterator FindLast(const element &x) const noexcept
Definition: Matrix.h:2192
void Translate(double dx, double dy)
Definition: Matrix.h:1586
bool IsEmpty() const noexcept
Definition: Matrix.h:1027
GenericMatrix ReverseSorted() const
Definition: Matrix.h:2136
static GenericMatrix Translation(const V &delta)
Definition: Matrix.h:1559
static GenericMatrix RotationY(double sphi, double cphi)
Definition: Matrix.h:1702
void Transfer(GenericMatrix &&x)
Definition: Matrix.h:501
void EnsureUnique()
Definition: Matrix.h:958
element & Element(int i, int j)
Definition: Matrix.h:1126
GenericMatrix Flipped() const
Definition: Matrix.h:1514
GenericMatrix Translated(double dx, double dy) const
Definition: Matrix.h:1618
void SetColumn(int j, const V &c)
Definition: Matrix.h:1391
double StableAvgDev() const
Definition: Matrix.h:2478
TwoSidedEstimate TwoSidedAvgDev(double center) const noexcept
Definition: Matrix.h:2489
GenericMatrix(const T1 *a, int rows, int cols)
Definition: Matrix.h:214
GenericMatrix(const GenericMatrix &x, int i0, int j0, int rows, int cols)
Definition: Matrix.h:313
double StableModulus() const noexcept
Definition: Matrix.h:2307
block_iterator RowPtr(int i) noexcept
Definition: Matrix.h:1303
const_block_iterator ConstEnd() const noexcept
Definition: Matrix.h:1265
block_iterator End()
Definition: Matrix.h:1241
double Sn() const
Definition: Matrix.h:2737
GenericMatrix RotatedY(double phi) const
Definition: Matrix.h:1921
block_iterator end()
Definition: Matrix.h:1328
void SetRow(int i, const V &r)
Definition: Matrix.h:1379
void ToImage(ImageVariant &image) const
Definition: Matrix.h:3004
GenericMatrix Rescaled(const element &f0=element(0), const element &f1=element(1)) const
Definition: Matrix.h:2097
const_block_iterator begin() const noexcept
Definition: Matrix.h:1320
element * block_iterator
Definition: Matrix.h:153
static GenericMatrix RotationY(double phi)
Definition: Matrix.h:1717
bool SameElements(const GenericMatrix &x) const noexcept
Definition: Matrix.h:1104
uint64 Hash(uint64 seed=0) const noexcept
Definition: Matrix.h:2803
const_block_iterator ConstBegin() const noexcept
Definition: Matrix.h:1202
void RotateY(double phi)
Definition: Matrix.h:1898
double Sum() const noexcept
Definition: Matrix.h:2275
void RotateY(double sphi, double cphi)
Definition: Matrix.h:1870
void RotateX(double sphi, double cphi)
Definition: Matrix.h:1789
void RotateZ(double phi)
Definition: Matrix.h:1979
block_iterator begin()
Definition: Matrix.h:1312
TwoSidedEstimate TwoSidedMAD(double center) const
Definition: Matrix.h:2541
TwoSidedEstimate TwoSidedBiweightMidvariance(double center, const TwoSidedEstimate &sigma, int k=9, bool reducedLength=false) const noexcept
Definition: Matrix.h:2645
GenericMatrix Inverse() const
Definition: Matrix.h:3331
element MinElement(Point &p) const noexcept
Definition: Matrix.h:2225
vector RowVector(int i) const
Definition: Matrix.h:1345
void ReverseSort()
Definition: Matrix.h:2126
block_iterator Begin()
Definition: Matrix.h:1179
double SumOfSquares() const noexcept
Definition: Matrix.h:2317
const_block_iterator Begin() const noexcept
Definition: Matrix.h:1194
double StdDev() const noexcept
Definition: Matrix.h:2394
const element & Element(int i, int j) const noexcept
Definition: Matrix.h:1136
GenericMatrix(const T1 &a00, const T1 &a01, const T1 &a10, const T1 &a11)
Definition: Matrix.h:240
double StableSumOfSquares() const noexcept
Definition: Matrix.h:2328
bool IsValid() const noexcept
Definition: Matrix.h:1018
static GenericMatrix FromColumnVector(const vector &c)
Definition: Matrix.h:1428
int Columns() const noexcept
Definition: Matrix.h:998
GenericMatrix RotatedX(double phi) const
Definition: Matrix.h:1840
GenericMatrix(const GenericImage< P > &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:364
GenericMatrix Sorted() const
Definition: Matrix.h:2116
GenericMatrix Translated(const V &delta) const
Definition: Matrix.h:1635
double StableMean() const noexcept
Definition: Matrix.h:2349
size_type NumberOfElements() const noexcept
Definition: Matrix.h:1046
void Sort(BP p)
Definition: Matrix.h:2149
GenericMatrix RotatedZ(double phi) const
Definition: Matrix.h:2002
double StableAvgDev(double center) const noexcept
Definition: Matrix.h:2443
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:261
void RotateX(double phi)
Definition: Matrix.h:1817
double AvgDev(double center) const noexcept
Definition: Matrix.h:2423
double BendMidvariance(double center, double beta=0.2) const
Definition: Matrix.h:2685
void ToImage(GenericImage< P > &image) const
Definition: Matrix.h:2978
static GenericMatrix RotationX(double phi)
Definition: Matrix.h:1675
TwoSidedEstimate TwoSidedAvgDev() const
Definition: Matrix.h:2499
GenericMatrix(const ImageVariant &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:384
GenericMatrix(const element &x, int rows, int cols)
Definition: Matrix.h:193
GenericMatrix RotatedY(double sphi, double cphi) const
Definition: Matrix.h:1910
static GenericMatrix Translation(double dx, double dy)
Definition: Matrix.h:1537
const_block_iterator end() const noexcept
Definition: Matrix.h:1336
static GenericMatrix RotationX(double sphi, double cphi)
Definition: Matrix.h:1660
void Assign(const GenericMatrix &x)
Definition: Matrix.h:451
block_iterator * DataPtr() noexcept
Definition: Matrix.h:1288
static GenericMatrix FromImage(const ImageVariant &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:3121
static GenericMatrix FromRowVector(const vector &r)
Definition: Matrix.h:1415
uint32 Hash32(uint32 seed=0) const noexcept
Definition: Matrix.h:2794
static GenericMatrix FromImage(const GenericImage< P > &image, const Rect &rect=Rect(0), int channel=-1)
Definition: Matrix.h:3072
GenericMatrix(GenericMatrix &&x)
Definition: Matrix.h:285
GenericMatrix(const GenericMatrix &x)
Definition: Matrix.h:276
friend void Swap(GenericMatrix &x1, GenericMatrix &x2) noexcept
Definition: Matrix.h:517
GenericMatrix(int rows, int cols)
Definition: Matrix.h:180
element MaxElement() const noexcept
Definition: Matrix.h:2243
double MAD() const
Definition: Matrix.h:2530
bool IsAliasOf(const GenericMatrix &x) const noexcept
Definition: Matrix.h:946
double BendMidvariance(double beta=0.2) const
Definition: Matrix.h:2709
int Rows() const noexcept
Definition: Matrix.h:978
static GenericMatrix FromColVector(const vector &c)
Definition: Matrix.h:1439
static GenericMatrix RotationZ(double sphi, double cphi)
Definition: Matrix.h:1744
double Mean() const noexcept
Definition: Matrix.h:2338
double Median() const
Definition: Matrix.h:2404
void Transfer(GenericMatrix &x)
Definition: Matrix.h:479
double BiweightMidvariance(int k=9, bool reducedLength=false) const
Definition: Matrix.h:2625
double TrimmedMeanOfSquares(distance_type l=1, distance_type h=1) const noexcept
Definition: Matrix.h:2373
const element * const_block_iterator
Definition: Matrix.h:160
TwoSidedEstimate TwoSidedMAD() const
Definition: Matrix.h:2551
double Qn() const
Definition: Matrix.h:2765
double BiweightMidvariance(double center, double sigma, int k=9, bool reducedLength=false) const noexcept
Definition: Matrix.h:2591
bool IsUnique() const noexcept
Definition: Matrix.h:937
const_block_iterator FindFirst(const element &x) const noexcept
Definition: Matrix.h:2183
GenericMatrix RotatedX(double sphi, double cphi) const
Definition: Matrix.h:1829
GenericMatrix RotatedZ(double sphi, double cphi) const
Definition: Matrix.h:1991
const_block_iterator Find(const element &x) const noexcept
Definition: Matrix.h:2172
GenericMatrix Abs() const
Definition: Matrix.h:892
TwoSidedEstimate TwoSidedBiweightMidvariance(int k=9, bool reducedLength=false) const
Definition: Matrix.h:2657
GenericMatrix Sqr() const
Definition: Matrix.h:798
void SetCol(int j, const V &c)
Definition: Matrix.h:1405
virtual ~GenericMatrix()
Definition: Matrix.h:396
GenericMatrix Truncated(const element &f0=element(0), const element &f1=element(1)) const
Definition: Matrix.h:2037
bool SameDimensions(const GenericMatrix &x) const noexcept
Definition: Matrix.h:1090
double StableSum() const noexcept
Definition: Matrix.h:2286
void Translate(const V &delta)
Definition: Matrix.h:1607
double MAD(double center) const
Definition: Matrix.h:2515
A generic point in the two-dimensional space.
Definition: Point.h:100
A generic rectangle in the two-dimensional space.
Definition: Rectangle.h:316
component y1
Vertical coordinate of the lower right corner.
Definition: Rectangle.h:337
component y0
Vertical coordinate of the upper left corner.
Definition: Rectangle.h:335
component x0
Horizontal coordinate of the upper left corner.
Definition: Rectangle.h:334
component Width() const noexcept
Definition: Rectangle.h:637
component Height() const noexcept
Definition: Rectangle.h:646
Generic vector of arbitrary length.
Definition: Vector.h:107
int Length() const noexcept
Definition: Vector.h:1802
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:2285
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2296
Complex< T1 > operator-(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:518
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:562
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:478
Complex< T1 > operator/(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:606
Complex< T1 > Pow(const Complex< T1 > &c, T2 x) noexcept
Definition: Complex.h:761
Complex< T > Sqrt(const Complex< T > &c) noexcept
Definition: Complex.h:688
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:443
uint64 Hash64(const void *data, size_type size, uint64 seed=0) noexcept
Definition: Math.h:4830
uint32 Hash32(const void *data, size_type size, uint32 seed=0) noexcept
Definition: Math.h:4984
GenericImage< P > operator^(const GenericImage< P > &image, T scalar)
Definition: Image.h:17768
void PCL_FUNC InPlaceGaussJordan(Matrix &A, Matrix &B)
void SinCos(T x, T &sx, T &cx) noexcept
Definition: Math.h:1101
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:997
static GenericMatrix PhaseCorrelationMatrix(const GenericMatrix &A, const GenericMatrix &B)
Definition: Matrix.h:2933
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:1029
static GenericMatrix CrossPowerSpectrumMatrix(const GenericMatrix &A, const GenericMatrix &B)
Definition: Matrix.h:2946
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:4250
double BendMidvariance(const T *__restrict__ x, const T *__restrict__ xn, double center, double beta=0.2)
Definition: Math.h:4560
double StableModulus(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2667
double MAD(const T *__restrict__ i, const T *__restrict__ j, double center, double eps=0)
Definition: Math.h:3844
double SumOfSquares(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2692
double StableMean(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2759
double TrimmedMean(const T *__restrict__ i, const T *__restrict__ j, distance_type l=1, distance_type h=1)
Definition: Math.h:3306
TwoSidedEstimate TwoSidedMAD(const T *__restrict__ i, const T *__restrict__ j, double center, double eps=0)
Definition: Math.h:3913
double StableSum(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2623
double Variance(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:2784
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:4484
double Sum(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2604
double StableSumOfSquares(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2714
double BiweightMidvariance(const T *__restrict__ x, const T *__restrict__ xn, double center, double sigma, int k=9, bool reducedLength=false) noexcept
Definition: Math.h:4421
double StdDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:2844
double TrimmedMeanOfSquares(const T *__restrict__ i, const T *__restrict__ j, distance_type l=1, distance_type h=1)
Definition: Math.h:3383
double AvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3468
double Median(const T *__restrict__ i, const T *__restrict__ j, double eps=0)
Definition: Math.h:2917
double Mean(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2740
double StableAvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3500
TwoSidedEstimate TwoSidedAvgDev(const T *__restrict__ i, const T *__restrict__ j, double center) noexcept
Definition: Math.h:3781
double Modulus(const T *__restrict__ i, const T *__restrict__ j) noexcept
Definition: Math.h:2648
double Sn(T *__restrict__ x, T *__restrict__ xn)
Definition: Math.h:4004
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:3592