- info(info_flags::has_indices) now works for sums and products. It
[ginac.git] / ginac / flags.h
1 /** @file flags.h
2  *
3  *  Collection of all flags used through the GiNaC framework. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2007 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 #ifndef __GINAC_FLAGS_H__
24 #define __GINAC_FLAGS_H__
25
26 namespace GiNaC {
27
28 /** Flags to control the behavior of expand(). */
29 class expand_options {
30 public:
31         enum {
32                 expand_indexed = 0x0001,      ///< expands (a+b).i to a.i+b.i
33                 expand_function_args = 0x0002 ///< expands the arguments of functions
34         };
35 };
36
37 /** Flags to control the behavior of has(). */
38 class has_options {
39 public:
40         enum {
41                 algebraic = 0x0001,              ///< enable algebraic matching
42         };
43 };
44
45 /** Flags to control the behavior of subs(). */
46 class subs_options {
47 public:
48         enum {
49                 no_pattern = 0x0001,             ///< disable pattern matching
50                 subs_no_pattern = 0x0001, // for backwards compatibility
51                 algebraic = 0x0002,              ///< enable algebraic substitutions
52                 subs_algebraic = 0x0002,  // for backwards compatibility
53                 pattern_is_product = 0x0004,     ///< used internally by expairseq::subschildren()
54                 pattern_is_not_product = 0x0008, ///< used internally by expairseq::subschildren()
55                 no_index_renaming = 0x0010,
56                 // To indicate that we want to substitue an index by something that is
57                 // is not an index. Without this flag the index value would be
58                 // substituted in that case.
59                 really_subs_idx = 0x0020
60         };
61 };
62
63 /** Domain of an object */
64 class domain {
65 public:
66         enum {
67                 complex,
68                 real,
69                 positive
70         };
71 };
72
73 /** Flags to control series expansion. */
74 class series_options {
75 public:
76         enum {
77                 /** Suppress branch cuts in series expansion.  Branch cuts manifest
78                  *  themselves as step functions, if this option is not passed.  If
79                  *  it is passed and expansion at a point on a cut is performed, then
80                  *  the analytic continuation of the function is expanded. */
81                 suppress_branchcut = 0x0001
82         };
83 };
84
85 /** Switch to control algorithm for determinant computation. */
86 class determinant_algo {
87 public:
88         enum {
89                 /** Let the system choose.  A heuristics is applied for automatic
90                  *  determination of a suitable algorithm. */
91                 automatic,
92                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
93                  *  original matrix, then the matrix is transformed into triangular
94                  *  form by applying the rules
95                  *  \f[
96                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
97                  *  \f]
98                  *  The determinant is then just the product of diagonal elements.
99                  *  Choose this algorithm only for purely numerical matrices. */
100                 gauss,
101                 /** Division-free elimination.  This is a modification of Gauss
102                  *  elimination where the division by the pivot element is not
103                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
104                  *  original matrix, then the matrix is transformed into triangular
105                  *  form by applying the rules
106                  *  \f[
107                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
108                  *  \f]
109                  *  The determinant can later be computed by inspecting the diagonal
110                  *  elements only.  This algorithm is only there for the purpose of
111                  *  cross-checks.  It is never fast. */
112                 divfree,
113                 /** Laplace elimination.  This is plain recursive elimination along
114                  *  minors although multiple minors are avoided by the algorithm.
115                  *  Although the algorithm is exponential in complexity it is
116                  *  frequently the fastest one when the matrix is populated by
117                  *  complicated symbolic expressions. */
118                 laplace,
119                 /** Bareiss fraction-free elimination.  This is a modification of
120                  *  Gauss elimination where the division by the pivot element is
121                  *  <EM>delayed</EM> until it can be carried out without computing
122                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
123                  *  matrix, then the matrix is transformed into triangular form by
124                  *  applying the rules
125                  *  \f[
126                  *      m_{i,j}^{(k+1)} = (m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}) / m_{k-1,k-1}^{(k-1)}
127                  *  \f]
128                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
129                  *  distinction in above formula.)  It can be shown that nothing more
130                  *  than polynomial long division is needed for carrying out the
131                  *  division.  The determinant can then be read of from the lower
132                  *  right entry.  This algorithm is rarely fast for computing
133                  *  determinants. */
134                 bareiss
135         };
136 };
137
138 /** Switch to control algorithm for linear system solving. */
139 class solve_algo {
140 public:
141         enum {
142                 /** Let the system choose.  A heuristics is applied for automatic
143                  *  determination of a suitable algorithm. */
144                 automatic,
145                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
146                  *  original matrix, then the matrix is transformed into triangular
147                  *  form by applying the rules
148                  *  \f[
149                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
150                  *  \f]
151                  *  This algorithm is well-suited for numerical matrices but generally
152                  *  suffers from the expensive division (and computation of GCDs) at
153                  *  each step. */
154                 gauss,
155                 /** Division-free elimination.  This is a modification of Gauss
156                  *  elimination where the division by the pivot element is not
157                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
158                  *  original matrix, then the matrix is transformed into triangular
159                  *  form by applying the rules
160                  *  \f[
161                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
162                  *  \f]
163                  *  This algorithm is only there for the purpose of cross-checks.
164                  *  It suffers from exponential intermediate expression swell.  Use it
165                  *  only for small systems. */
166                 divfree,
167                 /** Bareiss fraction-free elimination.  This is a modification of
168                  *  Gauss elimination where the division by the pivot element is
169                  *  <EM>delayed</EM> until it can be carried out without computing
170                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
171                  *  matrix, then the matrix is transformed into triangular form by
172                  *  applying the rules
173                  *  \f[
174                  *      m_{i,j}^{(k+1)} = (m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}) / m_{k-1,k-1}^{(k-1)}
175                  *  \f]
176                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
177                  *  distinction in above formula.)  It can be shown that nothing more
178                  *  than polynomial long division is needed for carrying out the
179                  *  division.  This is generally the fastest algorithm for solving
180                  *  linear systems.  In contrast to division-free elimination it only
181                  *  has a linear expression swell.  For two-dimensional systems, the
182                  *  two algorithms are equivalent, however. */
183                 bareiss
184         };
185 };
186
187 /** Flags to store information about the state of an object.
188  *  @see basic::flags */
189 class status_flags {
190 public:
191         enum {
192                 dynallocated    = 0x0001, ///< heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
193                 evaluated       = 0x0002, ///< .eval() has already done its job
194                 expanded        = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag)
195                 hash_calculated = 0x0008, ///< .calchash() has already done its job
196                 not_shareable   = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
197                 has_indices     = 0x0020,
198                 has_no_indices  = 0x0040  // ! (has_indices || has_no_indices) means "don't know"
199         };
200 };
201
202 /** Possible attributes an object can have. */
203 class info_flags {
204 public:
205         enum {
206                 // answered by class numeric and symbols/constants in particular domains
207                 numeric,
208                 real,
209                 rational,
210                 integer,
211                 crational,
212                 cinteger,
213                 positive,
214                 negative,
215                 nonnegative,
216                 posint,
217                 negint,
218                 nonnegint,
219                 even,
220                 odd,
221                 prime,
222
223                 // answered by class relation
224                 relation,
225                 relation_equal,
226                 relation_not_equal,
227                 relation_less,
228                 relation_less_or_equal,
229                 relation_greater,
230                 relation_greater_or_equal,
231
232                 // answered by class symbol
233                 symbol,
234
235                 // answered by class lst
236                 list,
237
238                 // answered by class exprseq
239                 exprseq,
240
241                 // answered by classes numeric, symbol, add, mul, power
242                 polynomial,
243                 integer_polynomial,
244                 cinteger_polynomial,
245                 rational_polynomial,
246                 crational_polynomial,
247                 rational_function,
248                 algebraic,
249
250                 // answered by class indexed
251                 indexed,      // class can carry indices
252                 has_indices,  // object has at least one index
253
254                 // answered by class idx
255                 idx,
256
257                 // answered by classes numeric, symbol, add, mul, power
258                 expanded
259         };
260 };
261
262 class return_types {
263 public:
264         enum {
265                 commutative,
266                 noncommutative,
267                 noncommutative_composite
268         };
269 };
270
271 /** Strategies how to clean up the function remember cache.
272  *  @see remember_table */
273 class remember_strategies {
274 public:
275         enum {
276                 delete_never,   ///< Let table grow undefinitely
277                 delete_lru,     ///< Least recently used
278                 delete_lfu,     ///< Least frequently used
279                 delete_cyclic   ///< First (oldest) one in list
280         };
281 };
282
283 } // namespace GiNaC
284
285 #endif // ndef __GINAC_FLAGS_H__