/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */ /* $Id: vctDynamicConstNArrayBase.h,v 1.5 2007/04/26 19:33:57 anton Exp $ Author(s): Daniel Li Created on: 2006-06-23 (C) Copyright 2006-2007 Johns Hopkins University (JHU), All Rights Reserved. --- begin cisst license - do not edit --- This software is provided "as is" under an open source license, with no warranty. The complete license can be found in license.txt and http://www.cisst.org/cisst/license.txt. --- end cisst license --- */ #ifndef _vctDynamicConstNArrayBase_h #define _vctDynamicConstNArrayBase_h /*! \file \brief Declaration of vctDynamicConstNArrayBase */ #include #include #include #include #include #include #include template inline vctReturnDynamicNArray vctDynamicNArrayElementwiseCompareNArray(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray1, const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray2); template inline vctReturnDynamicNArray vctDynamicNArrayElementwiseCompareScalar(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray, const _elementType & scalar); /* Functions used to generate slices based on dimension, i.e. if dimension is 1 return an element, otherwise return an NArray of lesser dimension. The class below is used to specify which function is used. */ template inline vctDynamicNArrayRef<_elementType, _dimension - 1> vctDynamicNArrayNArraySlice(vctDynamicNArrayBase<_nArrayOwnerType, _elementType, _dimension> & input, unsigned int dimension, unsigned int index); template inline _elementType & vctDynamicNArrayElementSlice(vctDynamicNArrayBase<_nArrayOwnerType, _elementType, 1> & input, unsigned int index); template inline vctDynamicConstNArrayRef<_elementType, _dimension - 1> vctDynamicNArrayConstNArraySlice(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & input, unsigned int dimension, unsigned int index); template inline const _elementType & vctDynamicNArrayConstElementSlice(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, 1> & input, unsigned int index); /* Class used to specify the type of a slice based on the dimension. The class also provides a static method to select the right function to call. Code couldn't be inline since it requires a full definition of vctDynamicNArrayRef and vctDynamicConstNArrayRef. This can't be solved just with forward declarations. */ template class vctDynamicNArrayTypes { public: template class SlicesTypes { public: typedef vctDynamicConstNArrayRef<_elementType, _dimension - 1> ConstSliceRefType; typedef vctDynamicNArrayRef<_elementType, _dimension - 1> SliceRefType; template static ConstSliceRefType ConstSliceOf(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & input, unsigned int dimension, unsigned int index) { return vctDynamicNArrayConstNArraySlice(input, dimension, index); } template static SliceRefType SliceOf(vctDynamicNArrayBase<_nArrayOwnerType, _elementType, _dimension> & input, unsigned int dimension, unsigned int index) { return vctDynamicNArrayNArraySlice(input, dimension, index); } }; }; /* Specialisation of class for dimension 1. In this case, a slice is a single element. */ template <> class vctDynamicNArrayTypes<1> { public: template class SlicesTypes { public: typedef const _elementType & ConstSliceRefType; typedef _elementType & SliceRefType; template static ConstSliceRefType ConstSliceOf(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, 1> & input, unsigned int dimension, unsigned int index) { return vctDynamicNArrayConstElementSlice(input, index); } template static SliceRefType SliceOf(vctDynamicNArrayBase<_nArrayOwnerType, _elementType, 1> & input, unsigned int dimension, unsigned int index) { return vctDynamicNArrayElementSlice(input, index); } }; }; /*! This class is templated with the ``nArray owner type'', which may be a vctDynamicNArrayOwner or a vctDynamicNArrayRefOwner. It provides const operations on the nArray, such as SumOfElements etc. nArray indexing is zero-based. nArray dimensions are zero-based. The method provided for the compatibility with the STL containers start with a lower case. Other methods start with a capitalilized letter (see CISST naming convention). \param _nArrayOwnerType the type of nArray owner \param _elementType the type of elements of the nArray */ template class vctDynamicConstNArrayBase { public: /* define most types from vctContainerTraits and vctNArrayTraits */ VCT_CONTAINER_TRAITS_TYPEDEFS(_elementType); VCT_NARRAY_TRAITS_TYPEDEFS(_dimension); /*! Type of the nArray itself. */ typedef vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> ThisType; /*! Type of the data owner (dynamic array or pointer) */ typedef _nArrayOwnerType NArrayOwnerType; enum {DIMENSION = NArrayOwnerType::DIMENSION}; /*! Type of the subarray (const and non const) */ typedef vctDynamicConstNArrayRef ConstSubarrayType; typedef vctDynamicNArrayRef SubarrayType; /*! \name Iterators on the elements of the nArray */ //@{ typedef typename NArrayOwnerType::iterator iterator; typedef typename NArrayOwnerType::const_iterator const_iterator; typedef typename NArrayOwnerType::reverse_iterator reverse_iterator; typedef typename NArrayOwnerType::const_reverse_iterator const_reverse_iterator; //@} /*! \name The type of the object representing a subarray of this nArray. Access is by (const and non const) reference. */ //@{ typedef vctDynamicConstNArrayRef ConstSubarrayRefType; typedef vctDynamicNArrayRef SubarrayRefType; //@} /*! \name The type of the object representing a permutation of this nArray. Access is by (const and non const) reference. */ //@{ typedef vctDynamicConstNArrayRef ConstPermutationRefType; typedef vctDynamicNArrayRef PermutationRefType; //@} /*! \name The type of the object representing a slice of this nArray. Access is by (const and non const) reference. */ //@{ typedef typename vctDynamicNArrayTypes::template SlicesTypes<_elementType> SlicesTypes; typedef typename SlicesTypes::ConstSliceRefType ConstSliceRefType; typedef typename SlicesTypes::SliceRefType SliceRefType; //@} /*! The type of an nArray returned by value from operations on this object */ typedef vctReturnDynamicNArray NArrayValueType; typedef cmnTypeTraits TypeTraits; /*! Define bool based on the container type to force some compilers (i.e. gcc 4.0) to delay the instantiation of the ElementWiseCompare methods. */ typedef typename TypeTraits::BoolType BoolType; /*! The type of an nArray of booleans returned from operations on this object, e.g., ElementwiseEqual. */ typedef vctReturnDynamicNArray BoolNArrayValueType; //@} protected: /*! Declaration of the nArray-defining member object */ NArrayOwnerType NArray; /*! Check the validity of the given dimension index */ inline void ThrowUnlessValidDimensionIndex(dimension_type dimensionIndex) const throw(std::out_of_range) { if (! ValidDimensionIndex(dimensionIndex)) { cmnThrow(std::out_of_range("vctDynamicNArray: Invalid dimension index of " + dimensionIndex)); } } /*! Check the validity of an index */ inline void ThrowUnlessValidIndex(size_type index) const throw(std::out_of_range) { if (! ValidIndex(index)) { cmnThrow(std::out_of_range("vctDynamicNArray: Invalid index")); } } /*! Check the validity of the nArray indices */ inline void ThrowUnlessValidIndex(const nsize_type & indices) const throw(std::out_of_range) { if (! ValidIndex(indices)) { cmnThrow(std::out_of_range("vctDynamicNArray: Invalid indices")); } } /*! Check the validity of the given index in the (dimension)th-dimension */ inline void ThrowUnlessValidIndex(dimension_type dimension, size_type index) const throw(std::out_of_range) { if (! ValidIndex(dimension, index)) { cmnThrow(std::out_of_range("vctDynamicNArray: Invalid index in dimension " + dimension)); } } public: /*! Returns a const iterator on the first element (STL compatibility). */ const_iterator begin(void) const { return NArray.begin(); } /*! Returns a const iterator on the last element (STL compatibility). */ const_iterator end(void) const { return NArray.end(); } /*! Returns a reverse const iterator on the last element (STL compatibility). */ const_reverse_iterator rbegin(void) const { return NArray.rbegin(); } /*! Returns a reverse const iterator on the element before first (STL compatibility). */ const_reverse_iterator rend(void) const { return NArray.rend(); } /*! Return the number of elements in the nArray. This is not equivalent to the difference between the end and the beginning. */ size_type size(void) const { return NArray.size(); } /*! Not required by STL but provided for completeness */ const nsize_type & sizes(void) const { return NArray.sizes(); } /*! Not required by STL but provided for completeness */ size_type size(dimension_type dimension) const { return NArray.size(dimension); } /*! Not required by STL but provided for completeness */ const nstride_type & strides(void) const { return NArray.strides(); } /*! Not required by STL but provided for completeness */ difference_type stride(dimension_type dimension) const { return NArray.stride(dimension); } /*! Not required by STL but provided for completeness */ dimension_type dimension(void) const { return NArray.dimension(); } /*! Tell if the matrix is empty (STL compatibility). False unless size is zero. */ bool empty(void) const { return (size() == 0); } /*! Returns true if the given dimension value is equal to this nArray's dimension. */ inline bool ValidDimension(dimension_type dimension) const { return (dimension == this->dimension()); } /*! Returns true if the given dimension index is valid. */ inline bool ValidDimensionIndex(dimension_type dimensionIndex) const { return (dimensionIndex < this->dimension()); } /*! Returns true if the index is less than the number of elements of the nArray. */ inline bool ValidIndex(size_type index) const { return (index < size()); } /*! Returns true if all indices are valid indices. */ inline bool ValidIndex(const nsize_type & indices) const { nsize_type sizes = this->NArray.sizes(); typename nsize_type::const_iterator sizesIter; typename nsize_type::const_iterator indicesIter; if (indices.size() != sizes.size()) return false; for (sizesIter = sizes.begin(), indicesIter = indices.begin(); sizesIter != sizes.end(); sizesIter++, indicesIter++) { if (*indicesIter >= *sizesIter) return false; } return true; } /*! Returns true if the given index is a valid index. */ inline bool ValidIndex(dimension_type dimension, size_type index) const { return ( index < this->size(dimension) ); } /*! Access an element by index (const). Compare with std::matrix::at(). This method can be a handy substitute for the overloaded operator [] when operator overloading is unavailable or inconvenient. \return a const reference to element[index] */ const_reference at(size_type metaIndex) const throw(std::out_of_range) { ThrowUnlessValidIndex(metaIndex); return (begin())[metaIndex]; } /*! Access an element by indices (const). Compare with std::vector::at(). This method can be a handy substitute for the overloaded operator () when operator overloading is unavailable or inconvenient. \return a const reference to the element at indices */ const_reference at(const nsize_type & coordinates) const throw(std::out_of_range) { ThrowUnlessValidIndex(coordinates); return *(Pointer(coordinates)); } /*! Overloaded operator () for simplified (const) element access with bounds checking */ const_reference operator () (const nsize_type & coordinates) const throw(std::out_of_range) { return this->at(coordinates); } /*! Returns a const pointer to the first element of the container. Addition to the STL requirements. */ const_pointer Pointer(void) const { return NArray.Pointer(); } /*! Returns a const pointer to an element of the container, specified by its indices. Addition to the STL requirements. */ const_pointer Pointer(const nsize_type & indices) const { return NArray.Pointer(indices); } /*! Access an element by indices (const). This method allows to access an element without any bounds checking. It doesn't create any temporary references as nArray[][]...[] would do. \return a reference to the element at the specified indices */ const_reference Element(const nsize_type & coordinates) const { return *(Pointer(coordinates)); } /*! Create a const reference to a subarray of this nArray. \param startPosition vector of indices of the element position where the reference will start \param lengths the number of elements to reference in each dimension \note Preserves the number of dimensions. */ ConstSubarrayRefType Subarray(const nsize_type & startPosition, const nsize_type & lengths) const { ConstSubarrayRefType subarray; subarray.SubarrayOf(*this, startPosition, lengths); return subarray; } /*! Create a const reference to this nArray with the strides permuted. \param dimensions a sequence of dimension numbers representing the permuted order of strides \note Preserves the number of dimensions. */ ConstPermutationRefType Permute(const ndimension_type & dimensions) const { ConstPermutationRefType permutation; permutation.PermutationOf(*this, dimensions); return permutation; } /*! Create a const reference to a slice of dimension n-1, where n is the dimension of this nArray. \param dimension the dimension number of the direction by which to reduce \param slice the index number in the dimension specified by which to set the reference \note The number of dimensions is reduced by one. */ ConstSliceRefType Slice(dimension_type dimension, size_type index) const throw(std::runtime_error, std::out_of_range) { return SlicesTypes::ConstSliceOf(*this, dimension, index); } /*! Reference an (n-1)-dimension slice of this nArray by index (const). \return a const reference to the given index in the most significant dimension */ ConstSliceRefType operator [] (size_type index) const { return this->Slice(0, index); } /*! \name Incremental operations returning a scalar. Compute a scalar from all the elements of the nArray. */ //@{ /*! Return the sum of the elements of the nArray. \return The sum of all the elements */ inline value_type SumOfElements(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Addition, typename vctUnaryOperations::Identity>:: Run(*this); } /*! Return the product of the elements of the nArray. \return The product of all the elements */ inline value_type ProductOfElements(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Multiplication, typename vctUnaryOperations::Identity>:: Run(*this); } /*! Return the square of the norm of the nArray. \return The square of the norm */ inline value_type NormSquare(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Addition, typename vctUnaryOperations::Square>:: Run(*this); } /*! Return the norm of the nArray. \return The norm. */ inline NormType Norm(void) const { return sqrt(NormType(NormSquare())); } /*! Return the L1 norm of the nArray, i.e. the sum of the absolute values of all the elements. \return The L1 norm. */ inline value_type L1Norm(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Addition, typename vctUnaryOperations::AbsValue>:: Run(*this); } /*! Return the Linf norm of the nArray, i.e. the maximum of the absolute values of all the elements. \return The Linf norm. */ inline value_type LinfNorm(void) const { return this->MaxAbsElement(); } /*! Return the maximum element of the nArray. \return The maximum element */ inline value_type MaxElement(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Maximum, typename vctUnaryOperations::Identity>:: Run(*this); } /*! Return the minimum element of the nArray. \return The minimum element */ inline value_type MinElement(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Minimum, typename vctUnaryOperations::Identity>:: Run(*this); } /*! Return the maximum of the absolute values of all the elements. \sa LinfNorm. \return The maximum of the absolute values. */ inline value_type MaxAbsElement(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Maximum, typename vctUnaryOperations::AbsValue>:: Run(*this); } /*! Return the minimum of the absolute values of all the elements. \return The minimum of the absolute values. */ inline value_type MinAbsElement(void) const { return vctDynamicNArrayLoopEngines::template SoNi::Minimum, typename vctUnaryOperations::AbsValue>:: Run(*this); } /*! Compute the minimum AND maximum elements of the nArray. This method is more runtime-efficient than computing them separately. \param minElement reference to store the minimum element result. \param maxElement reference to store the maximum element result. \note If this nArray is empty (null pointer) the result is undefined. */ inline void MinAndMaxElement(value_type & minElement, value_type & maxElement) const { vctDynamicNArrayLoopEngines::MinAndMax::Run((*this), minElement, maxElement); } /*! Return true if all the elements of this nArray are strictly positive, false otherwise */ inline bool IsPositive(void) const { return vctDynamicNArrayLoopEngines::template SoNi::And, typename vctUnaryOperations::IsPositive>:: Run(*this); } /*! Return true if all the elements of this nArray are non-negative, false otherwise */ inline bool IsNonNegative(void) const { return vctDynamicNArrayLoopEngines::template SoNi::And, typename vctUnaryOperations::IsNonNegative>:: Run(*this); } /*! Return true if all the elements of this nArray are non-positive, false otherwise */ inline bool IsNonPositive(void) const { return vctDynamicNArrayLoopEngines::template SoNi::And, typename vctUnaryOperations::IsNonPositive>:: Run(*this); } /*! Return true if all the elements of this nArray are strictly negative, false otherwise */ inline bool IsNegative (void) const { return vctDynamicNArrayLoopEngines::template SoNi< typename vctBinaryOperations::And, typename vctUnaryOperations::IsNegative>:: Run(*this); } /*! Return true if all the elements of this nArray are nonzero, false otherwise */ inline bool All(void) const { return vctDynamicNArrayLoopEngines::template SoNi< typename vctBinaryOperations::And, typename vctUnaryOperations::IsNonzero>:: Run(*this); } /*! Return true if any element of this nArray is nonzero, false otherwise */ inline bool Any(void) const { return vctDynamicNArrayLoopEngines::template SoNi< typename vctBinaryOperations::Or, typename vctUnaryOperations::IsNonzero>:: Run(*this); } //@} /*! \name Storage format. */ //@{ /*! Test if the nArray is compact, i.e. the nArray actually uses a contiguous block of memory. \note an empty nArray is considered to be ... compact? ... non compact? */ inline bool IsCompact(void) const { typename nsize_type::const_reverse_iterator sizesIter = this->NArray.sizes().rbegin(); typename nstride_type::const_reverse_iterator stridesIter = this->NArray.strides().rbegin(); const typename nstride_type::const_reverse_iterator stridesEnd = this->NArray.strides().rend(); size_type sizesIter_value; stride_type previous_stride; if (stridesIter != stridesEnd) { if (*stridesIter != 1) { return false; } else { previous_stride = 1; ++stridesIter; } } for (; stridesIter != stridesEnd; ++stridesIter, ++sizesIter) { sizesIter_value = (*sizesIter == 0) ? 1 : *sizesIter; if (*stridesIter != sizesIter_value * previous_stride) return false; else previous_stride = *stridesIter; } return true; } //@} /*! \name Elementwise comparisons between nArray. Returns the result of the comparison. */ //@{ /*! Comparison between two nArray of the same size, containing the same type of elements. The strides can be different. The comparaison (\f$ = \neq < \leq > \geq \f$) for Equal(), NotEqual(), Lesser(), LesserOrEqual(), Greater() or GreaterOrEqual() is performed elementwise between the two nArrays. A logical "and" is performed (except for NotEqual which uses a logical "or") to accumulate the elementwise results. The only operators provided are "==" and "!=" since the semantic is not ambiguous. \return A boolean. */ template inline bool Equal(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::And, typename vctBinaryOperations::Equal>:: Run(*this, otherNArray); } /* documented above */ template inline bool operator == (const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return Equal(otherNArray); } /* documented above */ template inline bool AlmostEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray, value_type tolerance) const { return ((*this - otherNArray).LinfNorm() <= tolerance); } /* documented above */ template inline bool AlmostEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return ((*this - otherNArray).LinfNorm() <= TypeTraits::Tolerance()); } /* documented above */ template inline bool NotEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::Or, typename vctBinaryOperations::NotEqual>:: Run(*this, otherNArray); } /* documented above */ template inline bool operator != (const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return NotEqual(otherNArray); } /* documented above */ template inline bool Lesser(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::And, typename vctBinaryOperations::Lesser>:: Run(*this, otherNArray); } /* documented above */ template inline bool LesserOrEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::And, typename vctBinaryOperations::LesserOrEqual>:: Run(*this, otherNArray); } /* documented above */ template inline bool Greater(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::And, typename vctBinaryOperations::Greater>:: Run(*this, otherNArray); } /* documented above */ template inline bool GreaterOrEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayLoopEngines::template SoNiNi::And, typename vctBinaryOperations::GreaterOrEqual>:: Run(*this, otherNArray); } //@} /*! \name Elementwise comparisons between nArrays. Returns the nArray of comparison's results. */ //@{ /*! Comparison between two nArrays of the same size, containing the same type of elements. The strides and the internal representation (_nArrayOwnerType) can be different. The comparison (\f$ = \neq < \leq > \geq \f$) for ElementwiseEqual(), ElementwiseNotEqual(), ElementwiseLesser(), ElementwiseLesserOrEqual(), ElementwiseGreater() or ElementwiseGreaterOrEqual() is performed elementwise between the two nArrays and stored in a newly created nArray. There is no operator provided since the semantic would be ambiguous. \return An nArray of booleans. */ template inline BoolNArrayValueType ElementwiseEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::Equal>(*this, otherNArray); } /* documented above */ template inline BoolNArrayValueType ElementwiseNotEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::NotEqual>(*this, otherNArray); } /* documented above */ template inline BoolNArrayValueType ElementwiseLesser(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::Lesser>(*this, otherNArray); } /* documented above */ template inline BoolNArrayValueType ElementwiseLesserOrEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::LesserOrEqual>(*this, otherNArray); } /* documented above */ template inline BoolNArrayValueType ElementwiseGreater(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::Greater>(*this, otherNArray); } /* documented above */ template inline BoolNArrayValueType ElementwiseGreaterOrEqual(const vctDynamicConstNArrayBase<__nArrayOwnerType, value_type, DIMENSION> & otherNArray) const { return vctDynamicNArrayElementwiseCompareNArray<_nArrayOwnerType, __nArrayOwnerType, value_type, typename vctBinaryOperations::GreaterOrEqual>(*this, otherNArray); } //@} /*! \name Elementwise comparisons between an nArray and a scalar. Returns the result of the comparison. */ //@{ /*! Comparison between an nArray and a scalar. The type of the elements of the nArray and the scalar must be the same. The comparison (\f$ = \neq < \leq > \geq \f$) for Equal(), NotEqual(), Lesser(), LesserOrEqual(), Greater() or GreaterOrEqual() is performed elementwise between the nArray and the scalar. A logical "and" is performed (except for NotEqual which uses a logical "or") to accumulate the elementwise results. The only operators provided are "==" and "!=" since the semantic is not ambiguous. \return A boolean. */ inline bool Equal(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::And, typename vctBinaryOperations::Equal>:: Run(*this, scalar); } /* documented above */ inline bool operator == (const value_type & scalar) const { return Equal(scalar); } /* documented above */ inline bool NotEqual(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::Or, typename vctBinaryOperations::NotEqual>:: Run(*this, scalar); } /* documented above */ inline bool operator != (const value_type & scalar) const { return NotEqual(scalar); } /* documented above */ inline bool Lesser(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::And, typename vctBinaryOperations::Lesser>:: Run(*this, scalar); } /* documented above */ inline bool LesserOrEqual(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::And, typename vctBinaryOperations::LesserOrEqual>:: Run(*this, scalar); } /* documented above */ inline bool Greater(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::And, typename vctBinaryOperations::Greater>:: Run(*this, scalar); } /* documented above */ inline bool GreaterOrEqual(const value_type & scalar) const { return vctDynamicNArrayLoopEngines::template SoNiSi::And, typename vctBinaryOperations::GreaterOrEqual>:: Run(*this, scalar); } //@} /*! \name Elementwise comparisons between an nArray and a scalar. Returns the result of the comparison. */ //@{ /*! Comparison between an nArray and a scalar, containing the same type of elements. The comparison (\f$ = \neq < \leq > \geq \f$) for ElementwiseEqual(), ElementwiseNotEqual(), ElementwiseLesser(), ElementwiseLesserOrEqual(), ElementwiseGreater() or ElementwiseGreaterOrEqual() is performed elementwise between the nArray and the scalar and stored in a newly created nArray. There is no operator provided since the semantic would be ambiguous. \return An nArray of booleans. */ BoolNArrayValueType ElementwiseEqual(const value_type & scalar) const; /* documented above */ BoolNArrayValueType ElementwiseNotEqual(const value_type & scalar) const; /* documented above */ BoolNArrayValueType ElementwiseLesser(const value_type & scalar) const; /* documented above */ BoolNArrayValueType ElementwiseLesserOrEqual(const value_type & scalar) const; /* documented above */ BoolNArrayValueType ElementwiseGreater(const value_type & scalar) const; /* documented above */ BoolNArrayValueType ElementwiseGreaterOrEqual(const value_type & scalar) const; //@} /*! \name Unary elementwise operations. Returns the result of nArray.op(). */ //@{ /*! Unary elementwise operations on an nArray. For each element of the nArray "this", performs \f$ this[i] \leftarrow op(otherNArray[i])\f$ where \f$op\f$ can calculate the absolute value (Abs) or the opposite (Negation). \return A new nArray. */ inline NArrayValueType Abs(void) const; /* documented above */ inline NArrayValueType Negation(void) const; /* documented above */ inline NArrayValueType Floor(void) const; /* documented above */ inline NArrayValueType Ceil(void) const; //@} /*! Return a string representation of the nArray elements */ std::string ToString(void) { std::stringstream outputStream; ToStream(outputStream); return outputStream.str(); } //. didn't touch /*! Print the matrix to a text stream */ void ToStream(std::ostream & outputStream) const { #if DANIEL const size_type myRows = rows(); const size_type myCols = cols(); // preserve the formatting flags as they were const int width = outputStream.width(12); const int precision = outputStream.precision(6); bool showpoint = ((outputStream.flags() & std::ios_base::showpoint) != 0); outputStream << std::setprecision(6) << std::showpoint; size_type indexRow, indexCol; for (indexRow = 0; indexRow < myRows; ++indexRow) { for (indexCol = 0; indexCol < myCols; ++indexCol) { outputStream << std::setw(12) << this->Element(indexRow, indexCol); if (indexCol < (myCols-1)) { outputStream << " "; } } // end of line between rows, not at the end if (indexRow != (myRows - 1)) { outputStream << std::endl; } } // resume the formatting flags outputStream << std::setprecision(precision) << std::setw(width); if (!showpoint) { outputStream << std::noshowpoint; } #endif } }; #ifndef DOXYGEN /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseEqual(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::Equal>(*this, scalar); } /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseNotEqual(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::NotEqual>(*this, scalar); } /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseLesser(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::Lesser>(*this, scalar); } /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseLesserOrEqual(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::LesserOrEqual>(*this, scalar); } /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseGreater(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::Greater>(*this, scalar); } /* documented in class. Implementation moved here for .Net 2003 */ template inline typename vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::BoolNArrayValueType vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension>::ElementwiseGreaterOrEqual(const _elementType & scalar) const { return vctDynamicNArrayElementwiseCompareScalar<_nArrayOwnerType, _elementType, typename vctBinaryOperations::GreaterOrEqual>(*this, scalar); } #endif // DOXYGEN /*! Return true if all the elements of the NArray are nonzero, false otherwise */ template inline bool vctAll(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray) { return nArray.All(); } /*! Return true if any element of the NArray is nonzero, false otherwise */ template inline bool vctAny(const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray) { return nArray.Any(); } /*! Stream out operator. */ template std::ostream & operator << (std::ostream & output, const vctDynamicConstNArrayBase<_nArrayOwnerType, _elementType, _dimension> & nArray) { nArray.ToStream(output); return output; } #endif // _vctDynamicConstNArrayBase_h // **************************************************************************** // Change History // **************************************************************************** // // $Log: vctDynamicConstNArrayBase.h,v $ // Revision 1.5 2007/04/26 19:33:57 anton // All files in libraries: Applied new license text, separate copyright and // updated dates, added standard header where missing. // // Revision 1.4 2007/03/08 04:29:25 anton // cisstVector NArray: Now templated by dimension (see #258). Added template // specialization for slices of dimension 1 NArray to return value_type. Used // Ofri's implementation of IncrementPointer() in loop engines (previous one did // not handle more than dimension 3). Also renamed DimSize, DimStride and // Dimension to size(d), stride(d), and dimensioni (for STL flavor). // // Revision 1.3 2007/01/23 21:09:24 anton // cisstVector NArray: Removed code and comments related to transpose and eye // since these have no real utility for NArrays (see ticket #255) // // Revision 1.2 2007/01/20 04:11:10 anton // cisstVector NArray: Removed code for diagonal since meaningless for NArray. // See ticket #255. // // Revision 1.1 2006/12/09 04:13:25 anton // cisstVector: Imported code for NArray from Daniel Li with minor cleanup // for license, dos2unix, a few renamed methods and port to gcc. // // // ****************************************************************************