26 #include "ndarray/eigen.h"
47 if (factors.size() < 1u) {
49 pex::exceptions::LengthError,
50 "ProductBoundedField requires at least one BoundedField factor."
53 auto iter = factors.begin();
54 auto bbox = (**iter).getBBox();
56 for (;
iter != factors.end(); ++
iter) {
57 if ((**iter).getBBox() !=
bbox) {
59 pex::exceptions::InvalidParameterError,
60 (boost::format(
"Inconsistency in ProductBoundedField bboxes: %s != %s") %
61 bbox % (**iter).getBBox()).str()
71 BoundedField(checkAndExtractBBox(factors)), _factors(factors)
80 for (
auto const &
field : _factors) {
81 product *=
field->evaluate(position);
87 ndarray::Array<double const, 1>
const&
x,
88 ndarray::Array<double const, 1>
const&
y
90 if (
x.getShape() !=
y.getShape()) {
93 (boost::format(
"Inconsistent shapes: %s != %s") %
x.getShape() %
y.getShape()).str()
96 ndarray::Array<double, 1, 1>
z = ndarray::allocate(
x.getShape());
98 for (
auto const &
field : _factors) {
99 ndarray::asEigenArray(
z) *= ndarray::asEigenArray(
field->evaluate(
x,
y));
108 struct PersistenceHelper {
112 static PersistenceHelper
const & get() {
113 static PersistenceHelper
const instance;
119 PersistenceHelper() :
121 id(
schema.addField<int>(
"id",
"Archive ID of a BoundedField factor."))
124 PersistenceHelper(PersistenceHelper
const &) =
delete;
125 PersistenceHelper(PersistenceHelper &&) =
delete;
126 PersistenceHelper & operator=(PersistenceHelper
const &) =
delete;
127 PersistenceHelper & operator=(PersistenceHelper &&) =
delete;
129 ~PersistenceHelper() noexcept = default;
133 class ProductBoundedFieldFactory : public table::io::PersistableFactory {
136 : afw::table::io::PersistableFactory(
name) {}
139 CatalogVector
const& catalogs)
const override {
141 auto const &
keys = PersistenceHelper::get();
142 auto const & cat = catalogs.front();
145 for (
auto const & record : cat) {
146 factors.
push_back(archive.get<BoundedField>(record.get(
keys.id)));
148 return std::make_shared<ProductBoundedField>(factors);
152 std::string getProductBoundedFieldPersistenceName() {
return "ProductBoundedField"; }
154 ProductBoundedFieldFactory registration(getProductBoundedFieldPersistenceName());
159 return std::all_of(_factors.begin(), _factors.end(),
160 [](
auto const &
field) { return field->isPersistable(); });
164 return getProductBoundedFieldPersistenceName();
170 auto const &
keys = PersistenceHelper::get();
172 catalog.
reserve(_factors.size());
173 for (
auto const &
field : _factors) {
183 bool multiplied =
false;
184 for (
auto &
field : factors) {
192 ndarray::Array<double, 2, 2>
coefficients = ndarray::allocate(1, 1);
196 return std::make_shared<ProductBoundedField>(factors);
201 if (!rhsCasted)
return false;
203 return (
getBBox() == rhsCasted->getBBox()) &&
205 rhsCasted->_factors.begin(), rhsCasted->_factors.end(),
206 [](
auto const &
a,
auto const &
b) {
return *
a == *
b; });
209 std::string ProductBoundedField::toString()
const {
211 os <<
"ProductBoundedField([";
212 for (
auto const &
field : _factors) {
213 os << (*field) <<
", ";