Hi all,
I am currently implementing a restraint in C++ with the goal of providing
similar functionality as the fuzzyRestraint in pmi/restraints/proteomics
with better efficiency.
I have come up with the following design (see code excerpts bellow):
A pure virtual base FuzzyRestraint class that implements the interface.
Several child classes that inherit from that and perform the fuzzy logic
calculation (ie OR, AND, NOT).
For example, given two restraints r1,r2, I could instantiate a FuzzyOr
r3=r1|r2;
My issue is the following: whenever I chain more that two operands (for
example r=r1|r2|r3|r4), I get a segfault in the do_get_inputs. I believe
this is due to the class containing pointers, but I didn't specify a copy
constructor, assignment operator, and destructor to handle these operations
without corrupting my memory/loosing information.
I know if I was writing standard c++ that's what i'd have to do, but I
admit that I am a bit lost when it comes to IMP due to the entanglement
with python and automatic memory management.
So my question is:
1/ Do you agree that my issue comes from that shallow copy ?
2/ Is there a functionality in IMP to handle such a case ?
Thanks,
sam hanot
class IMPPMIEXPORT FuzzyRestraint;
class IMPPMIEXPORT FuzzyOr;
class IMPPMIEXPORT FuzzyRestraint : public Restraint {
public:
FuzzyRestraint(Model *m, std::string name) : Restraint(m, name) {}
virtual double unprotected_evaluate(DerivativeAccumulator *) const = 0;
virtual ModelObjectsTemp do_get_inputs() const = 0;
FuzzyOr *operator|(FuzzyRestraint *r);
IMP_OBJECT_METHODS(FuzzyRestraint);
};
class IMPPMIEXPORT FuzzyOr : public FuzzyRestraint {
FuzzyRestraint *r1_;
FuzzyRestraint *r2_;
public:
FuzzyOr(Model *m, FuzzyRestraint *r1, FuzzyRestraint *r2)
: FuzzyRestraint(m, "FuzzyOr %1%"), r1_(r1), r2_(r2) {
std::cerr << "Creating FuzzyOr from " << r1_->get_name() << " (" << r1_
<< ") " << r2_->get_name() << " (" << r2_ << ") "
<< ": " << get_name() << '\n';
}
virtual double unprotected_evaluate(DerivativeAccumulator *) const
IMP_OVERRIDE {
Model *m(get_model());
double const a(r1_->unprotected_evaluate(nullptr));
double const b(r2_->unprotected_evaluate(nullptr));
return exp(-a) + exp(-b) - exp(-a - b);
}
virtual ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE {
ModelObjectsTemp ret(r1_->get_inputs());
ModelObjectsTemp const tmp(r2_->get_inputs());
ret.insert(ret.end(), tmp.begin(), tmp.end());
return ret;
}
IMP_OBJECT_METHODS(FuzzyOr);
};
FuzzyOr *FuzzyRestraint::operator|(FuzzyRestraint *r) {
IMP_NEW(IMP::pmi::FuzzyOr, ret, (get_model(), this, r));
return ret.release();
}