GiNaC  1.8.3
fderivative.cpp
Go to the documentation of this file.
1 
5 /*
6  * GiNaC Copyright (C) 1999-2022 Johannes Gutenberg University Mainz, Germany
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "fderivative.h"
24 #include "operators.h"
25 #include "archive.h"
26 #include "utils.h"
27 
28 #include <iostream>
29 
30 namespace GiNaC {
31 
34  print_func<print_latex>(&fderivative::do_print_latex).
35  print_func<print_csrc>(&fderivative::do_print_csrc).
36  print_func<print_tree>(&fderivative::do_print_tree))
37 
38 // default constructor
41 
43 {
44 }
45 
47 // other constructors
49 
50 fderivative::fderivative(unsigned ser, unsigned param, const exvector & args) : function(ser, args)
51 {
52  parameter_set.insert(param);
53 }
54 
55 fderivative::fderivative(unsigned ser, const paramset & params, const exvector & args) : function(ser, args), parameter_set(params)
56 {
57 }
58 
59 fderivative::fderivative(unsigned ser, const paramset & params, exvector && v) : function(ser, std::move(v)), parameter_set(params)
60 {
61 }
62 
64 // archiving
66 
68 {
69  inherited::read_archive(n, sym_lst);
70  unsigned i = 0;
71  while (true) {
72  unsigned u;
73  if (n.find_unsigned("param", u, i))
74  parameter_set.insert(u);
75  else
76  break;
77  ++i;
78  }
79 }
81 
83 {
84  inherited::archive(n);
85  auto i = parameter_set.begin(), end = parameter_set.end();
86  while (i != end) {
87  n.add_unsigned("param", *i);
88  ++i;
89  }
90 }
91 
92 
94 // functions overriding virtual functions from base classes
96 
97 void fderivative::print(const print_context & c, unsigned level) const
98 {
99  // class function overrides print(), but we don't want that
100  basic::print(c, level);
101 }
102 
103 void fderivative::do_print(const print_context & c, unsigned level) const
104 {
105  c.s << "D[";
106  auto i = parameter_set.begin(), end = parameter_set.end();
107  --end;
108  while (i != end) {
109  c.s << *i++ << ",";
110  }
111  c.s << *i << "](" << registered_functions()[serial].name << ")";
112  printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
113 }
114 
115 void fderivative::do_print_latex(const print_context & c, unsigned level) const
116 {
117  int order=1;
118  c.s << "\\partial_{";
119  auto i = parameter_set.begin(), end = parameter_set.end();
120  --end;
121  while (i != end) {
122  ++order;
123  c.s << *i++ << ",";
124  }
125  c.s << *i << "}";
126  if (order>1)
127  c.s << "^{" << order << "}";
128  c.s << "(" << registered_functions()[serial].TeX_name << ")";
129  printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
130 }
131 
132 void fderivative::do_print_csrc(const print_csrc & c, unsigned level) const
133 {
134  c.s << "D_";
135  auto i = parameter_set.begin(), end = parameter_set.end();
136  --end;
137  while (i != end)
138  c.s << *i++ << "_";
139  c.s << *i << "_" << registered_functions()[serial].name;
140  printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
141 }
142 
143 void fderivative::do_print_tree(const print_tree & c, unsigned level) const
144 {
145  c.s << std::string(level, ' ') << class_name() << " "
146  << registered_functions()[serial].name << " @" << this
147  << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
148  << ", nops=" << nops()
149  << ", params=";
150  auto i = parameter_set.begin(), end = parameter_set.end();
151  --end;
152  while (i != end)
153  c.s << *i++ << ",";
154  c.s << *i << std::endl;
155  for (auto & i : seq)
156  i.print(c, level + c.delta_indent);
157  c.s << std::string(level + c.delta_indent, ' ') << "=====" << std::endl;
158 }
159 
161 {
162  // No parameters specified? Then return the function itself
163  if (parameter_set.empty())
164  return function(serial, seq);
165 
166  // If the function in question actually has a derivative, return it
167  if (registered_functions()[serial].has_derivative() && parameter_set.size() == 1)
168  return pderivative(*(parameter_set.begin()));
169 
170  return this->hold();
171 }
172 
175 ex fderivative::series(const relational & r, int order, unsigned options) const
176 {
177  return basic::series(r, order, options);
178 }
179 
181 {
182  return fderivative(serial, parameter_set, v);
183 }
184 
186 {
187  return fderivative(serial, parameter_set, std::move(v));
188 }
189 
193 {
194  ex result;
195  for (size_t i=0; i<seq.size(); i++) {
196  ex arg_diff = seq[i].diff(s);
197  if (!arg_diff.is_zero()) {
198  paramset ps = parameter_set;
199  ps.insert(i);
200  result += arg_diff * fderivative(serial, ps, seq);
201  }
202  }
203  return result;
204 }
205 
206 int fderivative::compare_same_type(const basic & other) const
207 {
208  GINAC_ASSERT(is_a<fderivative>(other));
209  const fderivative & o = static_cast<const fderivative &>(other);
210 
211  if (parameter_set != o.parameter_set)
212  return parameter_set < o.parameter_set ? -1 : 1;
213  else
214  return inherited::compare_same_type(o);
215 }
216 
217 bool fderivative::is_equal_same_type(const basic & other) const
218 {
219  GINAC_ASSERT(is_a<fderivative>(other));
220  const fderivative & o = static_cast<const fderivative &>(other);
221 
222  if (parameter_set != o.parameter_set)
223  return false;
224  else
225  return inherited::is_equal_same_type(o);
226 }
227 
228 bool fderivative::match_same_type(const basic & other) const
229 {
230  GINAC_ASSERT(is_a<fderivative>(other));
231  const fderivative & o = static_cast<const fderivative &>(other);
232 
233  return parameter_set == o.parameter_set && inherited::match_same_type(other);
234 }
235 
247 {
248  return parameter_set;
249 }
250 
251 
252 } // namespace GiNaC
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition: assertion.h:33
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition: archive.h:49
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition: basic.h:105
unsigned hashvalue
hash value
Definition: basic.h:303
unsigned flags
of type status_flags
Definition: basic.h:302
virtual void print(const print_context &c, unsigned level=0) const
Output to stream.
Definition: basic.cpp:116
const basic & hold() const
Stop further evaluation.
Definition: basic.cpp:887
virtual ex series(const relational &r, int order, unsigned options=0) const
Default implementation of ex::series().
Definition: pseries.cpp:612
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition: basic.cpp:719
Wrapper template for making GiNaC classes out of STL containers.
Definition: container.h:73
virtual void printseq(const print_context &c, char openbracket, char delim, char closebracket, unsigned this_precedence, unsigned upper_precedence=0) const
Print sequence of contained elements.
Definition: container.h:451
const_iterator end() const
Definition: container.h:240
size_t nops() const override
Number of operands/members.
Definition: container.h:118
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
Definition: container.h:117
Lightweight wrapper for GiNaC's symbolic objects.
Definition: ex.h:72
bool is_zero() const
Definition: ex.h:213
This class represents the (abstract) derivative of a symbolic function.
Definition: fderivative.h:38
void do_print_latex(const print_context &c, unsigned level) const
const paramset & derivatives() const
Expose this object's derivative structure.
void do_print(const print_context &c, unsigned level) const
ex derivative(const symbol &s) const override
Implementation of ex::diff() for derivatives.
bool match_same_type(const basic &other) const override
Returns true if the attributes of two objects are similar enough for a match.
ex series(const relational &r, int order, unsigned options=0) const override
The series expansion of derivatives falls back to Taylor expansion.
ex thiscontainer(const exvector &v) const override
fderivative(unsigned ser, unsigned param, const exvector &args)
Construct derivative with respect to one parameter.
Definition: fderivative.cpp:50
void do_print_tree(const print_tree &c, unsigned level) const
ex eval() const override
Perform automatic non-interruptive term rewriting rules.
bool is_equal_same_type(const basic &other) const override
Returns true if two objects of same type are equal.
paramset parameter_set
Set of parameter numbers with respect to which to take the derivative.
Definition: fderivative.h:85
void do_print_csrc(const print_csrc &c, unsigned level) const
void print(const print_context &c, unsigned level=0) const override
Output to stream.
Definition: fderivative.cpp:97
void archive(archive_node &n) const override
Archive the object.
Definition: fderivative.cpp:82
void read_archive(const archive_node &n, lst &syms) override
Load (deserialize) the object from an archive node.
Definition: fderivative.cpp:67
The class function is used to implement builtin functions like sin, cos...
Definition: function.h:674
unsigned serial
Definition: function.h:751
static std::vector< function_options > & registered_functions()
Definition: function.cpp:2225
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
Definition: function.h:707
ex pderivative(unsigned diff_param) const
Definition: function.cpp:2034
Base class for print_contexts.
Definition: print.h:103
Base context for C source output.
Definition: print.h:158
Context for tree-like output for debugging.
Definition: print.h:147
This class holds a relation consisting of two expressions and a logical relation between them.
Definition: relational.h:35
Basic CAS symbol.
Definition: symbol.h:39
unsigned options
Definition: factor.cpp:2480
size_t n
Definition: factor.cpp:1463
size_t c
Definition: factor.cpp:770
size_t r
Definition: factor.cpp:770
Interface to abstract derivatives of functions.
int order
Definition: add.cpp:38
std::multiset< unsigned > paramset
Definition: fderivative.h:32
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition: idx.cpp:45
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
Definition: add.cpp:40
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(lst, basic, print_func< print_context >(&lst::do_print). print_func< print_tree >(&lst::do_print_tree)) template<> bool lst GINAC_BIND_UNARCHIVER(lst)
Specialization of container::info() for lst.
Definition: lst.cpp:42
std::vector< ex > exvector
Definition: basic.h:46
Definition: ex.h:972
Interface to GiNaC's overloaded operators.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.