]> www.ginac.de Git - ginac.git/commitdiff
Added methods for taking real and imaginary parts.
authorChris Dams <Chris.Dams@mi.infn.it>
Fri, 21 Apr 2006 16:16:01 +0000 (16:16 +0000)
committerChris Dams <Chris.Dams@mi.infn.it>
Fri, 21 Apr 2006 16:16:01 +0000 (16:16 +0000)
31 files changed:
doc/tutorial/ginac.texi
ginac/add.cpp
ginac/add.h
ginac/basic.cpp
ginac/basic.h
ginac/constant.cpp
ginac/constant.h
ginac/container.h
ginac/ex.h
ginac/function.pl
ginac/indexed.cpp
ginac/indexed.h
ginac/inifcns.cpp
ginac/inifcns.h
ginac/inifcns_trans.cpp
ginac/matrix.cpp
ginac/matrix.h
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/pseries.h
ginac/symbol.cpp
ginac/symbol.h
ginac/tensor.cpp
ginac/tensor.h

index a6f802be4c8123afeb13fb848a58bc02374f84e9..08fee762d2bc6d30a4f52b788eb44ab84743f7c5 100644 (file)
@@ -79,20 +79,20 @@ framework for symbolic computation within the C++ programming language.
 
 @menu
 * Introduction::                 GiNaC's purpose.
 
 @menu
 * Introduction::                 GiNaC's purpose.
-* A Tour of GiNaC::              A quick tour of the library.
+* A tour of GiNaC::              A quick tour of the library.
 * Installation::                 How to install the package.
 * Installation::                 How to install the package.
-* Basic Concepts::               Description of fundamental classes.
-* Methods and Functions::        Algorithms for symbolic manipulations.
+* Basic concepts::               Description of fundamental classes.
+* Methods and functions::        Algorithms for symbolic manipulations.
 * Extending GiNaC::              How to extend the library.
 * Extending GiNaC::              How to extend the library.
-* A Comparison With Other CAS::  Compares GiNaC to traditional CAS.
-* Internal Structures::          Description of some internal structures.
-* Package Tools::                Configuring packages to work with GiNaC.
+* A comparison with other CAS::  Compares GiNaC to traditional CAS.
+* Internal structures::          Description of some internal structures.
+* Package tools::                Configuring packages to work with GiNaC.
 * Bibliography::
 * Bibliography::
-* Concept Index::
+* Concept index::
 @end menu
 
 
 @end menu
 
 
-@node Introduction, A Tour of GiNaC, Top, Top
+@node Introduction, A tour of GiNaC, Top, Top
 @c    node-name, next, previous, up
 @chapter Introduction
 @cindex history of GiNaC
 @c    node-name, next, previous, up
 @chapter Introduction
 @cindex history of GiNaC
@@ -154,7 +154,7 @@ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 MA 02110-1301, USA.
 
 
 MA 02110-1301, USA.
 
 
-@node A Tour of GiNaC, How to use it from within C++, Introduction, Top
+@node A tour of GiNaC, How to use it from within C++, Introduction, Top
 @c    node-name, next, previous, up
 @chapter A Tour of GiNaC
 
 @c    node-name, next, previous, up
 @chapter A Tour of GiNaC
 
@@ -168,7 +168,7 @@ leaves many open questions.
 @end menu
 
 
 @end menu
 
 
-@node How to use it from within C++, What it can do for you, A Tour of GiNaC, A Tour of GiNaC
+@node How to use it from within C++, What it can do for you, A tour of GiNaC, A tour of GiNaC
 @c    node-name, next, previous, up
 @section How to use it from within C++
 
 @c    node-name, next, previous, up
 @section How to use it from within C++
 
@@ -206,7 +206,7 @@ $ ./hello
 355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2
 @end example
 
 355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2
 @end example
 
-(@xref{Package Tools}, for tools that help you when creating a software
+(@xref{Package tools}, for tools that help you when creating a software
 package that uses GiNaC.)
 
 @cindex Hermite polynomial
 package that uses GiNaC.)
 
 @cindex Hermite polynomial
@@ -256,7 +256,7 @@ the @command{ginsh}, a simple GiNaC interactive shell that provides a
 convenient window into GiNaC's capabilities.
 
 
 convenient window into GiNaC's capabilities.
 
 
-@node What it can do for you, Installation, How to use it from within C++, A Tour of GiNaC
+@node What it can do for you, Installation, How to use it from within C++, A tour of GiNaC
 @c    node-name, next, previous, up
 @section What it can do for you
 
 @c    node-name, next, previous, up
 @section What it can do for you
 
@@ -638,7 +638,7 @@ subdirectories.  It is therefore safe to go into any subdirectory
 @var{target} there in case something went wrong.
 
 
 @var{target} there in case something went wrong.
 
 
-@node Installing GiNaC, Basic Concepts, Building GiNaC, Installation
+@node Installing GiNaC, Basic concepts, Building GiNaC, Installation
 @c    node-name, next, previous, up
 @section Installing GiNaC
 @cindex installation
 @c    node-name, next, previous, up
 @section Installing GiNaC
 @cindex installation
@@ -691,9 +691,9 @@ do it by hand since you now know where all the files went during
 installation.}.
 
 
 installation.}.
 
 
-@node Basic Concepts, Expressions, Installing GiNaC, Top
+@node Basic concepts, Expressions, Installing GiNaC, Top
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@chapter Basic Concepts
+@chapter Basic concepts
 
 This chapter will describe the different fundamental objects that can be
 handled by GiNaC.  But before doing so, it is worthwhile introducing you
 
 This chapter will describe the different fundamental objects that can be
 handled by GiNaC.  But before doing so, it is worthwhile introducing you
@@ -704,7 +704,7 @@ meta-class for storing all mathematical objects.
 * Expressions::                  The fundamental GiNaC class.
 * Automatic evaluation::         Evaluation and canonicalization.
 * Error handling::               How the library reports errors.
 * Expressions::                  The fundamental GiNaC class.
 * Automatic evaluation::         Evaluation and canonicalization.
 * Error handling::               How the library reports errors.
-* The Class Hierarchy::          Overview of GiNaC's classes.
+* The class hierarchy::          Overview of GiNaC's classes.
 * Symbols::                      Symbolic objects.
 * Numbers::                      Numerical objects.
 * Constants::                    Pre-defined constants.
 * Symbols::                      Symbolic objects.
 * Numbers::                      Numerical objects.
 * Constants::                    Pre-defined constants.
@@ -716,11 +716,11 @@ meta-class for storing all mathematical objects.
 * Matrices::                     Matrices.
 * Indexed objects::              Handling indexed quantities.
 * Non-commutative objects::      Algebras with non-commutative products.
 * Matrices::                     Matrices.
 * Indexed objects::              Handling indexed quantities.
 * Non-commutative objects::      Algebras with non-commutative products.
-* Hash Maps::                    A faster alternative to std::map<>.
+* Hash maps::                    A faster alternative to std::map<>.
 @end menu
 
 
 @end menu
 
 
-@node Expressions, Automatic evaluation, Basic Concepts, Basic Concepts
+@node Expressions, Automatic evaluation, Basic concepts, Basic concepts
 @c    node-name, next, previous, up
 @section Expressions
 @cindex expression (class @code{ex})
 @c    node-name, next, previous, up
 @section Expressions
 @cindex expression (class @code{ex})
@@ -742,7 +742,7 @@ ex MyEx5 = MyEx4 + 1;               // similar to above
 
 Expressions are handles to other more fundamental objects, that often
 contain other expressions thus creating a tree of expressions
 
 Expressions are handles to other more fundamental objects, that often
 contain other expressions thus creating a tree of expressions
-(@xref{Internal Structures}, for particular examples).  Most methods on
+(@xref{Internal structures}, for particular examples).  Most methods on
 @code{ex} therefore run top-down through such an expression tree.  For
 example, the method @code{has()} scans recursively for occurrences of
 something inside an expression.  Thus, if you have declared @code{MyEx4}
 @code{ex} therefore run top-down through such an expression tree.  For
 example, the method @code{has()} scans recursively for occurrences of
 something inside an expression.  Thus, if you have declared @code{MyEx4}
@@ -769,11 +769,11 @@ as @code{std::set<ex, ex_is_less>}.
 Unsorted containers such as @code{std::vector<>} and @code{std::list<>}
 don't pose a problem. A @code{std::vector<ex>} works as expected.
 
 Unsorted containers such as @code{std::vector<>} and @code{std::list<>}
 don't pose a problem. A @code{std::vector<ex>} works as expected.
 
-@xref{Information About Expressions}, for more about comparing and ordering
+@xref{Information about expressions}, for more about comparing and ordering
 expressions.
 
 
 expressions.
 
 
-@node Automatic evaluation, Error handling, Expressions, Basic Concepts
+@node Automatic evaluation, Error handling, Expressions, Basic concepts
 @c    node-name, next, previous, up
 @section Automatic evaluation and canonicalization of expressions
 @cindex evaluation
 @c    node-name, next, previous, up
 @section Automatic evaluation and canonicalization of expressions
 @cindex evaluation
@@ -847,7 +847,7 @@ transform expressions, like @code{subs()} or @code{normal()}, automatically
 re-evaluate their results.
 
 
 re-evaluate their results.
 
 
-@node Error handling, The Class Hierarchy, Automatic evaluation, Basic Concepts
+@node Error handling, The class hierarchy, Automatic evaluation, Basic concepts
 @c    node-name, next, previous, up
 @section Error handling
 @cindex exceptions
 @c    node-name, next, previous, up
 @section Error handling
 @cindex exceptions
@@ -903,7 +903,7 @@ int main()
 @end example
 
 
 @end example
 
 
-@node The Class Hierarchy, Symbols, Error handling, Basic Concepts
+@node The class hierarchy, Symbols, Error handling, Basic concepts
 @c    node-name, next, previous, up
 @section The class hierarchy
 
 @c    node-name, next, previous, up
 @section The class hierarchy
 
@@ -929,7 +929,7 @@ features.  An example is @code{expairseq}, a container for a sequence of
 pairs each consisting of one expression and a number (@code{numeric}).
 What @emph{is} visible to the user are the derived classes @code{add}
 and @code{mul}, representing sums and products.  @xref{Internal
 pairs each consisting of one expression and a number (@code{numeric}).
 What @emph{is} visible to the user are the derived classes @code{add}
 and @code{mul}, representing sums and products.  @xref{Internal
-Structures}, where these two classes are described in more detail.  The
+structures}, where these two classes are described in more detail.  The
 following table shortly summarizes what kinds of mathematical objects
 are stored in the different classes:
 
 following table shortly summarizes what kinds of mathematical objects
 are stored in the different classes:
 
@@ -977,7 +977,7 @@ $\sin 2x$
 @end cartouche
 
 
 @end cartouche
 
 
-@node Symbols, Numbers, The Class Hierarchy, Basic Concepts
+@node Symbols, Numbers, The class hierarchy, Basic concepts
 @c    node-name, next, previous, up
 @section Symbols
 @cindex @code{symbol} (class)
 @c    node-name, next, previous, up
 @section Symbols
 @cindex @code{symbol} (class)
@@ -1128,7 +1128,7 @@ definitions.
 As we said, the names of symbols primarily serve for purposes of expression
 output. But there are actually two instances where GiNaC uses the names for
 identifying symbols: When constructing an expression from a string, and when
 As we said, the names of symbols primarily serve for purposes of expression
 output. But there are actually two instances where GiNaC uses the names for
 identifying symbols: When constructing an expression from a string, and when
-recreating an expression from an archive (@pxref{Input/Output}).
+recreating an expression from an archive (@pxref{Input/output}).
 
 In addition to its name, a symbol may contain a special string that is used
 in LaTeX output:
 
 In addition to its name, a symbol may contain a special string that is used
 in LaTeX output:
@@ -1137,7 +1137,7 @@ symbol x("x", "\\Box");
 @end example
 
 This creates a symbol that is printed as "@code{x}" in normal output, but
 @end example
 
 This creates a symbol that is printed as "@code{x}" in normal output, but
-as "@code{\Box}" in LaTeX code (@xref{Input/Output}, for more
+as "@code{\Box}" in LaTeX code (@xref{Input/output}, for more
 information about the different output formats of expressions in GiNaC).
 GiNaC automatically creates proper LaTeX code for symbols having names of
 greek letters (@samp{alpha}, @samp{mu}, etc.).
 information about the different output formats of expressions in GiNaC).
 GiNaC automatically creates proper LaTeX code for symbols having names of
 greek letters (@samp{alpha}, @samp{mu}, etc.).
@@ -1147,12 +1147,12 @@ Symbols in GiNaC can't be assigned values. If you need to store results of
 calculations and give them a name, use C++ variables of type @code{ex}.
 If you want to replace a symbol in an expression with something else, you
 can invoke the expression's @code{.subs()} method
 calculations and give them a name, use C++ variables of type @code{ex}.
 If you want to replace a symbol in an expression with something else, you
 can invoke the expression's @code{.subs()} method
-(@pxref{Substituting Expressions}).
+(@pxref{Substituting expressions}).
 
 @cindex @code{realsymbol()}
 By default, symbols are expected to stand in for complex values, i.e. they live
 in the complex domain.  As a consequence, operations like complex conjugation,
 
 @cindex @code{realsymbol()}
 By default, symbols are expected to stand in for complex values, i.e. they live
 in the complex domain.  As a consequence, operations like complex conjugation,
-for example (@pxref{Complex Conjugation}), do @emph{not} evaluate if applied
+for example (@pxref{Complex expressions}), do @emph{not} evaluate if applied
 to such symbols. Likewise @code{log(exp(x))} does not evaluate to @code{x},
 because of the unknown imaginary part of @code{x}.
 On the other hand, if you are sure that your symbols will hold only real values, you
 to such symbols. Likewise @code{log(exp(x))} does not evaluate to @code{x},
 because of the unknown imaginary part of @code{x}.
 On the other hand, if you are sure that your symbols will hold only real values, you
@@ -1161,7 +1161,7 @@ the domain of the symbol. Instead of @code{symbol x("x");} you can write
 @code{realsymbol x("x");} to tell GiNaC that @code{x} stands in for real values.
 
 
 @code{realsymbol x("x");} to tell GiNaC that @code{x} stands in for real values.
 
 
-@node Numbers, Constants, Symbols, Basic Concepts
+@node Numbers, Constants, Symbols, Basic concepts
 @c    node-name, next, previous, up
 @section Numbers
 @cindex @code{numeric} (class)
 @c    node-name, next, previous, up
 @section Numbers
 @cindex @code{numeric} (class)
@@ -1511,7 +1511,7 @@ rational number will return a floating-point approximation. Both
 part of complex numbers.
 
 
 part of complex numbers.
 
 
-@node Constants, Fundamental containers, Numbers, Basic Concepts
+@node Constants, Fundamental containers, Numbers, Basic concepts
 @c    node-name, next, previous, up
 @section Constants
 @cindex @code{constant} (class)
 @c    node-name, next, previous, up
 @section Constants
 @cindex @code{constant} (class)
@@ -1541,7 +1541,7 @@ The predefined known constants are:
 @end cartouche
 
 
 @end cartouche
 
 
-@node Fundamental containers, Lists, Constants, Basic Concepts
+@node Fundamental containers, Lists, Constants, Basic concepts
 @c    node-name, next, previous, up
 @section Sums, products and powers
 @cindex polynomial
 @c    node-name, next, previous, up
 @section Sums, products and powers
 @cindex polynomial
@@ -1612,7 +1612,7 @@ and safe simplifications are carried out like transforming
 @code{3*x+4-x} to @code{2*x+4}.
 
 
 @code{3*x+4-x} to @code{2*x+4}.
 
 
-@node Lists, Mathematical functions, Fundamental containers, Basic Concepts
+@node Lists, Mathematical functions, Fundamental containers, Basic concepts
 @c    node-name, next, previous, up
 @section Lists of expressions
 @cindex @code{lst} (class)
 @c    node-name, next, previous, up
 @section Lists of expressions
 @cindex @code{lst} (class)
@@ -1777,7 +1777,7 @@ elements with @code{unique()}:
 @end example
 
 
 @end example
 
 
-@node Mathematical functions, Relations, Lists, Basic Concepts
+@node Mathematical functions, Relations, Lists, Basic concepts
 @c    node-name, next, previous, up
 @section Mathematical functions
 @cindex @code{function} (class)
 @c    node-name, next, previous, up
 @section Mathematical functions
 @cindex @code{function} (class)
@@ -1786,7 +1786,7 @@ elements with @code{unique()}:
 
 There are quite a number of useful functions hard-wired into GiNaC.  For
 instance, all trigonometric and hyperbolic functions are implemented
 
 There are quite a number of useful functions hard-wired into GiNaC.  For
 instance, all trigonometric and hyperbolic functions are implemented
-(@xref{Built-in Functions}, for a complete list).
+(@xref{Built-in functions}, for a complete list).
 
 These functions (better called @emph{pseudofunctions}) are all objects
 of class @code{function}.  They accept one or more expressions as
 
 These functions (better called @emph{pseudofunctions}) are all objects
 of class @code{function}.  They accept one or more expressions as
@@ -1829,7 +1829,7 @@ point number of class @code{numeric} you should call
 wrapped inside an @code{ex}.
 
 
 wrapped inside an @code{ex}.
 
 
-@node Relations, Integrals, Mathematical functions, Basic Concepts
+@node Relations, Integrals, Mathematical functions, Basic concepts
 @c    node-name, next, previous, up
 @section Relations
 @cindex @code{relational} (class)
 @c    node-name, next, previous, up
 @section Relations
 @cindex @code{relational} (class)
@@ -1855,7 +1855,7 @@ conversion from @code{relational} to @code{bool} takes place.  Note,
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
-@node Integrals, Matrices, Relations, Basic Concepts
+@node Integrals, Matrices, Relations, Basic concepts
 @c    node-name, next, previous, up
 @section Integrals
 @cindex @code{integral} (class)
 @c    node-name, next, previous, up
 @section Integrals
 @cindex @code{integral} (class)
@@ -1916,7 +1916,7 @@ respectively calling @code{.op(0)}, @code{.op(1)}, @code{.op(2)}, and
 as expected. Note that it makes no sense to differentiate an integral
 with respect to the integration variable.
 
 as expected. Note that it makes no sense to differentiate an integral
 with respect to the integration variable.
 
-@node Matrices, Indexed objects, Integrals, Basic Concepts
+@node Matrices, Indexed objects, Integrals, Basic concepts
 @c    node-name, next, previous, up
 @section Matrices
 @cindex @code{matrix} (class)
 @c    node-name, next, previous, up
 @section Matrices
 @cindex @code{matrix} (class)
@@ -2180,7 +2180,7 @@ contain some of the indeterminates from @code{vars}.  If the system is
 overdetermined, an exception is thrown.
 
 
 overdetermined, an exception is thrown.
 
 
-@node Indexed objects, Non-commutative objects, Matrices, Basic Concepts
+@node Indexed objects, Non-commutative objects, Matrices, Basic concepts
 @c    node-name, next, previous, up
 @section Indexed objects
 
 @c    node-name, next, previous, up
 @section Indexed objects
 
@@ -2329,7 +2329,7 @@ bool idx::is_dim_symbolic();
 
 for checking whether the value and dimension are numeric or symbolic
 (non-numeric). Using the @code{info()} method of an index (see @ref{Information
 
 for checking whether the value and dimension are numeric or symbolic
 (non-numeric). Using the @code{info()} method of an index (see @ref{Information
-About Expressions}) returns information about the index value.
+about expressions}) returns information about the index value.
 
 @cindex @code{varidx} (class)
 If you need co- and contravariant indices, use the @code{varidx} class:
 
 @cindex @code{varidx} (class)
 If you need co- and contravariant indices, use the @code{varidx} class:
@@ -2420,7 +2420,7 @@ and the same or opposite variance.
 Sometimes you will want to substitute one symbolic index with another
 symbolic or numeric index, for example when calculating one specific element
 of a tensor expression. This is done with the @code{.subs()} method, as it
 Sometimes you will want to substitute one symbolic index with another
 symbolic or numeric index, for example when calculating one specific element
 of a tensor expression. This is done with the @code{.subs()} method, as it
-is done for symbols (see @ref{Substituting Expressions}).
+is done for symbols (see @ref{Substituting expressions}).
 
 You have two possibilities here. You can either substitute the whole index
 by another index or expression:
 
 You have two possibilities here. You can either substitute the whole index
 by another index or expression:
@@ -2956,7 +2956,7 @@ one form for @samp{F} and explicitly multiply it with a matrix representation
 of the metric tensor.
 
 
 of the metric tensor.
 
 
-@node Non-commutative objects, Hash Maps, Indexed objects, Basic Concepts
+@node Non-commutative objects, Hash maps, Indexed objects, Basic concepts
 @c    node-name, next, previous, up
 @section Non-commutative objects
 
 @c    node-name, next, previous, up
 @section Non-commutative objects
 
@@ -3717,7 +3717,7 @@ example:
 @end example
 
 
 @end example
 
 
-@node Hash Maps, Methods and Functions, Non-commutative objects, Basic Concepts
+@node Hash maps, Methods and functions, Non-commutative objects, Basic concepts
 @c    node-name, next, previous, up
 @section Hash Maps
 @cindex hash maps
 @c    node-name, next, previous, up
 @section Hash Maps
 @cindex hash maps
@@ -3753,9 +3753,9 @@ table
 @end itemize
 
 
 @end itemize
 
 
-@node Methods and Functions, Information About Expressions, Hash Maps, Top
+@node Methods and functions, Information about expressions, Hash maps, Top
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@chapter Methods and Functions
+@chapter Methods and functions
 @cindex polynomial
 
 In this chapter the most important algorithms provided by GiNaC will be
 @cindex polynomial
 
 In this chapter the most important algorithms provided by GiNaC will be
@@ -3794,26 +3794,26 @@ method on class @code{ex} and sometimes calling a function cannot be
 avoided.
 
 @menu
 avoided.
 
 @menu
-* Information About Expressions::
-* Numerical Evaluation::
-* Substituting Expressions::
-* Pattern Matching and Advanced Substitutions::
-* Applying a Function on Subexpressions::
-* Visitors and Tree Traversal::
-* Polynomial Arithmetic::           Working with polynomials.
-* Rational Expressions::            Working with rational functions.
-* Symbolic Differentiation::
-* Series Expansion::                Taylor and Laurent expansion.
+* Information about expressions::
+* Numerical evaluation::
+* Substituting expressions::
+* Pattern matching and advanced substitutions::
+* Applying a function on subexpressions::
+* Visitors and tree traversal::
+* Polynomial arithmetic::           Working with polynomials.
+* Rational expressions::            Working with rational functions.
+* Symbolic differentiation::
+* Series expansion::                Taylor and Laurent expansion.
 * Symmetrization::
 * Symmetrization::
-* Built-in Functions::              List of predefined mathematical functions.
+* Built-in functions::              List of predefined mathematical functions.
 * Multiple polylogarithms::
 * Multiple polylogarithms::
-* Complex Conjugation::
-* Solving Linear Systems of Equations::
-* Input/Output::                    Input and output of expressions.
+* Complex expressions::
+* Solving linear systems of equations::
+* Input/output::                    Input and output of expressions.
 @end menu
 
 
 @end menu
 
 
-@node Information About Expressions, Numerical Evaluation, Methods and Functions, Methods and Functions
+@node Information about expressions, Numerical evaluation, Methods and functions, Methods and functions
 @c    node-name, next, previous, up
 @section Getting information about expressions
 
 @c    node-name, next, previous, up
 @section Getting information about expressions
 
@@ -3840,7 +3840,7 @@ unsigned ex::return_type_tinfo() const;
 
 When the test made by @code{is_a<T>()} returns true, it is safe to call
 one of the functions @code{ex_to<T>()}, where @code{T} is one of the
 
 When the test made by @code{is_a<T>()} returns true, it is safe to call
 one of the functions @code{ex_to<T>()}, where @code{T} is one of the
-class names (@xref{The Class Hierarchy}, for a list of all classes). For
+class names (@xref{The class hierarchy}, for a list of all classes). For
 example, assuming @code{e} is an @code{ex}:
 
 @example
 example, assuming @code{e} is an @code{ex}:
 
 @example
@@ -3854,7 +3854,7 @@ example, assuming @code{e} is an @code{ex}:
 
 @code{is_a<T>(e)} allows you to check whether the top-level object of
 an expression @samp{e} is an instance of the GiNaC class @samp{T}
 
 @code{is_a<T>(e)} allows you to check whether the top-level object of
 an expression @samp{e} is an instance of the GiNaC class @samp{T}
-(@xref{The Class Hierarchy}, for a list of all classes). This is most useful,
+(@xref{The class hierarchy}, for a list of all classes). This is most useful,
 e.g., for checking whether an expression is a number, a sum, or a product:
 
 @example
 e.g., for checking whether an expression is a number, a sum, or a product:
 
 @example
@@ -4170,7 +4170,7 @@ if @code{*this} sorts before @code{other}, and @math{1} if @code{*this} sorts
 after @code{other}.
 
 
 after @code{other}.
 
 
-@node Numerical Evaluation, Substituting Expressions, Information About Expressions, Methods and Functions
+@node Numerical evaluation, Substituting expressions, Information about expressions, Methods and functions
 @c    node-name, next, previous, up
 @section Numerical evaluation
 @cindex @code{evalf()}
 @c    node-name, next, previous, up
 @section Numerical evaluation
 @cindex @code{evalf()}
@@ -4210,7 +4210,7 @@ call @code{evalf()} followed by @code{numeric::to_double()}, like this:
 @end example
 
 
 @end example
 
 
-@node Substituting Expressions, Pattern Matching and Advanced Substitutions, Numerical Evaluation, Methods and Functions
+@node Substituting expressions, Pattern matching and advanced substitutions, Numerical evaluation, Methods and functions
 @c    node-name, next, previous, up
 @section Substituting expressions
 @cindex @code{subs()}
 @c    node-name, next, previous, up
 @section Substituting expressions
 @cindex @code{subs()}
@@ -4283,7 +4283,7 @@ The optional last argument to @code{subs()} is a combination of
 large @code{subs()} operations significantly faster if you are not using
 patterns. The second option, @code{subs_options::algebraic} enables
 algebraic substitutions in products and powers.
 large @code{subs()} operations significantly faster if you are not using
 patterns. The second option, @code{subs_options::algebraic} enables
 algebraic substitutions in products and powers.
-@ref{Pattern Matching and Advanced Substitutions}, for more information
+@ref{Pattern matching and advanced substitutions}, for more information
 about patterns and algebraic substitutions. The third option,
 @code{subs_options::no_index_renaming} disables the feature that dummy
 indices are renamed if the subsitution could give a result in which a
 about patterns and algebraic substitutions. The third option,
 @code{subs_options::no_index_renaming} disables the feature that dummy
 indices are renamed if the subsitution could give a result in which a
@@ -4317,7 +4317,7 @@ A more powerful form of substitution using wildcards is described in the
 next section.
 
 
 next section.
 
 
-@node Pattern Matching and Advanced Substitutions, Applying a Function on Subexpressions, Substituting Expressions, Methods and Functions
+@node Pattern matching and advanced substitutions, Applying a function on subexpressions, Substituting expressions, Methods and functions
 @c    node-name, next, previous, up
 @section Pattern matching and advanced substitutions
 @cindex @code{wildcard} (class)
 @c    node-name, next, previous, up
 @section Pattern matching and advanced substitutions
 @cindex @code{wildcard} (class)
@@ -4610,7 +4610,7 @@ return @code{x^(-1)*c^2*z}. Note that this only works for multiplications
 and not for locating @code{x+y} within @code{x+y+z}.
 
 
 and not for locating @code{x+y} within @code{x+y+z}.
 
 
-@node Applying a Function on Subexpressions, Visitors and Tree Traversal, Pattern Matching and Advanced Substitutions, Methods and Functions
+@node Applying a function on subexpressions, Visitors and tree traversal, Pattern matching and advanced substitutions, Methods and functions
 @c    node-name, next, previous, up
 @section Applying a function on subexpressions
 @cindex tree traversal
 @c    node-name, next, previous, up
 @section Applying a function on subexpressions
 @cindex tree traversal
@@ -4755,7 +4755,7 @@ argument. You can not use functions like @samp{diff()}, @samp{op()},
 @end example
 
 
 @end example
 
 
-@node Visitors and Tree Traversal, Polynomial Arithmetic, Applying a Function on Subexpressions, Methods and Functions
+@node Visitors and tree traversal, Polynomial arithmetic, Applying a function on subexpressions, Methods and functions
 @c    node-name, next, previous, up
 @section Visitors and tree traversal
 @cindex tree traversal
 @c    node-name, next, previous, up
 @section Visitors and tree traversal
 @cindex tree traversal
@@ -4977,7 +4977,7 @@ lst gather_indices(const ex & e)
 @end example
 
 
 @end example
 
 
-@node Polynomial Arithmetic, Rational Expressions, Visitors and Tree Traversal, Methods and Functions
+@node Polynomial arithmetic, Rational expressions, Visitors and tree traversal, Methods and functions
 @c    node-name, next, previous, up
 @section Polynomial arithmetic
 
 @c    node-name, next, previous, up
 @section Polynomial arithmetic
 
@@ -5351,7 +5351,7 @@ Note also, how factors with the same exponents are not fully factorized
 with this method.
 
 
 with this method.
 
 
-@node Rational Expressions, Symbolic Differentiation, Polynomial Arithmetic, Methods and Functions
+@node Rational expressions, Symbolic differentiation, Polynomial arithmetic, Methods and functions
 @c    node-name, next, previous, up
 @section Rational expressions
 
 @c    node-name, next, previous, up
 @section Rational expressions
 
@@ -5477,7 +5477,7 @@ The following more useful example will print @samp{sin(x)-cos(x)}:
 @end example
 
 
 @end example
 
 
-@node Symbolic Differentiation, Series Expansion, Rational Expressions, Methods and Functions
+@node Symbolic differentiation, Series expansion, Rational expressions, Methods and functions
 @c    node-name, next, previous, up
 @section Symbolic differentiation
 @cindex differentiation
 @c    node-name, next, previous, up
 @section Symbolic differentiation
 @cindex differentiation
@@ -5543,7 +5543,7 @@ When you run it, it produces the sequence @code{1}, @code{-1}, @code{5},
 @code{i} by two since all odd Euler numbers vanish anyways.
 
 
 @code{i} by two since all odd Euler numbers vanish anyways.
 
 
-@node Series Expansion, Symmetrization, Symbolic Differentiation, Methods and Functions
+@node Series expansion, Symmetrization, Symbolic differentiation, Methods and functions
 @c    node-name, next, previous, up
 @section Series expansion
 @cindex @code{series()}
 @c    node-name, next, previous, up
 @section Series expansion
 @cindex @code{series()}
@@ -5656,7 +5656,7 @@ program, it will type out:
 @end example
 
 
 @end example
 
 
-@node Symmetrization, Built-in Functions, Series Expansion, Methods and Functions
+@node Symmetrization, Built-in functions, Series expansion, Methods and functions
 @c    node-name, next, previous, up
 @section Symmetrization
 @cindex @code{symmetrize()}
 @c    node-name, next, previous, up
 @section Symmetrization
 @cindex @code{symmetrize()}
@@ -5702,7 +5702,7 @@ almost any kind of object (anything that is @code{subs()}able):
 @}
 @end example
 
 @}
 @end example
 
-@node Built-in Functions, Multiple polylogarithms, Symmetrization, Methods and Functions
+@node Built-in functions, Multiple polylogarithms, Symmetrization, Methods and functions
 @c    node-name, next, previous, up
 @section Predefined mathematical functions
 @c
 @c    node-name, next, previous, up
 @section Predefined mathematical functions
 @c
@@ -5724,7 +5724,12 @@ GiNaC contains the following predefined mathematical functions:
 @cindex @code{conjugate()}
 @item @code{conjugate(x)}
 @tab complex conjugation
 @cindex @code{conjugate()}
 @item @code{conjugate(x)}
 @tab complex conjugation
-@cindex @code{conjugate()}
+@cindex @code{real_part()}
+@item @code{real_part(x)}
+@tab real part
+@cindex @code{imag_part()}
+@item @code{imag_part(x)}
+@tab imaginary part
 @item @code{sqrt(x)}
 @tab square root (not a GiNaC function, rather an alias for @code{pow(x, numeric(1, 2))})
 @cindex @code{sqrt()}
 @item @code{sqrt(x)}
 @tab square root (not a GiNaC function, rather an alias for @code{pow(x, numeric(1, 2))})
 @cindex @code{sqrt()}
@@ -5841,7 +5846,7 @@ serious CAS.  It is to be expected that future revisions of the C++
 standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
 standard incorporate these functions in the complex domain in a manner
 compatible with C99.
 
-@node Multiple polylogarithms, Complex Conjugation, Built-in Functions, Methods and Functions
+@node Multiple polylogarithms, Complex expressions, Built-in functions, Methods and functions
 @c    node-name, next, previous, up
 @subsection Multiple polylogarithms
 
 @c    node-name, next, previous, up
 @subsection Multiple polylogarithms
 
@@ -6001,21 +6006,32 @@ J.Borwein, D.Bradley, D.Broadhurst, P.Lisonek, Trans.Amer.Math.Soc. 353/3 (2001)
 @cite{Numerical Evaluation of Multiple Polylogarithms}, 
 J.Vollinga, S.Weinzierl, hep-ph/0410259
 
 @cite{Numerical Evaluation of Multiple Polylogarithms}, 
 J.Vollinga, S.Weinzierl, hep-ph/0410259
 
-@node Complex Conjugation, Solving Linear Systems of Equations, Multiple polylogarithms, Methods and Functions
+@node Complex expressions, Solving linear systems of equations, Multiple polylogarithms, Methods and functions
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@section Complex conjugation
+@section Complex expressions
 @c
 @cindex @code{conjugate()}
 
 @c
 @cindex @code{conjugate()}
 
-The method
+For dealing with complex expressions there are the methods
 
 @example
 ex ex::conjugate();
 
 @example
 ex ex::conjugate();
+ex ex::real_part();
+ex ex::imag_part();
 @end example
 
 @end example
 
-returns the complex conjugate of the expression. For all built-in functions and objects the
-conjugation gives the expected results:
+that return respectively the complex conjugate, the real part and the
+imaginary part of an expression. Complex conjugation works as expected
+for all built-in functinos and objects. Taking real and imaginary
+parts has not yet been implemented for all built-in functions. In cases where
+it is not known how to conjugate or take a real/imaginary part one
+of the functions @code{conjugate}, @code{real_part} or @code{imag_part}
+is returned. For instance, in case of a complex symbol @code{x}
+(symbols are complex by default), one could not simplify
+@code{conjugate(x)}. In the case of strings of gamma matrices,
+the @code{conjugate} method takes the Dirac conjugate.
 
 
+For example,
 @example
 @{
     varidx a(symbol("a"), 4), b(symbol("b"), 4);
 @example
 @{
     varidx a(symbol("a"), 4), b(symbol("b"), 4);
@@ -6029,13 +6045,14 @@ conjugation gives the expected results:
 @}
 @end example
 
 @}
 @end example
 
-For symbols in the complex domain the conjugation can not be evaluated and the GiNaC function
-@code{conjugate} is returned. GiNaC functions conjugate by applying the conjugation to their
-arguments. This is the default strategy. If you want to define your own functions and want to
-change this behavior, you have to supply a specialized conjugation method for your function
-(see @ref{Symbolic functions} and the GiNaC source-code for @code{abs} as an example).
+If you declare your own GiNaC functions, then they will conjugate themselves
+by conjugating their arguments. This is the default strategy. If you want to
+change this behavior, you have to supply a specialized conjugation method
+for your function (see @ref{Symbolic functions} and the GiNaC source-code
+for @code{abs} as an example). Also, specialized methods can be provided
+to take real and imaginary parts of user-defined functions.
 
 
-@node Solving Linear Systems of Equations, Input/Output, Complex Conjugation, Methods and Functions
+@node Solving linear systems of equations, Input/output, Complex expressions, Methods and functions
 @c    node-name, next, previous, up
 @section Solving linear systems of equations
 @cindex @code{lsolve()}
 @c    node-name, next, previous, up
 @section Solving linear systems of equations
 @cindex @code{lsolve()}
@@ -6051,7 +6068,7 @@ ex lsolve(const ex & eqns, const ex & symbols,
 
 Here, @code{eqns} is a @code{lst} of equalities (i.e. class
 @code{relational}) while @code{symbols} is a @code{lst} of
 
 Here, @code{eqns} is a @code{lst} of equalities (i.e. class
 @code{relational}) while @code{symbols} is a @code{lst} of
-indeterminates.  (@xref{The Class Hierarchy}, for an exposition of class
+indeterminates.  (@xref{The class hierarchy}, for an exposition of class
 @code{lst}).
 
 It returns the @code{lst} of solutions as an expression.  As an example,
 @code{lst}).
 
 It returns the @code{lst} of solutions as an expression.  As an example,
@@ -6076,7 +6093,7 @@ to @code{lsolve()}: it accepts the same parameters as
 around that method.
 
 
 around that method.
 
 
-@node Input/Output, Extending GiNaC, Solving Linear Systems of Equations, Methods and Functions
+@node Input/output, Extending GiNaC, Solving linear systems of equations, Methods and functions
 @c    node-name, next, previous, up
 @section Input and output of expressions
 @cindex I/O
 @c    node-name, next, previous, up
 @section Input and output of expressions
 @cindex I/O
@@ -6518,7 +6535,7 @@ Be warned, however, that the set of properties and their meaning for each
 class may change between GiNaC versions.
 
 
 class may change between GiNaC versions.
 
 
-@node Extending GiNaC, What does not belong into GiNaC, Input/Output, Top
+@node Extending GiNaC, What does not belong into GiNaC, Input/output, Top
 @c    node-name, next, previous, up
 @chapter Extending GiNaC
 
 @c    node-name, next, previous, up
 @chapter Extending GiNaC
 
@@ -6876,7 +6893,7 @@ code for the @code{psi()} function (@file{inifcns.h} and
 @section GiNaC's expression output system
 
 GiNaC allows the output of expressions in a variety of different formats
 @section GiNaC's expression output system
 
 GiNaC allows the output of expressions in a variety of different formats
-(@pxref{Input/Output}). This section will explain how expression output
+(@pxref{Input/output}). This section will explain how expression output
 is implemented internally, and how to define your own output formats or
 change the output format of built-in algebraic objects. You will also want
 to read this section if you plan to write your own algebraic classes or
 is implemented internally, and how to define your own output formats or
 change the output format of built-in algebraic objects. You will also want
 to read this section if you plan to write your own algebraic classes or
@@ -7558,7 +7575,7 @@ Note that the unarchiving constructor is @code{sprod::structure} and not
 @code{sprod::unarchive()} function.
 
 
 @code{sprod::unarchive()} function.
 
 
-@node Adding classes, A Comparison With Other CAS, Structures, Extending GiNaC
+@node Adding classes, A comparison with other CAS, Structures, Extending GiNaC
 @c    node-name, next, previous, up
 @section Adding classes
 
 @c    node-name, next, previous, up
 @section Adding classes
 
@@ -8066,7 +8083,7 @@ should become a need.
 That's it. May the source be with you!
 
 
 That's it. May the source be with you!
 
 
-@node A Comparison With Other CAS, Advantages, Adding classes, Top
+@node A comparison with other CAS, Advantages, Adding classes, Top
 @c    node-name, next, previous, up
 @chapter A Comparison With Other CAS
 @cindex advocacy
 @c    node-name, next, previous, up
 @chapter A Comparison With Other CAS
 @cindex advocacy
@@ -8082,7 +8099,7 @@ disadvantages over these systems.
 * Why C++?::                         Attractiveness of C++.
 @end menu
 
 * Why C++?::                         Attractiveness of C++.
 @end menu
 
-@node Advantages, Disadvantages, A Comparison With Other CAS, A Comparison With Other CAS
+@node Advantages, Disadvantages, A comparison with other CAS, A comparison with other CAS
 @c    node-name, next, previous, up
 @section Advantages
 
 @c    node-name, next, previous, up
 @section Advantages
 
@@ -8162,7 +8179,7 @@ speed with other CAS.
 @end itemize
 
 
 @end itemize
 
 
-@node Disadvantages, Why C++?, Advantages, A Comparison With Other CAS
+@node Disadvantages, Why C++?, Advantages, A comparison with other CAS
 @c    node-name, next, previous, up
 @section Disadvantages
 
 @c    node-name, next, previous, up
 @section Disadvantages
 
@@ -8197,7 +8214,7 @@ yet ANSI compliant, support all needed features.
 @end itemize
 
 
 @end itemize
 
 
-@node Why C++?, Internal Structures, Disadvantages, A Comparison With Other CAS
+@node Why C++?, Internal structures, Disadvantages, A comparison with other CAS
 @c    node-name, next, previous, up
 @section Why C++?
 
 @c    node-name, next, previous, up
 @section Why C++?
 
@@ -8214,16 +8231,16 @@ Furthermore, the main developers are more familiar with C++ than with
 any other programming language.
 
 
 any other programming language.
 
 
-@node Internal Structures, Expressions are reference counted, Why C++? , Top
+@node Internal structures, Expressions are reference counted, Why C++? , Top
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@appendix Internal Structures
+@appendix Internal structures
 
 @menu
 * Expressions are reference counted::
 * Internal representation of products and sums::
 @end menu
 
 
 @menu
 * Expressions are reference counted::
 * Internal representation of products and sums::
 @end menu
 
-@node Expressions are reference counted, Internal representation of products and sums, Internal Structures, Internal Structures
+@node Expressions are reference counted, Internal representation of products and sums, Internal structures, Internal structures
 @c    node-name, next, previous, up
 @appendixsection Expressions are reference counted
 
 @c    node-name, next, previous, up
 @appendixsection Expressions are reference counted
 
@@ -8312,7 +8329,7 @@ Marshall Cline.  Chapter 16 covers this issue and presents an
 implementation which is pretty close to the one in GiNaC.
 
 
 implementation which is pretty close to the one in GiNaC.
 
 
-@node Internal representation of products and sums, Package Tools, Expressions are reference counted, Internal Structures
+@node Internal representation of products and sums, Package tools, Expressions are reference counted, Internal structures
 @c    node-name, next, previous, up
 @appendixsection Internal representation of products and sums
 
 @c    node-name, next, previous, up
 @appendixsection Internal representation of products and sums
 
@@ -8380,9 +8397,9 @@ expansion and the like are reimplemented for @code{add} and @code{mul},
 but the data structure is inherited from @code{expairseq}.
 
 
 but the data structure is inherited from @code{expairseq}.
 
 
-@node Package Tools, ginac-config, Internal representation of products and sums, Top
+@node Package tools, ginac-config, Internal representation of products and sums, Top
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@appendix Package Tools
+@appendix Package tools
 
 If you are creating a software package that uses the GiNaC library,
 setting the correct command line options for the compiler and linker
 
 If you are creating a software package that uses the GiNaC library,
 setting the correct command line options for the compiler and linker
@@ -8394,7 +8411,7 @@ can be difficult. GiNaC includes two tools to make this process easier.
 @end menu
 
 
 @end menu
 
 
-@node ginac-config, AM_PATH_GINAC, Package Tools, Package Tools
+@node ginac-config, AM_PATH_GINAC, Package tools, Package tools
 @c    node-name, next, previous, up
 @section @command{ginac-config}
 @cindex ginac-config
 @c    node-name, next, previous, up
 @section @command{ginac-config}
 @cindex ginac-config
@@ -8441,7 +8458,7 @@ Not only is the form using @command{ginac-config} easier to type, it will
 work on any system, no matter how GiNaC was configured.
 
 
 work on any system, no matter how GiNaC was configured.
 
 
-@node AM_PATH_GINAC, Configure script options, ginac-config, Package Tools
+@node AM_PATH_GINAC, Configure script options, ginac-config, Package tools
 @c    node-name, next, previous, up
 @section @samp{AM_PATH_GINAC}
 @cindex AM_PATH_GINAC
 @c    node-name, next, previous, up
 @section @samp{AM_PATH_GINAC}
 @cindex AM_PATH_GINAC
@@ -8654,7 +8671,7 @@ $ make install
 @end example
 
 
 @end example
 
 
-@node Bibliography, Concept Index, Example package, Top
+@node Bibliography, Concept index, Example package, Top
 @c    node-name, next, previous, up
 @appendix Bibliography
 
 @c    node-name, next, previous, up
 @appendix Bibliography
 
@@ -8699,9 +8716,9 @@ ISBN 3-540-66572-2, 2001, Springer, Heidelberg
 @end itemize
 
 
 @end itemize
 
 
-@node Concept Index, , Bibliography, Top
+@node Concept index, , Bibliography, Top
 @c    node-name, next, previous, up
 @c    node-name, next, previous, up
-@unnumbered Concept Index
+@unnumbered Concept index
 
 @printindex cp
 
 
 @printindex cp
 
index acced780a596e5eea340365b1b26e058f44d31b6..9c314ee64dba61bbee6e05ebb950da7a2f6ebf9f 100644 (file)
@@ -424,6 +424,36 @@ ex add::conjugate() const
        return *this;
 }
 
        return *this;
 }
 
+ex add::real_part() const
+{
+       epvector v;
+       v.reserve(seq.size());
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+               if ((i->coeff).info(info_flags::real))
+                       v.push_back(expair((i->rest).real_part(), i->coeff));
+               else {
+                       ex rp=recombine_pair_to_ex(*i).real_part();
+                       v.push_back(split_ex_to_pair(rp));
+               }
+       return (new add(v, overall_coeff.real_part()))
+               -> setflag(status_flags::dynallocated);
+}
+
+ex add::imag_part() const
+{
+       epvector v;
+       v.reserve(seq.size());
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+               if ((i->coeff).info(info_flags::real))
+                       v.push_back(expair((i->rest).imag_part(), i->coeff));
+               else {
+                       ex ip=recombine_pair_to_ex(*i).imag_part();
+                       v.push_back(split_ex_to_pair(ip));
+               }
+       return (new add(v, overall_coeff.imag_part()))
+               -> setflag(status_flags::dynallocated);
+}
+
 ex add::eval_ncmul(const exvector & v) const
 {
        if (seq.empty())
 ex add::eval_ncmul(const exvector & v) const
 {
        if (seq.empty())
index 6d87f6bc65980eee622cc6fc55da9bcdecdbaaac..cee93aae38bf9b03fd7a89c1972646d90f55d9c5 100644 (file)
@@ -58,6 +58,8 @@ public:
        ex smod(const numeric &xi) const;
        numeric max_coefficient() const;
        ex conjugate() const;
        ex smod(const numeric &xi) const;
        numeric max_coefficient() const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
        exvector get_free_indices() const;
        ex eval_ncmul(const exvector & v) const;
 protected:
        exvector get_free_indices() const;
        ex eval_ncmul(const exvector & v) const;
 protected:
index a3c727bebaaa270404cbfc878bf3533a83706288..f86483e4ec7da5b7000c258939e18cc0b6e9c4bd 100644 (file)
@@ -38,6 +38,7 @@
 #include "wildcard.h"
 #include "archive.h"
 #include "utils.h"
 #include "wildcard.h"
 #include "archive.h"
 #include "utils.h"
+#include "inifcns.h"
 
 namespace GiNaC {
 
 
 namespace GiNaC {
 
@@ -711,6 +712,16 @@ ex basic::conjugate() const
        return *this;
 }
 
        return *this;
 }
 
+ex basic::real_part() const
+{
+       return real_part_function(*this).hold();
+}
+
+ex basic::imag_part() const
+{
+       return imag_part_function(*this).hold();
+}
+
 ex basic::eval_ncmul(const exvector & v) const
 {
        return hold_ncmul(v);
 ex basic::eval_ncmul(const exvector & v) const
 {
        return hold_ncmul(v);
index 6b117cc9dc1b289b1cdc9cef023f696c449f2fcd..b08ad6693472859ccf1645abf889f1558b3f37d2 100644 (file)
@@ -215,8 +215,10 @@ public:
        virtual unsigned return_type() const;
        virtual tinfo_t return_type_tinfo() const;
 
        virtual unsigned return_type() const;
        virtual tinfo_t return_type_tinfo() const;
 
-       // complex conjugation
+       // functions for complex expressions
        virtual ex conjugate() const;
        virtual ex conjugate() const;
+       virtual ex real_part() const;
+       virtual ex imag_part() const;
 
        // functions that should be called from class ex only
 protected:
 
        // functions that should be called from class ex only
 protected:
index 8ae372be1965c26a8d8549cad381a74e8f853ae0..cff955a9488bcb5b09298b4dc513a656a6dc1a3e 100644 (file)
@@ -29,6 +29,7 @@
 #include "ex.h"
 #include "archive.h"
 #include "utils.h"
 #include "ex.h"
 #include "archive.h"
 #include "utils.h"
+#include "inifcns.h"
 
 namespace GiNaC {
 
 
 namespace GiNaC {
 
@@ -161,6 +162,27 @@ bool constant::is_polynomial(const ex & var) const
        return true;
 }
 
        return true;
 }
 
+ex constant::conjugate() const
+{
+       if ( domain == domain::real )
+               return *this;
+       return conjugate_function(*this).hold();
+}
+
+ex constant::real_part() const
+{
+       if ( domain == domain::real )
+               return *this;
+       return real_part_function(*this).hold();
+}
+
+ex constant::imag_part() const
+{
+       if ( domain == domain::real )
+               return 0;
+       return imag_part_function(*this).hold();
+}
+
 // protected
 
 /** Implementation of ex::diff() for a constant always returns 0.
 // protected
 
 /** Implementation of ex::diff() for a constant always returns 0.
index 4b4a5e4596d848dc64d38010d18d16b864b1ea18..5ba32987d8ba38397292a139b3341fe605f50bd9 100644 (file)
@@ -51,6 +51,9 @@ public:
        bool info(unsigned inf) const;
        ex evalf(int level = 0) const;
        bool is_polynomial(const ex & var) const;
        bool info(unsigned inf) const;
        ex evalf(int level = 0) const;
        bool is_polynomial(const ex & var) const;
+       ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
index 5774d5ace53d49ca09d6eddc308a4564e08c3f6a..28cf05e44546ee511ad8d888a2d046fb63afe634 100644 (file)
@@ -394,6 +394,28 @@ protected:
                return *this;
        }
 
                return *this;
        }
 
+       ex real_part() const
+       {
+               STLT cont;
+               reserve(cont, nops());
+               const_iterator b = begin();
+               const_iterator e = end();
+               for(const_iterator i=b; i!=e; ++i)
+                       cont.push_back(i->real_part());
+               return thiscontainer(cont);
+       }
+
+       ex imag_part() const
+       {
+               STLT cont;
+               reserve(cont, nops());
+               const_iterator b = begin();
+               const_iterator e = end();
+               for(const_iterator i=b; i!=e; ++i)
+                       cont.push_back(i->imag_part());
+               return thiscontainer(cont);
+       }
+
        bool is_equal_same_type(const basic & other) const;
 
        // new virtual functions which can be overridden by derived classes
        bool is_equal_same_type(const basic & other) const;
 
        // new virtual functions which can be overridden by derived classes
index c23336ba5fdb56b56df9400068622dc614cbec9c..030046c5c1d576612634cb4c7a2daf4be4b3181c 100644 (file)
@@ -134,8 +134,10 @@ public:
        ex lhs() const;
        ex rhs() const;
 
        ex lhs() const;
        ex rhs() const;
 
-       // complex conjugation
+       // function for complex expressions
        ex conjugate() const { return bp->conjugate(); }
        ex conjugate() const { return bp->conjugate(); }
+       ex real_part() const { return bp->real_part(); }
+       ex imag_part() const { return bp->imag_part(); }
 
        // pattern matching
        bool has(const ex & pattern, unsigned options = 0) const { return bp->has(pattern, options); }
 
        // pattern matching
        bool has(const ex & pattern, unsigned options = 0) const { return bp->has(pattern, options); }
@@ -685,6 +687,12 @@ inline ex expand(const ex & thisex, unsigned options = 0)
 inline ex conjugate(const ex & thisex)
 { return thisex.conjugate(); }
 
 inline ex conjugate(const ex & thisex)
 { return thisex.conjugate(); }
 
+inline ex real_part(const ex & thisex)
+{ return thisex.real_part(); }
+
+inline ex imag_part(const ex & thisex)
+{ return thisex.imag_part(); }
+
 inline bool has(const ex & thisex, const ex & pattern, unsigned options = 0)
 { return thisex.has(pattern, options); }
 
 inline bool has(const ex & thisex, const ex & pattern, unsigned options = 0)
 { return thisex.has(pattern, options); }
 
index e3c10f1e362797f1ff97189daaf658404de8d2f5..435434625c95cb416ba903a6d879c28779b78d2e 100755 (executable)
@@ -79,6 +79,14 @@ $typedef_conjugate_funcp=generate(
 'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n",
 'const ex &','','');
 
 'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n",
 'const ex &','','');
 
+$typedef_real_part_funcp=generate(
+'typedef ex (* real_part_funcp_${N})(${SEQ1});'."\n",
+'const ex &','','');
+
+$typedef_imag_part_funcp=generate(
+'typedef ex (* imag_part_funcp_${N})(${SEQ1});'."\n",
+'const ex &','','');
+
 $typedef_derivative_funcp=generate(
 'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n",
 'const ex &','','');
 $typedef_derivative_funcp=generate(
 'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n",
 'const ex &','','');
@@ -101,6 +109,10 @@ $evalf_func_interface=generate('    function_options & evalf_func(evalf_funcp_${
 
 $conjugate_func_interface=generate('    function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','','');
 
 
 $conjugate_func_interface=generate('    function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','','');
 
+$real_part_func_interface=generate('    function_options & real_part_func(real_part_funcp_${N} d);'."\n",'','','');
+
+$imag_part_func_interface=generate('    function_options & imag_part_func(imag_part_funcp_${N} d);'."\n",'','','');
+
 $derivative_func_interface=generate('    function_options & derivative_func(derivative_funcp_${N} d);'."\n",'','','');
 
 $power_func_interface=generate('    function_options & power_func(power_funcp_${N} d);'."\n",'','','');
 $derivative_func_interface=generate('    function_options & derivative_func(derivative_funcp_${N} d);'."\n",'','','');
 
 $power_func_interface=generate('    function_options & power_func(power_funcp_${N} d);'."\n",'','','');
@@ -149,6 +161,18 @@ $conjugate_switch_statement=generate(
                return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1});
 END_OF_DIFF_SWITCH_STATEMENT
 
                return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1});
 END_OF_DIFF_SWITCH_STATEMENT
 
+$real_part_switch_statement=generate(
+       <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
+       case ${N}:
+               return ((real_part_funcp_${N})(opt.real_part_f))(${SEQ1});
+END_OF_DIFF_SWITCH_STATEMENT
+
+$imag_part_switch_statement=generate(
+       <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
+       case ${N}:
+               return ((imag_part_funcp_${N})(opt.imag_part_f))(${SEQ1});
+END_OF_DIFF_SWITCH_STATEMENT
+
 $diff_switch_statement=generate(
        <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
        case ${N}:
 $diff_switch_statement=generate(
        <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','','');
        case ${N}:
@@ -209,6 +233,26 @@ function_options & function_options::conjugate_func(conjugate_funcp_${N} c)
 }
 END_OF_CONJUGATE_FUNC_IMPLEMENTATION
 
 }
 END_OF_CONJUGATE_FUNC_IMPLEMENTATION
 
+$real_part_func_implementation=generate(
+       <<'END_OF_REAL_PART_FUNC_IMPLEMENTATION','','','');
+function_options & function_options::real_part_func(real_part_funcp_${N} c)
+{
+       test_and_set_nparams(${N});
+       real_part_f = real_part_funcp(c);
+       return *this;
+}
+END_OF_REAL_PART_FUNC_IMPLEMENTATION
+
+$imag_part_func_implementation=generate(
+       <<'END_OF_IMAG_PART_FUNC_IMPLEMENTATION','','','');
+function_options & function_options::imag_part_func(imag_part_funcp_${N} c)
+{
+       test_and_set_nparams(${N});
+       imag_part_f = imag_part_funcp(c);
+       return *this;
+}
+END_OF_IMAG_PART_FUNC_IMPLEMENTATION
+
 $derivative_func_implementation=generate(
        <<'END_OF_DERIVATIVE_FUNC_IMPLEMENTATION','','','');
 function_options & function_options::derivative_func(derivative_funcp_${N} d)
 $derivative_func_implementation=generate(
        <<'END_OF_DERIVATIVE_FUNC_IMPLEMENTATION','','','');
 function_options & function_options::derivative_func(derivative_funcp_${N} d)
@@ -293,6 +337,8 @@ class symmetry;
 typedef ex (* eval_funcp)();
 typedef ex (* evalf_funcp)();
 typedef ex (* conjugate_funcp)();
 typedef ex (* eval_funcp)();
 typedef ex (* evalf_funcp)();
 typedef ex (* conjugate_funcp)();
+typedef ex (* real_part_funcp)();
+typedef ex (* imag_part_funcp)();
 typedef ex (* derivative_funcp)();
 typedef ex (* power_funcp)();
 typedef ex (* series_funcp)();
 typedef ex (* derivative_funcp)();
 typedef ex (* power_funcp)();
 typedef ex (* series_funcp)();
@@ -302,6 +348,8 @@ typedef void (* print_funcp)();
 $typedef_eval_funcp
 $typedef_evalf_funcp
 $typedef_conjugate_funcp
 $typedef_eval_funcp
 $typedef_evalf_funcp
 $typedef_conjugate_funcp
+$typedef_real_part_funcp
+$typedef_imag_part_funcp
 $typedef_derivative_funcp
 $typedef_power_funcp
 $typedef_series_funcp
 $typedef_derivative_funcp
 $typedef_power_funcp
 $typedef_series_funcp
@@ -313,6 +361,8 @@ $typedef_print_funcp
 typedef ex (* eval_funcp_exvector)(const exvector &);
 typedef ex (* evalf_funcp_exvector)(const exvector &);
 typedef ex (* conjugate_funcp_exvector)(const exvector &);
 typedef ex (* eval_funcp_exvector)(const exvector &);
 typedef ex (* evalf_funcp_exvector)(const exvector &);
 typedef ex (* conjugate_funcp_exvector)(const exvector &);
+typedef ex (* real_part_funcp_exvector)(const exvector &);
+typedef ex (* imag_part_funcp_exvector)(const exvector &);
 typedef ex (* derivative_funcp_exvector)(const exvector &, unsigned);
 typedef ex (* power_funcp_exvector)(const exvector &, const ex &);
 typedef ex (* series_funcp_exvector)(const exvector &, const relational &, int, unsigned);
 typedef ex (* derivative_funcp_exvector)(const exvector &, unsigned);
 typedef ex (* power_funcp_exvector)(const exvector &, const ex &);
 typedef ex (* series_funcp_exvector)(const exvector &, const relational &, int, unsigned);
@@ -337,6 +387,8 @@ public:
 $eval_func_interface
 $evalf_func_interface
 $conjugate_func_interface
 $eval_func_interface
 $evalf_func_interface
 $conjugate_func_interface
+$real_part_func_interface
+$imag_part_func_interface
 $derivative_func_interface
 $power_func_interface
 $series_func_interface
 $derivative_func_interface
 $power_func_interface
 $series_func_interface
@@ -345,6 +397,8 @@ $print_func_interface
        function_options & eval_func(eval_funcp_exvector e);
        function_options & evalf_func(evalf_funcp_exvector ef);
        function_options & conjugate_func(conjugate_funcp_exvector d);
        function_options & eval_func(eval_funcp_exvector e);
        function_options & evalf_func(evalf_funcp_exvector ef);
        function_options & conjugate_func(conjugate_funcp_exvector d);
+       function_options & real_part_func(real_part_funcp_exvector d);
+       function_options & imag_part_func(imag_part_funcp_exvector d);
        function_options & derivative_func(derivative_funcp_exvector d);
        function_options & power_func(power_funcp_exvector d);
        function_options & series_func(series_funcp_exvector s);
        function_options & derivative_func(derivative_funcp_exvector d);
        function_options & power_func(power_funcp_exvector d);
        function_options & series_func(series_funcp_exvector s);
@@ -380,6 +434,8 @@ protected:
        eval_funcp eval_f;
        evalf_funcp evalf_f;
        conjugate_funcp conjugate_f;
        eval_funcp eval_f;
        evalf_funcp evalf_f;
        conjugate_funcp conjugate_f;
+       real_part_funcp real_part_f;
+       imag_part_funcp imag_part_f;
        derivative_funcp derivative_f;
        power_funcp power_f;
        series_funcp series_f;
        derivative_funcp derivative_f;
        power_funcp power_f;
        series_funcp series_f;
@@ -399,6 +455,8 @@ protected:
        bool eval_use_exvector_args;
        bool evalf_use_exvector_args;
        bool conjugate_use_exvector_args;
        bool eval_use_exvector_args;
        bool evalf_use_exvector_args;
        bool conjugate_use_exvector_args;
+       bool real_part_use_exvector_args;
+       bool imag_part_use_exvector_args;
        bool derivative_use_exvector_args;
        bool power_use_exvector_args;
        bool series_use_exvector_args;
        bool derivative_use_exvector_args;
        bool power_use_exvector_args;
        bool series_use_exvector_args;
@@ -454,6 +512,8 @@ public:
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
        ex conjugate() const;
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
@@ -581,12 +641,15 @@ void function_options::initialize()
 {
        set_name("unnamed_function", "\\\\mbox{unnamed}");
        nparams = 0;
 {
        set_name("unnamed_function", "\\\\mbox{unnamed}");
        nparams = 0;
-       eval_f = evalf_f = conjugate_f = derivative_f = power_f = series_f = 0;
+       eval_f = evalf_f = real_part_f = imag_part_f = conjugate_f = derivative_f
+               = power_f = series_f = 0;
        evalf_params_first = true;
        use_return_type = false;
        eval_use_exvector_args = false;
        evalf_use_exvector_args = false;
        conjugate_use_exvector_args = false;
        evalf_params_first = true;
        use_return_type = false;
        eval_use_exvector_args = false;
        evalf_use_exvector_args = false;
        conjugate_use_exvector_args = false;
+       real_part_use_exvector_args = false;
+       imag_part_use_exvector_args = false;
        derivative_use_exvector_args = false;
        power_use_exvector_args = false;
        series_use_exvector_args = false;
        derivative_use_exvector_args = false;
        power_use_exvector_args = false;
        series_use_exvector_args = false;
@@ -617,6 +680,8 @@ function_options & function_options::latex_name(std::string const & tn)
 $eval_func_implementation
 $evalf_func_implementation
 $conjugate_func_implementation
 $eval_func_implementation
 $evalf_func_implementation
 $conjugate_func_implementation
+$real_part_func_implementation
+$imag_part_func_implementation
 $derivative_func_implementation
 $power_func_implementation
 $series_func_implementation
 $derivative_func_implementation
 $power_func_implementation
 $series_func_implementation
@@ -640,6 +705,19 @@ function_options& function_options::conjugate_func(conjugate_funcp_exvector c)
        conjugate_f = conjugate_funcp(c);
        return *this;
 }
        conjugate_f = conjugate_funcp(c);
        return *this;
 }
+function_options& function_options::real_part_func(real_part_funcp_exvector c)
+{
+       real_part_use_exvector_args = true;
+       real_part_f = real_part_funcp(c);
+       return *this;
+}
+function_options& function_options::imag_part_func(imag_part_funcp_exvector c)
+{
+       imag_part_use_exvector_args = true;
+       imag_part_f = imag_part_funcp(c);
+       return *this;
+}
+
 function_options& function_options::derivative_func(derivative_funcp_exvector d)
 {
        derivative_use_exvector_args = true;
 function_options& function_options::derivative_func(derivative_funcp_exvector d)
 {
        derivative_use_exvector_args = true;
@@ -1049,6 +1127,46 @@ ${conjugate_switch_statement}
        throw(std::logic_error("function::conjugate(): invalid nparams"));
 }
 
        throw(std::logic_error("function::conjugate(): invalid nparams"));
 }
 
+/** Implementation of ex::real_part for functions. */
+ex function::real_part() const
+{
+       GINAC_ASSERT(serial<registered_functions().size());
+       const function_options & opt = registered_functions()[serial];
+
+       if (opt.real_part_f==0)
+               return basic::real_part();
+
+       if (opt.real_part_use_exvector_args)
+               return ((real_part_funcp_exvector)(opt.real_part_f))(seq);
+
+       switch (opt.nparams) {
+               // the following lines have been generated for max. ${maxargs} parameters
+${real_part_switch_statement}
+               // end of generated lines
+       }
+       throw(std::logic_error("function::real_part(): invalid nparams"));
+}
+
+/** Implementation of ex::imag_part for functions. */
+ex function::imag_part() const
+{
+       GINAC_ASSERT(serial<registered_functions().size());
+       const function_options & opt = registered_functions()[serial];
+
+       if (opt.imag_part_f==0)
+               return basic::imag_part();
+
+       if (opt.imag_part_use_exvector_args)
+               return ((imag_part_funcp_exvector)(opt.imag_part_f))(seq);
+
+       switch (opt.nparams) {
+               // the following lines have been generated for max. ${maxargs} parameters
+${imag_part_switch_statement}
+               // end of generated lines
+       }
+       throw(std::logic_error("function::imag_part(): invalid nparams"));
+}
+
 // protected
 
 /** Implementation of ex::diff() for functions. It applies the chain rule,
 // protected
 
 /** Implementation of ex::diff() for functions. It applies the chain rule,
index b8b70f7e9d5ae853649c85c709fb895182aaf91d..26867dcbfc4d9f424b622741ec8bbb6d9a215eb2 100644 (file)
@@ -39,6 +39,7 @@
 #include "utils.h"
 #include "integral.h"
 #include "matrix.h"
 #include "utils.h"
 #include "integral.h"
 #include "matrix.h"
+#include "inifcns.h"
 
 namespace GiNaC {
 
 
 namespace GiNaC {
 
@@ -317,6 +318,20 @@ ex indexed::eval(int level) const
        return ex_to<basic>(base).eval_indexed(*this);
 }
 
        return ex_to<basic>(base).eval_indexed(*this);
 }
 
+ex indexed::real_part() const
+{
+       if(op(0).info(info_flags::real))
+               return *this;
+       return real_part_function(*this).hold();
+}
+
+ex indexed::imag_part() const
+{
+       if(op(0).info(info_flags::real))
+               return 0;
+       return imag_part_function(*this).hold();
+}
+
 ex indexed::thiscontainer(const exvector & v) const
 {
        return indexed(ex_to<symmetry>(symtree), v);
 ex indexed::thiscontainer(const exvector & v) const
 {
        return indexed(ex_to<symmetry>(symtree), v);
index 4ad25cb96dadf00609f9d1e11862daf735d43e0b..bbe94005672424dcb1805b0422150d9802228469 100644 (file)
@@ -147,6 +147,8 @@ public:
        unsigned precedence() const {return 55;}
        bool info(unsigned inf) const;
        ex eval(int level = 0) const;
        unsigned precedence() const {return 55;}
        bool info(unsigned inf) const;
        ex eval(int level = 0) const;
+       ex real_part() const;
+       ex imag_part() const;
        exvector get_free_indices() const;
 
 protected:
        exvector get_free_indices() const;
 
 protected:
index a8f82d8ea0413efaa02e63ea29d9a9919759f793..c49fc7021aa5694c1862d8ff743ac9f7936b60e6 100644 (file)
@@ -66,12 +66,114 @@ static ex conjugate_conjugate(const ex & arg)
        return arg;
 }
 
        return arg;
 }
 
+static ex conjugate_real_part(const ex & arg)
+{
+       return arg.real_part();
+}
+
+static ex conjugate_imag_part(const ex & arg)
+{
+       return -arg.imag_part();
+}
+
 REGISTER_FUNCTION(conjugate_function, eval_func(conjugate_eval).
                                       evalf_func(conjugate_evalf).
                                       print_func<print_latex>(conjugate_print_latex).
                                       conjugate_func(conjugate_conjugate).
 REGISTER_FUNCTION(conjugate_function, eval_func(conjugate_eval).
                                       evalf_func(conjugate_evalf).
                                       print_func<print_latex>(conjugate_print_latex).
                                       conjugate_func(conjugate_conjugate).
+                                      real_part_func(conjugate_real_part).
+                                      imag_part_func(conjugate_imag_part).
                                       set_name("conjugate","conjugate"));
 
                                       set_name("conjugate","conjugate"));
 
+//////////
+// real part
+//////////
+
+static ex real_part_evalf(const ex & arg)
+{
+       if (is_exactly_a<numeric>(arg)) {
+               return ex_to<numeric>(arg).real();
+       }
+       return real_part_function(arg).hold();
+}
+
+static ex real_part_eval(const ex & arg)
+{
+       return arg.real_part();
+}
+
+static void real_part_print_latex(const ex & arg, const print_context & c)
+{
+       c.s << "\\Re"; arg.print(c); c.s << "";
+}
+
+static ex real_part_conjugate(const ex & arg)
+{
+       return real_part_function(arg).hold();
+}
+
+static ex real_part_real_part(const ex & arg)
+{
+       return real_part_function(arg).hold();
+}
+
+static ex real_part_imag_part(const ex & arg)
+{
+       return 0;
+}
+
+REGISTER_FUNCTION(real_part_function, eval_func(real_part_eval).
+                                      evalf_func(real_part_evalf).
+                                      print_func<print_latex>(real_part_print_latex).
+                                      conjugate_func(real_part_conjugate).
+                                      real_part_func(real_part_real_part).
+                                      imag_part_func(real_part_imag_part).
+                                      set_name("real_part","real_part"));
+
+//////////
+// imag part
+//////////
+
+static ex imag_part_evalf(const ex & arg)
+{
+       if (is_exactly_a<numeric>(arg)) {
+               return ex_to<numeric>(arg).imag();
+       }
+       return imag_part_function(arg).hold();
+}
+
+static ex imag_part_eval(const ex & arg)
+{
+       return arg.imag_part();
+}
+
+static void imag_part_print_latex(const ex & arg, const print_context & c)
+{
+       c.s << "\\Im"; arg.print(c); c.s << "";
+}
+
+static ex imag_part_conjugate(const ex & arg)
+{
+       return imag_part_function(arg).hold();
+}
+
+static ex imag_part_real_part(const ex & arg)
+{
+       return imag_part_function(arg).hold();
+}
+
+static ex imag_part_imag_part(const ex & arg)
+{
+       return 0;
+}
+
+REGISTER_FUNCTION(imag_part_function, eval_func(imag_part_eval).
+                                      evalf_func(imag_part_evalf).
+                                      print_func<print_latex>(imag_part_print_latex).
+                                      conjugate_func(imag_part_conjugate).
+                                      real_part_func(imag_part_real_part).
+                                      imag_part_func(imag_part_imag_part).
+                                      set_name("imag_part","imag_part"));
+
 //////////
 // absolute value
 //////////
 //////////
 // absolute value
 //////////
@@ -107,6 +209,16 @@ static ex abs_conjugate(const ex & arg)
        return abs(arg);
 }
 
        return abs(arg);
 }
 
+static ex abs_real_part(const ex & arg)
+{
+       return abs(arg).hold();
+}
+
+static ex abs_imag_part(const ex& arg)
+{
+       return 0;
+}
+
 static ex abs_power(const ex & arg, const ex & exp)
 {
        if (arg.is_equal(arg.conjugate()) && is_a<numeric>(exp) && ex_to<numeric>(exp).is_even())
 static ex abs_power(const ex & arg, const ex & exp)
 {
        if (arg.is_equal(arg.conjugate()) && is_a<numeric>(exp) && ex_to<numeric>(exp).is_even())
@@ -121,6 +233,8 @@ REGISTER_FUNCTION(abs, eval_func(abs_eval).
                        print_func<print_csrc_float>(abs_print_csrc_float).
                        print_func<print_csrc_double>(abs_print_csrc_float).
                        conjugate_func(abs_conjugate).
                        print_func<print_csrc_float>(abs_print_csrc_float).
                        print_func<print_csrc_double>(abs_print_csrc_float).
                        conjugate_func(abs_conjugate).
+                       real_part_func(abs_real_part).
+                       imag_part_func(abs_imag_part).
                        power_func(abs_power));
 
 //////////
                        power_func(abs_power));
 
 //////////
@@ -182,13 +296,25 @@ static ex step_series(const ex & arg,
 
 static ex step_conjugate(const ex& arg)
 {
 
 static ex step_conjugate(const ex& arg)
 {
-       return step(arg);
+       return step(arg).hold();
+}
+
+static ex step_real_part(const ex& arg)
+{
+       return step(arg).hold();
+}
+
+static ex step_imag_part(const ex& arg)
+{
+       return 0;
 }
 
 REGISTER_FUNCTION(step, eval_func(step_eval).
                         evalf_func(step_evalf).
                         series_func(step_series).
 }
 
 REGISTER_FUNCTION(step, eval_func(step_eval).
                         evalf_func(step_evalf).
                         series_func(step_series).
-                        conjugate_func(step_conjugate));
+                        conjugate_func(step_conjugate).
+                                                               real_part_func(step_real_part).
+                                                               imag_part_func(step_imag_part));
 
 //////////
 // Complex sign
 
 //////////
 // Complex sign
@@ -249,7 +375,17 @@ static ex csgn_series(const ex & arg,
 
 static ex csgn_conjugate(const ex& arg)
 {
 
 static ex csgn_conjugate(const ex& arg)
 {
-       return csgn(arg);
+       return csgn(arg).hold();
+}
+
+static ex csgn_real_part(const ex& arg)
+{
+       return csgn(arg).hold();
+}
+
+static ex csgn_imag_part(const ex& arg)
+{
+       return 0;
 }
 
 static ex csgn_power(const ex & arg, const ex & exp)
 }
 
 static ex csgn_power(const ex & arg, const ex & exp)
@@ -268,6 +404,8 @@ REGISTER_FUNCTION(csgn, eval_func(csgn_eval).
                         evalf_func(csgn_evalf).
                         series_func(csgn_series).
                         conjugate_func(csgn_conjugate).
                         evalf_func(csgn_evalf).
                         series_func(csgn_series).
                         conjugate_func(csgn_conjugate).
+                        real_part_func(csgn_real_part).
+                        imag_part_func(csgn_imag_part).
                         power_func(csgn_power));
 
 
                         power_func(csgn_power));
 
 
@@ -345,7 +483,17 @@ static ex eta_series(const ex & x, const ex & y,
 
 static ex eta_conjugate(const ex & x, const ex & y)
 {
 
 static ex eta_conjugate(const ex & x, const ex & y)
 {
-       return -eta(x,y);
+       return -eta(x, y);
+}
+
+static ex eta_real_part(const ex & x, const ex & y)
+{
+       return 0;
+}
+
+static ex eta_imag_part(const ex & x, const ex & y)
+{
+       return -I*eta(x, y).hold();
 }
 
 REGISTER_FUNCTION(eta, eval_func(eta_eval).
 }
 
 REGISTER_FUNCTION(eta, eval_func(eta_eval).
@@ -353,7 +501,9 @@ REGISTER_FUNCTION(eta, eval_func(eta_eval).
                        series_func(eta_series).
                        latex_name("\\eta").
                        set_symmetry(sy_symm(0, 1)).
                        series_func(eta_series).
                        latex_name("\\eta").
                        set_symmetry(sy_symm(0, 1)).
-                       conjugate_func(eta_conjugate));
+                       conjugate_func(eta_conjugate).
+                       real_part_func(eta_real_part).
+                       imag_part_func(eta_imag_part));
 
 
 //////////
 
 
 //////////
@@ -568,14 +718,26 @@ static void factorial_print_dflt_latex(const ex & x, const print_context & c)
 
 static ex factorial_conjugate(const ex & x)
 {
 
 static ex factorial_conjugate(const ex & x)
 {
-       return factorial(x);
+       return factorial(x).hold();
+}
+
+static ex factorial_real_part(const ex & x)
+{
+       return factorial(x).hold();
+}
+
+static ex factorial_imag_part(const ex & x)
+{
+       return 0;
 }
 
 REGISTER_FUNCTION(factorial, eval_func(factorial_eval).
                              evalf_func(factorial_evalf).
                              print_func<print_dflt>(factorial_print_dflt_latex).
                              print_func<print_latex>(factorial_print_dflt_latex).
 }
 
 REGISTER_FUNCTION(factorial, eval_func(factorial_eval).
                              evalf_func(factorial_evalf).
                              print_func<print_dflt>(factorial_print_dflt_latex).
                              print_func<print_latex>(factorial_print_dflt_latex).
-                             conjugate_func(factorial_conjugate));
+                             conjugate_func(factorial_conjugate).
+                             real_part_func(factorial_real_part).
+                             imag_part_func(factorial_imag_part));
 
 //////////
 // binomial
 
 //////////
 // binomial
@@ -620,12 +782,24 @@ static ex binomial_eval(const ex & x, const ex &y)
 // function, also complex conjugation should be changed (or rather, deleted).
 static ex binomial_conjugate(const ex & x, const ex & y)
 {
 // function, also complex conjugation should be changed (or rather, deleted).
 static ex binomial_conjugate(const ex & x, const ex & y)
 {
-       return binomial(x,y);
+       return binomial(x,y).hold();
+}
+
+static ex binomial_real_part(const ex & x, const ex & y)
+{
+       return binomial(x,y).hold();
+}
+
+static ex binomial_imag_part(const ex & x, const ex & y)
+{
+       return 0;
 }
 
 REGISTER_FUNCTION(binomial, eval_func(binomial_eval).
                             evalf_func(binomial_evalf).
 }
 
 REGISTER_FUNCTION(binomial, eval_func(binomial_eval).
                             evalf_func(binomial_evalf).
-                            conjugate_func(binomial_conjugate));
+                            conjugate_func(binomial_conjugate).
+                            real_part_func(binomial_real_part).
+                            imag_part_func(binomial_imag_part));
 
 //////////
 // Order term function (for truncated power series)
 
 //////////
 // Order term function (for truncated power series)
@@ -660,7 +834,19 @@ static ex Order_series(const ex & x, const relational & r, int order, unsigned o
 
 static ex Order_conjugate(const ex & x)
 {
 
 static ex Order_conjugate(const ex & x)
 {
-       return Order(x);
+       return Order(x).hold();
+}
+
+static ex Order_real_part(const ex & x)
+{
+       return Order(x).hold();
+}
+
+static ex Order_imag_part(const ex & x)
+{
+       if(x.info(info_flags::real))
+               return 0;
+       return Order(x).hold();
 }
 
 // Differentiation is handled in function::derivative because of its special requirements
 }
 
 // Differentiation is handled in function::derivative because of its special requirements
@@ -668,7 +854,9 @@ static ex Order_conjugate(const ex & x)
 REGISTER_FUNCTION(Order, eval_func(Order_eval).
                          series_func(Order_series).
                          latex_name("\\mathcal{O}").
 REGISTER_FUNCTION(Order, eval_func(Order_eval).
                          series_func(Order_series).
                          latex_name("\\mathcal{O}").
-                         conjugate_func(Order_conjugate));
+                         conjugate_func(Order_conjugate).
+                         real_part_func(Order_real_part).
+                         imag_part_func(Order_imag_part));
 
 //////////
 // Solve linear system
 
 //////////
 // Solve linear system
index 0e13a040f1b42d85644e4525fd227ca11eda9c4c..af5516db58057e3efa2dd7b0e1314c3d3a51008f 100644 (file)
@@ -31,13 +31,19 @@ namespace GiNaC {
 
 /** Complex conjugate. */
 DECLARE_FUNCTION_1P(conjugate_function)
 
 /** Complex conjugate. */
 DECLARE_FUNCTION_1P(conjugate_function)
+
+/** Real part. */
+DECLARE_FUNCTION_1P(real_part_function)
+
+/** Imaginary part. */
+DECLARE_FUNCTION_1P(imag_part_function)
        
 /** Absolute value. */
 DECLARE_FUNCTION_1P(abs)
        
 /** Step function. */
 DECLARE_FUNCTION_1P(step)
        
 /** Absolute value. */
 DECLARE_FUNCTION_1P(abs)
        
 /** Step function. */
 DECLARE_FUNCTION_1P(step)
-
+       
 /** Complex sign. */
 DECLARE_FUNCTION_1P(csgn)
 
 /** Complex sign. */
 DECLARE_FUNCTION_1P(csgn)
 
index 364ec55e2bfce859fab2e1ade21eadb3346205e3..3f9c380b6dd51fe60708a275175f1831a63c1787 100644 (file)
@@ -89,9 +89,21 @@ static ex exp_deriv(const ex & x, unsigned deriv_param)
        return exp(x);
 }
 
        return exp(x);
 }
 
+static ex exp_real_part(const ex & x)
+{
+       return exp(GiNaC::real_part(x))*cos(GiNaC::imag_part(x));
+}
+
+static ex exp_imag_part(const ex & x)
+{
+       return exp(GiNaC::real_part(x))*sin(GiNaC::imag_part(x));
+}
+
 REGISTER_FUNCTION(exp, eval_func(exp_eval).
                        evalf_func(exp_evalf).
                        derivative_func(exp_deriv).
 REGISTER_FUNCTION(exp, eval_func(exp_eval).
                        evalf_func(exp_evalf).
                        derivative_func(exp_deriv).
+                       real_part_func(exp_real_part).
+                       imag_part_func(exp_imag_part).
                        latex_name("\\exp"));
 
 //////////
                        latex_name("\\exp"));
 
 //////////
@@ -232,10 +244,22 @@ static ex log_series(const ex &arg,
        throw do_taylor();  // caught by function::series()
 }
 
        throw do_taylor();  // caught by function::series()
 }
 
+static ex log_real_part(const ex & x)
+{
+       return log(abs(x));
+}
+
+static ex log_imag_part(const ex & x)
+{
+       return atan2(GiNaC::imag_part(x), GiNaC::real_part(x));
+}
+
 REGISTER_FUNCTION(log, eval_func(log_eval).
                        evalf_func(log_evalf).
                        derivative_func(log_deriv).
                        series_func(log_series).
 REGISTER_FUNCTION(log, eval_func(log_eval).
                        evalf_func(log_evalf).
                        derivative_func(log_deriv).
                        series_func(log_series).
+                       real_part_func(log_real_part).
+                       imag_part_func(log_imag_part).
                        latex_name("\\ln"));
 
 //////////
                        latex_name("\\ln"));
 
 //////////
@@ -321,9 +345,21 @@ static ex sin_deriv(const ex & x, unsigned deriv_param)
        return cos(x);
 }
 
        return cos(x);
 }
 
+static ex sin_real_part(const ex & x)
+{
+       return cosh(GiNaC::imag_part(x))*sin(GiNaC::real_part(x));
+}
+
+static ex sin_imag_part(const ex & x)
+{
+       return sinh(GiNaC::imag_part(x))*cos(GiNaC::real_part(x));
+}
+
 REGISTER_FUNCTION(sin, eval_func(sin_eval).
                        evalf_func(sin_evalf).
                        derivative_func(sin_deriv).
 REGISTER_FUNCTION(sin, eval_func(sin_eval).
                        evalf_func(sin_evalf).
                        derivative_func(sin_deriv).
+                       real_part_func(sin_real_part).
+                       imag_part_func(sin_imag_part).
                        latex_name("\\sin"));
 
 //////////
                        latex_name("\\sin"));
 
 //////////
@@ -409,9 +445,21 @@ static ex cos_deriv(const ex & x, unsigned deriv_param)
        return -sin(x);
 }
 
        return -sin(x);
 }
 
+static ex cos_real_part(const ex & x)
+{
+       return cosh(GiNaC::imag_part(x))*cos(GiNaC::real_part(x));
+}
+
+static ex cos_imag_part(const ex & x)
+{
+       return -sinh(GiNaC::imag_part(x))*sin(GiNaC::real_part(x));
+}
+
 REGISTER_FUNCTION(cos, eval_func(cos_eval).
                        evalf_func(cos_evalf).
                        derivative_func(cos_deriv).
 REGISTER_FUNCTION(cos, eval_func(cos_eval).
                        evalf_func(cos_evalf).
                        derivative_func(cos_deriv).
+                       real_part_func(cos_real_part).
+                       imag_part_func(cos_imag_part).
                        latex_name("\\cos"));
 
 //////////
                        latex_name("\\cos"));
 
 //////////
@@ -494,6 +542,20 @@ static ex tan_deriv(const ex & x, unsigned deriv_param)
        return (_ex1+power(tan(x),_ex2));
 }
 
        return (_ex1+power(tan(x),_ex2));
 }
 
+static ex tan_real_part(const ex & x)
+{
+       ex a = GiNaC::real_part(x);
+       ex b = GiNaC::imag_part(x);
+       return tan(a)/(1+power(tan(a),2)*power(tan(b),2));
+}
+
+static ex tan_imag_part(const ex & x)
+{
+       ex a = GiNaC::real_part(x);
+       ex b = GiNaC::imag_part(x);
+       return tanh(b)/(1+power(tan(a),2)*power(tan(b),2));
+}
+
 static ex tan_series(const ex &x,
                      const relational &rel,
                      int order,
 static ex tan_series(const ex &x,
                      const relational &rel,
                      int order,
@@ -514,6 +576,8 @@ REGISTER_FUNCTION(tan, eval_func(tan_eval).
                        evalf_func(tan_evalf).
                        derivative_func(tan_deriv).
                        series_func(tan_series).
                        evalf_func(tan_evalf).
                        derivative_func(tan_deriv).
                        series_func(tan_series).
+                       real_part_func(tan_real_part).
+                       imag_part_func(tan_imag_part).
                        latex_name("\\tan"));
 
 //////////
                        latex_name("\\tan"));
 
 //////////
@@ -896,9 +960,21 @@ static ex sinh_deriv(const ex & x, unsigned deriv_param)
        return cosh(x);
 }
 
        return cosh(x);
 }
 
+static ex sinh_real_part(const ex & x)
+{
+       return sinh(GiNaC::real_part(x))*cos(GiNaC::imag_part(x));
+}
+
+static ex sinh_imag_part(const ex & x)
+{
+       return cosh(GiNaC::real_part(x))*sin(GiNaC::imag_part(x));
+}
+
 REGISTER_FUNCTION(sinh, eval_func(sinh_eval).
                         evalf_func(sinh_evalf).
                         derivative_func(sinh_deriv).
 REGISTER_FUNCTION(sinh, eval_func(sinh_eval).
                         evalf_func(sinh_evalf).
                         derivative_func(sinh_deriv).
+                        real_part_func(sinh_real_part).
+                        imag_part_func(sinh_imag_part).
                         latex_name("\\sinh"));
 
 //////////
                         latex_name("\\sinh"));
 
 //////////
@@ -961,9 +1037,21 @@ static ex cosh_deriv(const ex & x, unsigned deriv_param)
        return sinh(x);
 }
 
        return sinh(x);
 }
 
+static ex cosh_real_part(const ex & x)
+{
+       return cosh(GiNaC::real_part(x))*cos(GiNaC::imag_part(x));
+}
+
+static ex cosh_imag_part(const ex & x)
+{
+       return sinh(GiNaC::real_part(x))*sin(GiNaC::imag_part(x));
+}
+
 REGISTER_FUNCTION(cosh, eval_func(cosh_eval).
                         evalf_func(cosh_evalf).
                         derivative_func(cosh_deriv).
 REGISTER_FUNCTION(cosh, eval_func(cosh_eval).
                         evalf_func(cosh_evalf).
                         derivative_func(cosh_deriv).
+                        real_part_func(cosh_real_part).
+                        imag_part_func(cosh_imag_part).
                         latex_name("\\cosh"));
 
 //////////
                         latex_name("\\cosh"));
 
 //////////
@@ -1042,10 +1130,26 @@ static ex tanh_series(const ex &x,
        return (sinh(x)/cosh(x)).series(rel, order, options);
 }
 
        return (sinh(x)/cosh(x)).series(rel, order, options);
 }
 
+static ex tanh_real_part(const ex & x)
+{
+       ex a = GiNaC::real_part(x);
+       ex b = GiNaC::imag_part(x);
+       return tanh(a)/(1+power(tanh(a),2)*power(tan(b),2));
+}
+
+static ex tanh_imag_part(const ex & x)
+{
+       ex a = GiNaC::real_part(x);
+       ex b = GiNaC::imag_part(x);
+       return tan(b)/(1+power(tanh(a),2)*power(tan(b),2));
+}
+
 REGISTER_FUNCTION(tanh, eval_func(tanh_eval).
                         evalf_func(tanh_evalf).
                         derivative_func(tanh_deriv).
                         series_func(tanh_series).
 REGISTER_FUNCTION(tanh, eval_func(tanh_eval).
                         evalf_func(tanh_evalf).
                         derivative_func(tanh_deriv).
                         series_func(tanh_series).
+                        real_part_func(tanh_real_part).
+                        imag_part_func(tanh_imag_part).
                         latex_name("\\tanh"));
 
 //////////
                         latex_name("\\tanh"));
 
 //////////
index f62e2d409244d8a50d44890b8eae74f8ac5e4eb1..3f3b2e6fa93b34edaca43a427d94487db91bcd12 100644 (file)
@@ -262,6 +262,24 @@ ex matrix::conjugate() const
        return *this;
 }
 
        return *this;
 }
 
+ex matrix::real_part() const
+{
+       exvector v;
+       v.reserve(m.size());
+       for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i)
+               v.push_back(i->real_part());
+       return matrix(row, col, v);
+}
+
+ex matrix::imag_part() const
+{
+       exvector v;
+       v.reserve(m.size());
+       for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i)
+               v.push_back(i->imag_part());
+       return matrix(row, col, v);
+}
+
 // protected
 
 int matrix::compare_same_type(const basic & other) const
 // protected
 
 int matrix::compare_same_type(const basic & other) const
index a1ac7cbcb968883c19c68620bc73e7392d406e93..08c9fe8888f547bb750e5383b88e4d4021299004 100644 (file)
@@ -121,6 +121,8 @@ public:
        ex scalar_mul_indexed(const ex & self, const numeric & other) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
        ex conjugate() const;
        ex scalar_mul_indexed(const ex & self, const numeric & other) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 
 protected:
        bool match_same_type(const basic & other) const;
 
 protected:
        bool match_same_type(const basic & other) const;
index dd929f7e136ffc90546550ee57e87dfdb5069dab..d2dd675cfa08b9af4265a599e8011b99c06e14d8 100644 (file)
@@ -461,6 +461,41 @@ ex mul::evalf(int level) const
        return mul(s, overall_coeff.evalf(level));
 }
 
        return mul(s, overall_coeff.evalf(level));
 }
 
+void mul::find_real_imag(ex & rp, ex & ip) const
+{
+       rp = overall_coeff.real_part();
+       ip = overall_coeff.imag_part();
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+               ex factor = recombine_pair_to_ex(*i);
+               ex new_rp = factor.real_part();
+               ex new_ip = factor.imag_part();
+               if(new_ip.is_zero()) {
+                       rp *= new_rp;
+                       ip *= new_rp;
+               } else {
+                       ex temp = rp*new_rp - ip*new_ip;
+                       ip = ip*new_rp + rp*new_ip;
+                       rp = temp;
+               }
+       }
+       rp = rp.expand();
+       ip = ip.expand();
+}
+
+ex mul::real_part() const
+{
+       ex rp, ip;
+       find_real_imag(rp, ip);
+       return rp;
+}
+
+ex mul::imag_part() const
+{
+       ex rp, ip;
+       find_real_imag(rp, ip);
+       return ip;
+}
+
 ex mul::evalm() const
 {
        // numeric*matrix
 ex mul::evalm() const
 {
        // numeric*matrix
index 7730bad07deb6ed8fb90eb8ab6b12a4d1f67d7b6..d9023c2f30755d2374e621d24f2f3a03864ecce8 100644 (file)
@@ -55,6 +55,8 @@ public:
        bool has(const ex & other, unsigned options = 0) const;
        ex eval(int level=0) const;
        ex evalf(int level=0) const;
        bool has(const ex & other, unsigned options = 0) const;
        ex eval(int level=0) const;
        ex evalf(int level=0) const;
+       ex real_part() const;
+       ex imag_part() const;
        ex evalm() const;
        ex series(const relational & s, int order, unsigned options = 0) const;
        ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const;
        ex evalm() const;
        ex series(const relational & s, int order, unsigned options = 0) const;
        ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const;
@@ -79,6 +81,7 @@ protected:
        void combine_overall_coeff(const ex & c1, const ex & c2);
        bool can_make_flat(const expair & p) const;
        ex expand(unsigned options=0) const;
        void combine_overall_coeff(const ex & c1, const ex & c2);
        bool can_make_flat(const expair & p) const;
        ex expand(unsigned options=0) const;
+       void find_real_imag(ex&, ex&) const;
        
        // new virtual functions which can be overridden by derived classes
        // none
        
        // new virtual functions which can be overridden by derived classes
        // none
index 81d0653e4fbb751bc4d4a8897f6523f296a950e5..21f7730c841fe13ce9b41083058ced5e7b68d6f3 100644 (file)
@@ -508,6 +508,16 @@ ex ncmul::conjugate() const
        return (new ncmul(ev, true))->setflag(status_flags::dynallocated).eval();
 }
 
        return (new ncmul(ev, true))->setflag(status_flags::dynallocated).eval();
 }
 
+ex ncmul::real_part() const
+{
+       return basic::real_part();
+}
+
+ex ncmul::imag_part() const
+{
+       return basic::imag_part();
+}
+
 // protected
 
 /** Implementation of ex::diff() for a non-commutative product. It applies
 // protected
 
 /** Implementation of ex::diff() for a non-commutative product. It applies
index cc156d54a480af65b0816bcd0825052ede4ce287..d6fb40d1622fcd830e9db2cf391e27c97a4d740b 100644 (file)
@@ -65,6 +65,8 @@ public:
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
        ex conjugate() const;
        ex thiscontainer(const exvector & v) const;
        ex thiscontainer(std::auto_ptr<exvector> vp) const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 
 protected:
        ex derivative(const symbol & s) const;
 
 protected:
        ex derivative(const symbol & s) const;
index 278741f1e43aec63aa875dd56dd8092687ff58b6..cc72565a22b460b6c1a292e1091219d7dabb5057 100644 (file)
@@ -687,6 +687,16 @@ ex numeric::conjugate() const
        return numeric(cln::conjugate(this->value));
 }
 
        return numeric(cln::conjugate(this->value));
 }
 
+ex numeric::real_part() const
+{
+       return numeric(cln::realpart(value));
+}
+
+ex numeric::imag_part() const
+{
+       return numeric(cln::imagpart(value));
+}
+
 // protected
 
 int numeric::compare_same_type(const basic &other) const
 // protected
 
 int numeric::compare_same_type(const basic &other) const
index ff460638e0ed3c402b3499040200d534880e4d89..09603f660d33f1542995733b05dbdb96de4fc973 100644 (file)
@@ -120,6 +120,8 @@ public:
        ex smod(const numeric &xi) const;
        numeric max_coefficient() const;
        ex conjugate() const;
        ex smod(const numeric &xi) const;
        numeric max_coefficient() const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 protected:
        /** Implementation of ex::diff for a numeric always returns 0.
         *  @see ex::diff */
 protected:
        /** Implementation of ex::diff for a numeric always returns 0.
         *  @see ex::diff */
index 0ebc8dc29a20db47796cde8ab228eb293c76d3da..75fd2ff51a9d12bd09d867d30fdf50b860ec6240 100644 (file)
@@ -40,6 +40,7 @@
 #include "lst.h"
 #include "archive.h"
 #include "utils.h"
 #include "lst.h"
 #include "archive.h"
 #include "utils.h"
+#include "relational.h"
 
 namespace GiNaC {
 
 
 namespace GiNaC {
 
@@ -614,6 +615,59 @@ ex power::conjugate() const
        return (new power(newbasis, newexponent))->setflag(status_flags::dynallocated);
 }
 
        return (new power(newbasis, newexponent))->setflag(status_flags::dynallocated);
 }
 
+ex power::real_part() const
+{
+       if (exponent.info(info_flags::integer)) {
+               ex basis_real = basis.real_part();
+               if (basis_real == basis)
+                       return *this;
+               realsymbol a("a"),b("b");
+               ex result;
+               if (exponent.info(info_flags::posint))
+                       result = power(a+I*b,exponent);
+               else
+                       result = power(a/(a*a+b*b)-I*b/(a*a+b*b),-exponent);
+               result = result.expand();
+               result = result.real_part();
+               result = result.subs(lst( a==basis_real, b==basis.imag_part() ));
+               return result;
+       }
+       
+       ex a = basis.real_part();
+       ex b = basis.imag_part();
+       ex c = exponent.real_part();
+       ex d = exponent.imag_part();
+       return power(abs(basis),c)*exp(-d*atan2(b,a))*cos(c*atan2(b,a)+d*log(abs(basis)));
+}
+
+ex power::imag_part() const
+{
+       if (exponent.info(info_flags::integer)) {
+               ex basis_real = basis.real_part();
+               if (basis_real == basis)
+                       return 0;
+               realsymbol a("a"),b("b");
+               ex result;
+               if (exponent.info(info_flags::posint))
+                       result = power(a+I*b,exponent);
+               else
+                       result = power(a/(a*a+b*b)-I*b/(a*a+b*b),-exponent);
+               result = result.expand();
+               result = result.imag_part();
+               result = result.subs(lst( a==basis_real, b==basis.imag_part() ));
+               return result;
+       }
+       
+       ex a=basis.real_part();
+       ex b=basis.imag_part();
+       ex c=exponent.real_part();
+       ex d=exponent.imag_part();
+       return
+               power(abs(basis),c)*exp(-d*atan2(b,a))*sin(c*atan2(b,a)+d*log(abs(basis)));
+}
+
+// protected
+
 // protected
 
 /** Implementation of ex::diff() for a power.
 // protected
 
 /** Implementation of ex::diff() for a power.
index c76452476bbedc29f8b4fc32ed78cc554ecc6666..ad2b4af9a66f70228d249287518f38b23e4afade 100644 (file)
@@ -68,6 +68,8 @@ public:
        ex to_rational(exmap & repl) const;
        ex to_polynomial(exmap & repl) const;
        ex conjugate() const;
        ex to_rational(exmap & repl) const;
        ex to_polynomial(exmap & repl) const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
 protected:
        ex derivative(const symbol & s) const;
        ex eval_ncmul(const exvector & v) const;
 protected:
        ex derivative(const symbol & s) const;
        ex eval_ncmul(const exvector & v) const;
index 41ec9036c00dc78559bff80e1f730032e434c634..14488ba71c222b81e033379d51f61be66e94b062 100644 (file)
@@ -412,21 +412,53 @@ ex pseries::evalf(int level) const
 
 ex pseries::conjugate() const
 {
 
 ex pseries::conjugate() const
 {
+       if(!var.info(info_flags::real))
+               return conjugate_function(*this).hold();
+
        epvector * newseq = conjugateepvector(seq);
        epvector * newseq = conjugateepvector(seq);
-       ex newvar = var.conjugate();
        ex newpoint = point.conjugate();
 
        ex newpoint = point.conjugate();
 
-       if (!newseq     && are_ex_trivially_equal(newvar, var) && are_ex_trivially_equal(point, newpoint)) {
+       if (!newseq     && are_ex_trivially_equal(point, newpoint)) {
                return *this;
        }
 
                return *this;
        }
 
-       ex result = (new pseries(newvar==newpoint, newseq ? *newseq : seq))->setflag(status_flags::dynallocated);
+       ex result = (new pseries(var==newpoint, newseq ? *newseq : seq))->setflag(status_flags::dynallocated);
        if (newseq) {
                delete newseq;
        }
        return result;
 }
 
        if (newseq) {
                delete newseq;
        }
        return result;
 }
 
+ex pseries::real_part() const
+{
+       if(!var.info(info_flags::real))
+               return real_part_function(*this).hold();
+       ex newpoint = point.real_part();
+       if(newpoint != point)
+               return real_part_function(*this).hold();
+
+       epvector v;
+       v.reserve(seq.size());
+       for(epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+               v.push_back(expair((i->rest).real_part(), i->coeff));
+       return (new pseries(var==point, v))->setflag(status_flags::dynallocated);
+}
+
+ex pseries::imag_part() const
+{
+       if(!var.info(info_flags::real))
+               return imag_part_function(*this).hold();
+       ex newpoint = point.real_part();
+       if(newpoint != point)
+               return imag_part_function(*this).hold();
+
+       epvector v;
+       v.reserve(seq.size());
+       for(epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+               v.push_back(expair((i->rest).imag_part(), i->coeff));
+       return (new pseries(var==point, v))->setflag(status_flags::dynallocated);
+}
+
 ex pseries::eval_integ() const
 {
        epvector *newseq = NULL;
 ex pseries::eval_integ() const
 {
        epvector *newseq = NULL;
index fe88508cd7668e928c39a817b94d446edcb05739..0d1813aa315f11bf3cb8d1385d26155ed3c416b6 100644 (file)
@@ -56,6 +56,8 @@ public:
        ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const;
        ex expand(unsigned options = 0) const;
        ex conjugate() const;
        ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const;
        ex expand(unsigned options = 0) const;
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
        ex eval_integ() const;
 protected:
        ex derivative(const symbol & s) const;
        ex eval_integ() const;
 protected:
        ex derivative(const symbol & s) const;
index 10b38a8eb71f8750e4671a2742db328bf9d62da8..59dda652a133f3e71b0c0930696beb41139947d1 100644 (file)
@@ -220,12 +220,26 @@ ex symbol::eval(int level) const
 ex symbol::conjugate() const
 {
        if (this->domain == domain::complex) {
 ex symbol::conjugate() const
 {
        if (this->domain == domain::complex) {
-               return GiNaC::conjugate_function(*this).hold();
+               return conjugate_function(*this).hold();
        } else {
                return *this;
        }
 }
 
        } else {
                return *this;
        }
 }
 
+ex symbol::real_part() const
+{
+       if (domain == domain::real)
+               return *this;
+       return real_part_function(*this).hold();
+}
+
+ex symbol::imag_part() const
+{
+       if (domain == domain::real)
+               return 0;
+       return imag_part_function(*this).hold();
+}
+
 bool symbol::is_polynomial(const ex & var) const
 {
        return true;
 bool symbol::is_polynomial(const ex & var) const
 {
        return true;
index b7c17a8000ecd3eff0b271eae6a3b1ce60bac524..9c7e526d6dca881b89c35a49e39fff2feb89c27b 100644 (file)
@@ -75,6 +75,8 @@ public:
        unsigned return_type() const { return ret_type; }
        tinfo_t return_type_tinfo() const { return ret_type_tinfo; }
        ex conjugate() const;
        unsigned return_type() const { return ret_type; }
        tinfo_t return_type_tinfo() const { return ret_type_tinfo; }
        ex conjugate() const;
+       ex real_part() const;
+       ex imag_part() const;
        bool is_polynomial(const ex & var) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_polynomial(const ex & var) const;
 protected:
        ex derivative(const symbol & s) const;
index 5b43e65a350de329daaaafcb2f33ee822bbc48cd..c215237d85f9d1225913b7fff4f87e59e0bc8134 100644 (file)
@@ -141,6 +141,22 @@ DEFAULT_COMPARE(tensdelta)
 DEFAULT_COMPARE(tensmetric)
 DEFAULT_COMPARE(spinmetric)
 
 DEFAULT_COMPARE(tensmetric)
 DEFAULT_COMPARE(spinmetric)
 
+bool tensdelta::info(unsigned inf) const
+{
+       if(inf == info_flags::real)
+               return true;
+
+       return false;
+}
+
+bool tensmetric::info(unsigned inf) const
+{
+       if(inf == info_flags::real)
+               return true;
+
+       return false;
+}
+
 int minkmetric::compare_same_type(const basic & other) const
 {
        GINAC_ASSERT(is_a<minkmetric>(other));
 int minkmetric::compare_same_type(const basic & other) const
 {
        GINAC_ASSERT(is_a<minkmetric>(other));
@@ -152,6 +168,14 @@ int minkmetric::compare_same_type(const basic & other) const
                return inherited::compare_same_type(other);
 }
 
                return inherited::compare_same_type(other);
 }
 
+bool minkmetric::info(unsigned inf) const
+{
+       if(inf == info_flags::real)
+               return true;
+
+       return false;
+}
+
 int tensepsilon::compare_same_type(const basic & other) const
 {
        GINAC_ASSERT(is_a<tensepsilon>(other));
 int tensepsilon::compare_same_type(const basic & other) const
 {
        GINAC_ASSERT(is_a<tensepsilon>(other));
@@ -165,6 +189,22 @@ int tensepsilon::compare_same_type(const basic & other) const
                return inherited::compare_same_type(other);
 }
 
                return inherited::compare_same_type(other);
 }
 
+bool tensepsilon::info(unsigned inf) const
+{
+       if(inf == info_flags::real)
+               return true;
+
+       return false;
+}
+
+bool spinmetric::info(unsigned inf) const
+{
+       if(inf == info_flags::real)
+               return true;
+
+       return false;
+}
+
 DEFAULT_PRINT_LATEX(tensdelta, "delta", "\\delta")
 DEFAULT_PRINT(tensmetric, "g")
 DEFAULT_PRINT_LATEX(minkmetric, "eta", "\\eta")
 DEFAULT_PRINT_LATEX(tensdelta, "delta", "\\delta")
 DEFAULT_PRINT(tensmetric, "g")
 DEFAULT_PRINT_LATEX(minkmetric, "eta", "\\eta")
index b424cedf4f47f28af1dd6207b78e4b4e75728941..d33603ae8e30133c51a1f7886eab79dad14ec91d 100644 (file)
@@ -60,6 +60,7 @@ class tensdelta : public tensor
 
        // functions overriding virtual functions from base classes
 public:
 
        // functions overriding virtual functions from base classes
 public:
+       bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
@@ -80,6 +81,7 @@ class tensmetric : public tensor
 
        // functions overriding virtual functions from base classes
 public:
 
        // functions overriding virtual functions from base classes
 public:
+       bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
@@ -104,6 +106,7 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
 
        // functions overriding virtual functions from base classes
 public:
+       bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
 
        // non-virtual functions in this class
        ex eval_indexed(const basic & i) const;
 
        // non-virtual functions in this class
@@ -128,6 +131,7 @@ class spinmetric : public tensmetric
 
        // functions overriding virtual functions from base classes
 public:
 
        // functions overriding virtual functions from base classes
 public:
+       bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
@@ -151,6 +155,7 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
 
        // functions overriding virtual functions from base classes
 public:
+       bool info(unsigned inf) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;