Enable copying and moving for DensitySimilarityMeasure.
Change-Id: Ie4250f67ae42b5cea227b7c17b0a932b04a42a63
virtual density gradient(density comparedDensity) = 0;
//! \copydoc DensitySimilarityMeasure::gradient(density comparedDensity)
virtual float similarity(density comparedDensity) = 0;
+ //! clone to allow copy operations
+ virtual std::unique_ptr<DensitySimilarityMeasureImpl> clone() = 0;
};
DensitySimilarityMeasureImpl::~DensitySimilarityMeasureImpl() = default;
DensitySimilarityInnerProduct(density referenceDensity);
//! The gradient for the inner product similarity measure is the reference density divided by the number of voxels
density gradient(density comparedDensity) override;
+ //! Clone this
+ std::unique_ptr<DensitySimilarityMeasureImpl> clone() override;
//! The similarity between reference density and compared density
float similarity(density comparedDensity) override;
+ private:
//! A view on the reference density
const density referenceDensity_;
//! Stores the gradient of the similarity measure in memory
return gradient_.asConstView();
}
+std::unique_ptr<DensitySimilarityMeasureImpl> DensitySimilarityInnerProduct::clone()
+{
+ return std::make_unique<DensitySimilarityInnerProduct>(referenceDensity_);
+}
+
} // namespace
DensitySimilarityMeasure::~DensitySimilarityMeasure() = default;
+DensitySimilarityMeasure::DensitySimilarityMeasure(const DensitySimilarityMeasure &other)
+ : impl_(other.impl_->clone())
+{
+}
+
+DensitySimilarityMeasure &DensitySimilarityMeasure::operator=(const DensitySimilarityMeasure &other)
+{
+ impl_ = other.impl_->clone();
+ return *this;
+}
+
+DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasure &&) noexcept = default;
+
+DensitySimilarityMeasure &DensitySimilarityMeasure::operator=(DensitySimilarityMeasure &&) noexcept = default;
+
} // namespace gmx
*/
DensitySimilarityMeasure(DensitySimilarityMeasureMethod method, density referenceDensity);
~DensitySimilarityMeasure();
+ //! Copy constructor
+ DensitySimilarityMeasure(const DensitySimilarityMeasure &other);
+ //! Copy assignment
+ DensitySimilarityMeasure &operator=(const DensitySimilarityMeasure &other);
+ //! Move constructor
+ DensitySimilarityMeasure(DensitySimilarityMeasure &&other) noexcept;
+ //! Move assignment
+ DensitySimilarityMeasure &operator=(DensitySimilarityMeasure &&other) noexcept;
+
/*! \brief Derivative of the density similarity measure at all voxels.
* \param[in] comparedDensity the variable density
* \returns density similarity measure derivative
EXPECT_THROW(measure.similarity(comparedDensity.asConstView()), RangeError);
}
+TEST(DensitySimilarityTest, CopiedMeasureInnerProductIsCorrect)
+{
+ MultiDimArray<std::vector<float>, dynamicExtents3D> referenceDensity(3, 3, 3);
+ std::iota(begin(referenceDensity), end(referenceDensity), 0);
+
+ DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView());
+
+ DensitySimilarityMeasure copiedMeasure = measure;
+ MultiDimArray<std::vector<float>, dynamicExtents3D> comparedDensity(3, 3, 3);
+ std::iota(begin(comparedDensity), end(comparedDensity), -18);
+
+ // 0*(-18) + 1*(-17) .. + 26 * 8 / Number elements
+ const float expectedSimilarity = -117.0 / comparedDensity.asConstView().mapping().required_span_size();
+ EXPECT_FLOAT_EQ(expectedSimilarity, copiedMeasure.similarity(comparedDensity.asConstView()));
+}
+
+
} // namespace test
} // namespace gmx