[go: up one dir, main page]

Menu

[r50]: / src / func.h  Maximize  Restore  History

Download this file

415 lines (345 with data), 16.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
/***************************************************************************
func.h - header file for class func, extending the GiNaC function class
*** added in 0.5
-------------------
begin : Fri Feb 13 2004
copyright : (C) 2004 by Jan Rheinlaender
email : jrheinlaender@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef FUNC_H
#define FUNC_H
/**
* @author Jan Rheinlaender
* @short Extends the GiNaC function class
*/
// *** modified in large parts in 0.6 for greater compatibility with GiNaC::function.h
#include <string>
#include <stdexcept>
#include <ginac/ginac.h>
/* removed in 1.4.2, changed to std::map instead
#ifdef _MSC_VER
#include <unordered_map> // *** changed in 1.4.1
#else
#include <ext/hash_map> // *** added in 1.0
#endif
*/
using namespace GiNaC;
#include "expression.h"
//#include "message.h" // *** added in 0.7
#include "utils.h"
class imathprint; // *** added in 1.4.1
/// Helper class to initialize class func
class func_init {
public:
func_init();
private:
/// A boolean used to ensure that init() is only called once in the lifetime of the class
static bool called;
static func_init func_initializer;
};
/* *** replaced by option o_difftype in 1.4.1
enum diff_t { // *** added in 0.6
dfdt, // print the differential as df(x)/dt
dot, // print the differential as \dot{f(x)}
line // print the differential as f'(x)
};
*/
/// This structure stores all the information about a user defined function
struct funcrec {
/// The serial number of the function, if it is hard-coded into GiNaC
unsigned serial;
/// dependant variables of the function (e.g. (x; y; z)
// *** changed name to vars to avoid confusion in 0.6 and changed type to exvector
exvector vars;
/// The definition of the function (e.g. for \\cubic: x^3)
expression definition;
/// True if the function is hard-coded into GiNaC
bool hard;
/// Contains hints for handling and printing of the function
unsigned hints; // *** changed in 0.6
/// Contains the (GiNaC) function options.
// Note we cannot use the options of hard-coded functions, because they are protected
// *** added in 0.6
//function_options opts;
};
/// Define a hash_map for key std::string and value funcrec*
// *** added in 1.0, changed to std::map in 1.4.2
/*
#ifdef _MSC_VER
typedef std::tr1::unordered_map<const std::string, funcrec*, std::tr1::hash<std::string>, eqstr> funcmap; // *** changed in 1.4.1
#else
typedef __gnu_cxx::hash_map<const std::string, funcrec*,
__gnu_cxx::hash<const std::string>, eqstr> funcmap;
#endif
*/
/**
* Internal GiNaC identifier for class func
*/
///const unsigned TINFO_func = 0x42420002U; *** removed in 1.2.1
/// Extends GiNaC::function by runtime definition of functions
// *** Major rewrite in 0.6, changed basic to exprseq and copied class GiNaC::function as
// *** closely as possible because of problems with the subs() method
class func : public exprseq {
GINAC_DECLARE_REGISTERED_CLASS(func, exprseq)
public:
friend class func_init;
private:
/// Helper function for the constructors
void checkargs();
void print_name(const print_context &c) const; // *** added in 1.0
public:
/**
* Construct a func with the given name
* @param n A string with the name of the function
* @param args An exvector containing the arguments of the function, e.g. (2*x; y^2)
* @param discardable Required by GiNaC
*/
// *** changed for GiNaC 1.2.1 in 0.7
func(const std::string &n, const exvector &args = exvector(), bool discardable = false);
/// Create a function from an expression
func(const std::string &n, const expression &e);
/// Create a function from an expression sequence
func(const std::string &n, const exprseq & es);
/// Create a function from an expression vector
func(const std::string &n, exvector &v, bool discardable);
/// Create a function from a pointer to an exvector
func(const std::string &n, std::auto_ptr<exvector> vp); // *** added in 0.7
/// Create a function from another function
func(const std::string &n, const function &f);
/// Print the function arguments
void printseq(const print_context & c, const std::string &openbracket, char delim,
const std::string &closebracket, unsigned this_precedence = 0, unsigned upper_precedence = 0) const;
void printseq(const imathprint & c, const std::string &openbracket, char delim,
const std::string &closebracket, unsigned this_precedence = 0, unsigned upper_precedence = 0) const;
/**
* Print the function in a GiNaC print context.
* @param c The print context (e.g., print_latex)
* @param p A power argument for the function, important for printing sin^2 x instead of (sin x)^2
* @param level Unused, for consistency with GiNaC print methods
*/
void print(const print_context &c, const ex &p, unsigned level = 0) const;
void print_imath(const imathprint &c, const ex &p, unsigned level = 0) const; // *** added in 1.4.1
/**
* Print the function in a GiNaC print context.
* @param c The print context (e.g., print_latex)
* @param level Unused, for consistency with GiNaC print methods
*/
// *** changed name to do_print in 0.8
void do_print(const print_context &c, unsigned level = 0) const;
void do_print_imath(const imathprint &c, unsigned level = 0) const; // *** added in 1.4.1
/// Print function with difftype line
// *** added in 1.4.1
void print_diff_line(const unsigned ndiff, const print_context& c) const;
// functions overriding virtual functions from base classes, see functions.h
/// Set the precedence for functions
unsigned precedence(void) const { return 70; }
/// expand the function, using its definition on the arguments
ex expand(unsigned options = 0) const;
/// symbolic integration (implemented for simple cases only)
const ex eval_integral(const symbol& sym, const ex& lbound, const ex& hbound) const;
/// Evaluate the function to a numeric value, if possible
ex eval(int level=0) const;
/// archive the function
void archive(archive_node& n) const; // *** added in 1.3.1
/// unarchive the function
void read_archive(const archive_node& n, lst& syms); // *** added in 1.3.1
/// Do unsafe evaluations of the function
// *** changed in 1.0 to use a map function
struct reduce_double_funcs : public map_function {
/// Map the expression
ex operator()(const ex &e);
};
/// Replace all GiNaC functions by EQC funcs
struct replace_function_by_func : public map_function { // *** added in 1.0
/// Map the expression
ex operator()(const ex &e);
};
/// Expand all partialdiff functions (by calculating the derivative)
struct expand_partialdiff : public map_function { // *** added in 1.0
/// Map the expression
ex operator()(const ex &e);
};
/// Expand all sum functions (by adding up)
struct expand_sum : public map_function { // *** added in 1.0
/// Map the expression
ex operator()(const ex &e);
};
/**
* Evaluate the function without arguments
@param level An argument to control the recursion depth. Use level=1 to evaluate only the
top level
@returns A GiNaC::ex with the result of the evaluation
@exception runtime_error(Max recursion level reached)
**/
ex evalf(int level = 0) const;
// *** removed evaluation with arguments in 0.6
/// Calculate the hash value of the function
unsigned calchash(void) const;
/// Return this container with v
ex thiscontainer(const exvector &v) const; // *** changed for GiNaC 1.2.1 in 0.7
/// Return this container with vp
ex thiscontainer(std::auto_ptr<exvector> vp) const; // *** changed for GiNaC 1.2.1 in 0.7
/// Create a series expansion of the function
ex series(const relational &r, int order, unsigned options = 0) const;
protected:
/// Calculate the (total) derivative of the function with respect to s
ex derivative(const symbol & s) const; // *** added in 0.6
/**
* Apply the function definition on the function arguments
* An exception is thrown if the function is not registered, or has no definition
@exception runtime_error(Function is not registered)
@exception logic_error(Function has no definition)
**/
ex expand_definition() const;
/// Equality checking functions required by GiNaC
bool is_equal_same_type(const basic & other) const; // *** added in 0.6
/// Type matching function required by GiNaC
bool match_same_type(const basic & other) const; // *** added in 0.6
/// Return type of the function
unsigned return_type(void) const; // *** added in 0.6
/// tinfo number of the function
// return_type_t return_type_tinfo(void) const; // *** added in 0.6, changed to tinfo_t in 1.2.1, changed to return_type_t in 1.3.1 and removed
/** *** added in 0.6
Calculate the partial derivative of the function with respect to the nth dependant variable
@param diff_param The number of the dependant variable
@returns An expression containing the partial derivative
@exception logic_error(Parameter does not exist)
**/
ex pderivative(unsigned diff_param) const;
// Not implemented because class GiNaC::remember_table is specific to GiNaC::function
//bool lookup_remember_table(ex & result) const;
//void store_remember_table(ex const & result) const;
// static (class) functions----------------------------------------------------
private:
static bool initialized; // *** added in 1.3.1
public:
/// Initialize the map of functions with the GiNaC hard-coded functions
static void init(); // *** made public in 1.3.1
/// Delete the function
static void remove(const std::string& fname); // *** added in 1.4.1
/// Return the function table to the state after reading 'mathconstants.tex'
static void clear();
/// Return the function table to the state after init()
static void clearall();
/// Print all the functions that have been registered
static void print_functions();
/**
* Register a user-defined function so that the scanner will be able to look it up.
@param n The Latex name of the function which the scanner finds in the input file
@param args The arguments of the function. This defines number and name of the default
arguments
@param defarg A symbol containing the default argument to use for the function if an argument
in args is invalid
@param h A flag giving hints for printing and processing the function
@exception invalid_argument(Function already exists)
**/
static void registr(const std::string &n, const lst &args, const symbol &defarg,
const unsigned h = 0); // *** added hints in 0.6
// *** added in 0.6
/// Return the number assigned to this hint
static const unsigned hint(const std::string &s);
/**
Define a user-defined function
@param n The name of the function
@param def An expression defining how to evaluate the function
@exception invalid_argument (Function does not exist)
*/
static void define(const std::string &n, const expression &def);
/**
* Check whether fname is a function
@param fname A string containing the name of the function
@returns True if the function exists
*/
static const bool is_a_func(const std::string &fname);
/// Set the notation for the tangent function to 'tg' or to 'tan'
// *** added in 1.4.3
static void set_tangent(const bool is_tg = false);
// *** replaced by option o_difftype in 1.4.1
// Return the flag characterizing the way the derivative should be printed
// static inline const diff_t get_diff_type() {
// return diff_type;
// }
// member functions-------------------------------------------
/**
* Return the name of the function
* @returns A string with the name of the function - not the Latex name!
*/
inline const std::string get_name() const { return(name); }
/// Return the number of arguments of the function
inline const unsigned get_numargs() const { return(numargs); } // *** added in 1.0
/**
* Return true if this is a trigonometric function, else false
* @exception runtime_error(Function is not registered)
**/
const bool is_trig() const;
/**
* Return true if this is a library function, else false
* @exception runtime_error(Function is not registered)
**/
const bool is_lib() const; // *** added in 0.9
/// Return true if the function has no arguments (useful for printing)
inline const bool is_pure() const { return(seq.empty()); } // *** added in 1.0
// member variables -------------------------------------------------
protected:
/// The name of the function, this is used to look it up in the map of registered functions
std::string name;
/// Number of arguments of the function
unsigned numargs; // *** added in 1.0 for efficiency purposes
// *** using seq instead of arguments in 0.6 since func is now a subclass of GiNaC::exprseq
// lst arguments;
/// The number of times this function has been differentiated in each of the dependant variables
// *** added in 0.6, removed in 1.0
//uvector diff_num;
// class variables ------------------------------------------------
/** *** moved here from ltxeqlex.ll and adapted in 0.5
* A map containing a list of function names and pointers to the corresponding func objects
**/
static std::map<const std::string, funcrec*> functions; // *** changed to funcmap in 1.0
/// A map containing the names of the functions hard-coded in GiNaC and their Latex equivalents
static std::map<const std::string, std::string> hard_names;
/// The reverse map, for fast lookup in the opposite direction
static std::map<const std::string, std::string> hard_names_rev;
/// A map containing the numbers assigned to different hints
static std::map<std::string, unsigned> hint_map;
/// A map containing functions and their inverse functions
static std::map<std::string, std::string> func_inv; // *** added in 0.9
// A flag characterizing the way the derivative should be printed
// *** added in 0.6
// *** replaced by option o_difftype in 1.4.1
// static diff_t diff_type;
};
GINAC_DECLARE_UNARCHIVER(func);
// hardcoded functions
// *** differentiation function added in 1.0, replaces diff_num functionality
DECLARE_FUNCTION_3P(partialdiff)
DECLARE_FUNCTION_3P(sum) // *** added in 1.0
DECLARE_FUNCTION_2P(round) // *** added in 1.2
DECLARE_FUNCTION_2P(ceil)
DECLARE_FUNCTION_2P(floor)
DECLARE_FUNCTION_3P(mindex) // *** added in 1.4.1
DECLARE_FUNCTION_1P(transpose) // *** added in 1.4.3
DECLARE_FUNCTION_2P(vecprod)
DECLARE_FUNCTION_2P(scalprod)
DECLARE_FUNCTION_3P(ifelse)
DECLARE_FUNCTION_1P(vmax)
DECLARE_FUNCTION_1P(vmin)
// helper functions ------------------------------------------------
/// Find derivative with respect to a (pure) function
ex diff_to_func(const ex &e, const func &s, const unsigned n = 1); // *** added in 1.0
/** *** added in 0.7
* Print a function an a message stream
* @param ms The message stream to print on
* @param f The func to print
* @returns The message stream (for concatenation of << operators)
**/
// message &operator<<(message &ms, const func &f);
// *** moved operator<<(ostream &, const exvector &) to utils.cpp in 0.7
#endif