GaussianSpreadKernelParameters::Shape makeSpreadKernel(real sigma, real nSigma, const ScaleCoordinates& scaleToLattice)
{
RVec sigmaInLatticeCoordinates{ sigma, sigma, sigma };
- scaleToLattice({ &sigmaInLatticeCoordinates, &sigmaInLatticeCoordinates + 1 });
+ scaleToLattice(&sigmaInLatticeCoordinates);
return { DVec{ sigmaInLatticeCoordinates[XX], sigmaInLatticeCoordinates[YY],
sigmaInLatticeCoordinates[ZZ] },
nSigma };
referenceDensityCenter_ = { real(referenceDensity.extent(XX)) / 2,
real(referenceDensity.extent(YY)) / 2,
real(referenceDensity.extent(ZZ)) / 2 };
- transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale(
- { &referenceDensityCenter_, &referenceDensityCenter_ + 1 });
+ transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale(&referenceDensityCenter_);
// correct the reference density center for a shift
// if the reference density does not have its origin at (0,0,0)
RVec referenceDensityOriginShift(0, 0, 0);
- transformationToDensityLattice_({ &referenceDensityOriginShift, &referenceDensityOriginShift + 1 });
- transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale(
- { &referenceDensityOriginShift, &referenceDensityOriginShift + 1 });
+ transformationToDensityLattice_(&referenceDensityOriginShift);
+ transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale(&referenceDensityOriginShift);
referenceDensityCenter_ -= referenceDensityOriginShift;
}
impl_->scale(coordinates);
}
+void ScaleCoordinates::operator()(RVec* coordinate) const
+{
+ impl_->scale({ coordinate, coordinate + 1 });
+}
+
void ScaleCoordinates::inverseIgnoringZeroScale(ArrayRef<RVec> coordinates) const
{
impl_->inverseIgnoringZeroScale(coordinates);
}
+void ScaleCoordinates::inverseIgnoringZeroScale(RVec* coordinate) const
+{
+ impl_->inverseIgnoringZeroScale({ coordinate, coordinate + 1 });
+}
+
ScaleCoordinates::~ScaleCoordinates() = default;
ScaleCoordinates::ScaleCoordinates(const ScaleCoordinates& other) : impl_(new Impl(*other.impl_)) {}
impl_->transform(coordinates);
}
+void TranslateAndScale::operator()(RVec* coordinate) const
+{
+ impl_->transform({ coordinate, coordinate + 1 });
+}
+
ScaleCoordinates TranslateAndScale::scaleOperationOnly() const
{
return ScaleCoordinates{ impl_->scale_ };
* \param[in] coordinates to be transformed
*/
void operator()(ArrayRef<RVec> coordinates) const;
+
+ /*! \brief Perform a coordinate transformation on an input coordinate.
+ * \param[in] coordinate to be transformed
+ */
+ void operator()(RVec* coordinate) const;
+
/*! \brief Apply the inverse scale to coordinates, ignoring dimensions for which scale is zero.
* \param[in] coordinates to be transformed
*/
void inverseIgnoringZeroScale(ArrayRef<RVec> coordinates) const;
+ /*! \brief Apply the inverse scale to a coordinate, ignoring dimensions for which scale is zero.
+ * \param[in] coordinate to be transformed
+ */
+ void inverseIgnoringZeroScale(RVec* coordinate) const;
+
private:
class Impl;
PrivateImplPointer<Impl> impl_;
*/
void operator()(ArrayRef<RVec> coordinates) const;
+ /*! \brief Perform a coordinate transformation on a coordinate.
+ * \param[in] coordinate to be transformed
+ */
+ void operator()(RVec* coordinate) const;
+
/*! \brief Returns the scaling operation, discarding the translation.
*/
ScaleCoordinates scaleOperationOnly() const;
EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_));
}
+TEST_F(TranslateAndScaleTest, translationAndScalingNonTrivialSingeVector)
+{
+ TranslateAndScale translateAndScale({ -1e10, 2, 0 }, { 1, -1, 2 });
+ RVec test(0, 0, 0);
+ translateAndScale(&test);
+
+ EXPECT_REAL_EQ(-1e+10, test[XX]);
+ EXPECT_REAL_EQ(-2, test[YY]);
+ EXPECT_REAL_EQ(0, test[ZZ]);
+}
+
TEST_F(TranslateAndScaleTest, scalingIdentity)
{
ScaleCoordinates scale(identityScale_);
EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_));
}
+TEST_F(TranslateAndScaleTest, scalingNonTrivialSingleVector)
+{
+ ScaleCoordinates scale({ -100, 0.1, 0 });
+ RVec test(3, -6, 2.5);
+ scale(&test);
+
+ EXPECT_REAL_EQ(-300, test[XX]);
+ EXPECT_REAL_EQ(-0.6, test[YY]);
+ EXPECT_REAL_EQ(0, test[ZZ]);
+}
+
+
TEST_F(TranslateAndScaleTest, scalingInverseNoZero)
{
ScaleCoordinates scale({ -100, 0.1, 3 });
EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_));
}
+TEST_F(TranslateAndScaleTest, scalingInverseWithOneScaleDimensionZeroSingleVector)
+{
+ ScaleCoordinates scale({ -100, 0.1, 0 });
+ RVec test(3, -6, 2.5);
+
+ scale(&test);
+ scale.inverseIgnoringZeroScale(&test);
+
+ EXPECT_REAL_EQ(3, test[XX]);
+ EXPECT_REAL_EQ(-6, test[YY]);
+ EXPECT_REAL_EQ(0, test[ZZ]);
+}
+
+
} // namespace test
} // namespace gmx