/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkVector_hxx #define itkVector_hxx #include "itkMath.h" #include "vnl/vnl_vector.h" #include "itkObject.h" #include "itkNumericTraitsVectorPixel.h" namespace itk { template Vector::Vector(const ValueType & r) : Superclass{ r } {} template Vector & Vector::operator=(const ValueType r[TVectorDimension]) { BaseArray::operator=(r); return *this; } template auto Vector::operator+=(const Self & vec) -> const Self & { for (unsigned int i = 0; i < TVectorDimension; ++i) { (*this)[i] += vec[i]; } return *this; } template auto Vector::operator-=(const Self & vec) -> const Self & { for (unsigned int i = 0; i < TVectorDimension; ++i) { (*this)[i] -= vec[i]; } return *this; } template Vector Vector::operator-() const { Self result; for (unsigned int i = 0; i < TVectorDimension; ++i) { result[i] = -(*this)[i]; } return result; } template Vector Vector::operator+(const Self & vec) const { Self result; for (unsigned int i = 0; i < TVectorDimension; ++i) { result[i] = (*this)[i] + vec[i]; } return result; } template Vector Vector::operator-(const Self & vec) const { Self result; for (unsigned int i = 0; i < TVectorDimension; ++i) { result[i] = (*this)[i] - vec[i]; } return result; } template auto Vector::GetSquaredNorm() const -> RealValueType { typename NumericTraits::AccumulateType sum = T{}; for (unsigned int i = 0; i < TVectorDimension; ++i) { const RealValueType value = (*this)[i]; sum += value * value; } return sum; } template auto Vector::GetNorm() const -> RealValueType { return RealValueType(std::sqrt(static_cast(this->GetSquaredNorm()))); } template auto Vector::Normalize() -> RealValueType { const RealValueType norm = this->GetNorm(); if (norm < NumericTraits::epsilon()) { return norm; // Prevent division by 0 } const RealValueType inversedNorm = 1.0 / norm; for (unsigned int i = 0; i < TVectorDimension; ++i) { (*this)[i] = static_cast(static_cast((*this)[i] * inversedNorm)); } return norm; } template vnl_vector_ref Vector::GetVnlVector() { return vnl_vector_ref(TVectorDimension, this->GetDataPointer()); } template vnl_vector Vector::GetVnlVector() const { return vnl_vector(this->GetDataPointer(), TVectorDimension); } template void Vector::SetVnlVector(const vnl_vector & v) { for (unsigned int i = 0; i < v.size(); ++i) { (*this)[i] = v(i); } } template std::ostream & operator<<(std::ostream & os, const Vector & vct) { os << '['; if (TVectorDimension == 1) { os << vct[0]; } else { for (unsigned int i = 0; i + 1 < TVectorDimension; ++i) { os << vct[i] << ", "; } os << vct[TVectorDimension - 1]; } os << ']'; return os; } template std::istream & operator>>(std::istream & is, Vector & vct) { for (unsigned int i = 0; i < TVectorDimension; ++i) { is >> vct[i]; } return is; } template typename Vector::ValueType Vector::operator*(const Self & other) const { typename NumericTraits::AccumulateType value = T{}; for (unsigned int i = 0; i < TVectorDimension; ++i) { value += (*this)[i] * other[i]; } return value; } } // end namespace itk #endif