1 2 3 #pragma once 4 5 #include "Algorithm.hh" 6 7 namespace cadabra { 8 9 /// \ingroup algorithms 10 /// 11 /// Integrate by parts away from the indicated derivative object. 12 13 14 class integrate_by_parts : public Algorithm { 15 public: 16 integrate_by_parts(const Kernel&, Ex&, Ex&); 17 18 virtual bool can_apply(iterator) override; 19 virtual result_t apply(iterator&) override; 20 21 private: 22 // Integrate by parts on a single term in the integrand. First 23 // argument points to the integral, second to a term in the 24 // integrand. 25 result_t handle_term(iterator, iterator&); 26 27 // Are the given integral and derivative inverses of each-other? 28 bool int_and_derivative_related(iterator int_it, iterator der_it) const; 29 30 // Split one derivative from a multiple derivative. 31 void split_off_single_derivative(iterator int_it, iterator der_it); 32 33 // Wrap the indicated range of factor nodes inside the product node in 34 // the derivative. 35 Ex wrap(iterator, sibling_iterator, sibling_iterator) const; 36 37 // Determine whether the indicated derivative acts on the 'away_from' 38 // expression. 39 bool derivative_acting_on_arg(iterator der_it) const; 40 41 // Expression to move derivative away from. 42 Ex away_from; 43 }; 44 45 } 46