1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkNumericTraitsVariableLengthVectorPixel_h 19 #define itkNumericTraitsVariableLengthVectorPixel_h 20 21 #include "itkVariableLengthVector.h" 22 23 // This work is part of the National Alliance for Medical Image Computing 24 // (NAMIC), funded by the National Institutes of Health through the NIH Roadmap 25 // for Medical Research, Grant U54 EB005149. 26 27 namespace itk 28 { 29 /** 30 * \brief Define numeric traits for VariableLengthVector. 31 * \tparam T Component type of VariableLenghtVector 32 * 33 * We provide here a generic implementation based on creating types of 34 * VariableLengthVector whose components are the types of the NumericTraits from 35 * the original VariableLengthVector components. This implementation require 36 * support for partial specializations, since it is based on the 37 * concept that: 38 * NumericTraits<VariableLengthVector< T > > is defined piecewise by 39 * VariableLengthVector< NumericTraits< T > > 40 * 41 * \note The Zero(), One(), min() and max() methods here take 42 * references to a pixel as input. This is due to the fact that the 43 * length of the VariableLengthVector is not known until 44 * run-time. Since the most common use of Zero and One is for 45 * comparison purposes or initialization of sums etc, this might just 46 * as easily be re-written with a pixel passed in as a reference and 47 * the length is inferred from this pixel. 48 * 49 * \sa NumericTraits 50 * \ingroup DataRepresentation 51 * \ingroup ITKCommon 52 */ 53 template< typename T > 54 class NumericTraits< VariableLengthVector< T > > 55 { 56 public: 57 58 using ElementAbsType = typename NumericTraits< T >::AbsType; 59 using ElementAccumulateType = typename NumericTraits< T >::AccumulateType; 60 using ElementFloatType = typename NumericTraits< T >::FloatType; 61 using ElementPrintType = typename NumericTraits< T >::PrintType; 62 using ElementRealType = typename NumericTraits< T >::RealType; 63 64 /** Return the type of the native component type. */ 65 using ValueType = T; 66 67 using Self = VariableLengthVector< T >; 68 69 /** Unsigned component type */ 70 using AbsType = VariableLengthVector< ElementAbsType >; 71 72 /** Accumulation of addition and multiplication. */ 73 using AccumulateType = VariableLengthVector< ElementAccumulateType >; 74 75 /** Typedef for operations that use floating point instead of real precision 76 */ 77 using FloatType = VariableLengthVector< ElementFloatType >; 78 79 /** Return the type that can be printed. */ 80 using PrintType = VariableLengthVector< ElementPrintType >; 81 82 /** Type for real-valued scalar operations. */ 83 using RealType = VariableLengthVector< ElementRealType >; 84 85 /** Type for real-valued scalar operations. */ 86 using ScalarRealType = ElementRealType; 87 88 /** Measurement vector type */ 89 using MeasurementVectorType = Self; 90 91 /** Component wise defined element 92 * 93 * \note minimum value for floating pointer types is defined as 94 * minimum positive normalize value. 95 */ max(const Self & a)96 static const Self max(const Self & a) 97 { 98 Self b( a.Size() ); 99 100 b.Fill( NumericTraits< T >::max() ); 101 return b; 102 } 103 min(const Self & a)104 static const Self min(const Self & a) 105 { 106 Self b( a.Size() ); 107 108 b.Fill( NumericTraits< T >::min() ); 109 return b; 110 } 111 ZeroValue(const Self & a)112 static const Self ZeroValue(const Self & a) 113 { 114 Self b( a.Size() ); 115 116 b.Fill(NumericTraits< T >::ZeroValue()); 117 return b; 118 } 119 OneValue(const Self & a)120 static const Self OneValue(const Self & a) 121 { 122 Self b( a.Size() ); 123 124 b.Fill(NumericTraits< T >::OneValue()); 125 return b; 126 } 127 NonpositiveMin(const Self & a)128 static const Self NonpositiveMin(const Self & a) 129 { 130 Self b( a.Size() ); 131 b.Fill( NumericTraits< T >::NonpositiveMin() ); 132 return b; 133 } 134 IsPositive(const Self & a)135 static bool IsPositive( const Self & a) 136 { 137 bool flag = false; 138 for (unsigned int i=0; i < GetLength( a ); i++) 139 { 140 if ( a[i] > NumericTraits< ValueType >::ZeroValue() ) 141 { 142 flag = true; 143 } 144 } 145 return flag; 146 } 147 IsNonpositive(const Self & a)148 static bool IsNonpositive( const Self & a) 149 { 150 bool flag = false; 151 for (unsigned int i=0; i < GetLength( a ); i++) 152 { 153 if ( ! (a[i] > 0.0 ) ) 154 { 155 flag = true; 156 } 157 } 158 return flag; 159 } 160 IsNegative(const Self & a)161 static bool IsNegative( const Self & a) 162 { 163 bool flag = false; 164 for (unsigned int i=0; i < GetLength( a ); i++) 165 { 166 if ( a[i] < NumericTraits< ValueType >::ZeroValue() ) 167 { 168 flag = true; 169 } 170 } 171 return flag; 172 } 173 IsNonnegative(const Self & a)174 static bool IsNonnegative( const Self & a) 175 { 176 bool flag = false; 177 for (unsigned int i=0; i < GetLength( a ); i++) 178 { 179 if ( ! (a[i] < 0.0 )) 180 { 181 flag = true; 182 } 183 } 184 return flag; 185 } 186 187 static constexpr bool IsSigned = NumericTraits< ValueType >::IsSigned; 188 static constexpr bool IsInteger = NumericTraits< ValueType >::IsInteger; 189 static constexpr bool IsComplex = NumericTraits< ValueType >::IsComplex; 190 191 192 /** Resize the input vector to the specified size. */ SetLength(VariableLengthVector<T> & m,const unsigned int s)193 static void SetLength(VariableLengthVector< T > & m, const unsigned int s) 194 { 195 m.SetSize(s); 196 m.Fill(NumericTraits< T >::ZeroValue()); 197 } 198 199 /** Return the size of the vector. */ GetLength(const VariableLengthVector<T> & m)200 static unsigned int GetLength(const VariableLengthVector< T > & m) 201 { 202 return m.GetSize(); 203 } 204 AssignToArray(const Self & v,MeasurementVectorType & mv)205 static void AssignToArray( const Self & v, MeasurementVectorType & mv ) 206 { 207 mv = v; 208 } 209 210 template<typename TArray> AssignToArray(const Self & v,TArray & mv)211 static void AssignToArray( const Self & v, TArray & mv ) 212 { 213 for( unsigned int i=0; i<GetLength(v); i++ ) 214 { 215 mv[i] = v[i]; 216 } 217 } 218 219 }; 220 } // end namespace itk 221 222 #endif // itkNumericTraitsVariableLengthVector_h 223