Richard Kreckel [Thu, 5 Nov 2015 12:30:48 +0000 (13:30 +0100)]
Speed up power::real_part() and power::imag_part().
Add special case for real base and exponent (not just integer exponent).
Improve special case for integer exponent by explicitly constructing
the result using the Binomial expansion.
Add a test case for real/imaginary part expansion.
Richard Kreckel [Thu, 15 Oct 2015 06:59:20 +0000 (08:59 +0200)]
Fix make check with g++ -std=c++11.
Our template function log() returning an object of type GiNaC::function
turns out to compete with a template from a libstdc++ header. We have
to help the compiler a bit.
Richard Kreckel [Sat, 18 Jul 2015 21:56:55 +0000 (23:56 +0200)]
Fix pow(+(...),2).expand().
Due to a failure to expand result terms, expand((sqrt(1+x)+y*sqrt(1+x))^2)
returned 1+y^2+x+x*y^2+2*y*(1+x). Note that 2*y*(1+x) was not expanded
to 2*y+2*y*x.
Richard Kreckel [Thu, 7 May 2015 20:33:13 +0000 (22:33 +0200)]
Fix pow(+(...),2).expand().
Due to a failure to recombine coeffs and rests to expairs,
expand((x+sqrt(2)*x)^2) returned x^2+2*x^2+2*sqrt(2)*x^2. The
2*x^2 term was not combined with the x^2 term to 3*x^2 because it
was not the canonical expair [[x^2,2]] but rather [[2*x^2,1]].
Vladimir Kisil [Wed, 22 Apr 2015 21:06:56 +0000 (23:06 +0200)]
Fix pow::info(info_flags::nonnegative).
This function call was missing the case where a positive base is raised
to a real power (where pow::info(info_flags::positive) correctly returned
true).
Ladislav Zejda [Sat, 14 Mar 2015 10:12:11 +0000 (11:12 +0100)]
Improve normalization with nested functions.
normal() fails to fully normalize expressions where nested functions occur
multiple times because replace_with_symbol() searches repl for an
original expression but inserts into repl the substitued expression. Then
the repeated search does not work and a new symbol is introduced.
This patch fixes that by searching for the expression with the repl
substituted instead of for the original expression.
This patch adds a possibility to define derivatives of functions in this way.
In particular the derivative of abs(), Order(), real_part(), imag_part() and
conjugate() are defined.
For example, conjugate of a derivative with respect of a real symbol
If x is real then U.diff(x)-I*V.diff(x) represents both
conjugate(U+I*V).diff(x) and conjugate((U+I*V).diff(x))
Thus in this patch we use the rule
conjugate(f)'=conjugate(f')
for a derivative with respect to the real symbol.
Signed-off-by: Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>
The problem is the sorting operation in G_do_trafo. This operation should
1) put the elements in increasing order of |x|
2) put equal elements next to each other (which then will avoid the log(0) problem).
The current code fails for goal 2) if we have complex numbers of equal absolute
value, one number occuring more than once, in an initial order like in the example
above:
Entries 1,3,4 of the list all have the same absolute value, entries 1 and 4 are
equal. In the sorting operation 1 and 4 should be put next to each other.
Previously, the sorting operation would give 2,1,3,4. What we would like to have
is either 2,1,4,3 or 2,3,1,4. It is clear that the key for the sorting operation
cannot be |x| alone. If |x1|=|x2| we have to use the phase as well.
This patch takes the phase into account in the sorting.
Stefan Weinzierl [Sun, 12 Oct 2014 18:24:07 +0000 (18:24 +0000)]
Fix evaluation of some G-polylogs.
This patch corrects and supersedes the patches 97ef604e "G_numeric: fix numeric evaluation with trailing zeros and y != 1."
and 9e80b0d3 "G_numeric: fix evaluation with y == 1".
The original motivation for 97ef604e was to make sure that Hoelder convolution
is only used if there no trailing zeros.
Patch 97ef604e delegated the case of trailing zeros to G_do_trafo, which correctly
removes the trailing zeros, but in addition also performed the transformation
described in sect. 5.3 of hep-ph/0410259 ("convergence transformation").
The inappropriate call of the convergence transformation is the cause of the new bug
reported at http://www.cebix.net/pipermail/ginac-list/2014-September/002011.html
The patch 9e80b0d3 cures the symptons mentioned in the above bug report,
but fails for other cases, like evalf( G({-2,2,-2,0},2) ).
What should be done is the following: If trailing zeros are detected in G_numeric,
these should be removed and the result should be returned to G_numeric. The
routine G_numeric decides then what to do next: either calling the convergence
transformation, or Hoelder convolution or direct summation. What is needed is a
subroutine, which just removes trailing zeros, but does not perform the convergence
transformation.
With the present code the minimal modification to achieve this goal is to add an
additional boolean parameter flag_trailing_zeros_only to G_do_trafo (and its
dependent sub-routines), so G_do_trafo can be called for the removal of trailing
zeros only.
This patch implements this and uses G_do_trafo to remove trailing zeros only for
the case at hand.
Do apply Hoelder convolution if y == 1 even if there are trailing zeros.
Fixes the regression introduced by commit 97ef604e ("G_numeric: fix
numeric evaluation with trailing zeros and y != 1.")
The function power::is_polynomial(x) sometimes returned false,
even if x did not occur in the power object.
Thanks to Rubel Zilibowitz for reporting this bug.
Similarly, mul::is_polynomial(x) sometimes returned true, even
if x occurred only in the denominator of a rational function.
The function mul::is_polynomial(x) does a simpler version of
power::is_polynomial(x) on its factors. (It's simpler because the
exponents cannot be functions of x.)
Check if the argument is on a branch cut check if it actually depends
on the expansion variable before trying to expand around a different
point in order to avoid the infinite recursion (or rather a segfault
due to a stack overflow).
Stefan Weinzierl [Sat, 12 Apr 2014 11:32:20 +0000 (14:32 +0300)]
G_do_hoelder: fix the transformation of the imaginary part.
The G_do_hoelder function transforms the arguments as z -> 1-z.
If z has an imaginary part, the sign of the imagniary part transforms
as s -> -s.
In the special case where z is real and > 1, the transformed value is
real and < 0. For (transformed) real negative values of z the sign of
the imaginary part is not relevant (there are no branch cuts). The code
requires that in this case the sign takes the default value +1.
This is now fixed.
Stefan Weinzierl [Wed, 12 Feb 2014 20:07:40 +0000 (22:07 +0200)]
G_numeric: fix numeric evaluation with trailing zeros and y != 1.
Make sure G_numeric makes use of scaling relation (G_do_hoelder) only if
there are no traling zeros. Use G_do_trafo otherwise (which can handle
trailing zeros).
Binary compatibilty has been broken, update the library version.
commit 798d53ebb4da4e8e3865ed7bd7f31412fe2be3a7 (`Make it possible to override
info() for functions.') overrides the function::info() virtual method. This
breaks binary compatibility (adds a new entry in the middle of the vtable of
the `function' class).
The experimental proof of the above statement: ginsh linked with the previous
release of libginac segfaults if libginac.so is upgraded to the current
version.
log_eval: don't apply the log(x^p) -> p*log(x) rule.
Automatically transforming log(p^2) into 2 log(p) might be quite annoying.
Perhaps this transformation should be moved to expand() and applied only
if expand_options::expand_transcendental is specified.
Stefan Weinzierl [Tue, 28 Jan 2014 06:58:06 +0000 (08:58 +0200)]
Li_eval(): avoid the "numeric::operator>(): complex inequality" exception.
Basically the problem is that 1 + 0.0*I is equal to 1, but checking if
the former is positive results in the the "numeric::operator>(): complex
inequality" exception. This behavior is definitely inconsistent and should
be fixed.
As a work around teach Li_eval and convert_parameter_Li_to_H to explicitly
convert 1 + 0.0*I to 1 (and -1 + 0.0*I to -1, respectively).
[Alexei Sheplyakov: comment the code a little bit, otherwise it looks weird]
Stefan Weinzierl [Sun, 12 Jan 2014 22:31:22 +0000 (22:31 +0000)]
Fix S_num for arguments close to the sixth root of unity or its conjugate.
The method S_num within the Nielsen polylogs used to map the region
abs(x)<=1 && abs(x)>0.95 && abs(1-x)<=1 && abs(1-x)>0.95 infinitely many times
onto itself. This infinite recursion is now avoided.
This however reveals the next problem: The numerical convergence in this
region is very slow. Within the Nielsen polylogs there is no transformation
available to improve the convergence. However we can use the (1-x)/(1+x)
transformation within the harmonic polylogs. In order to avoid another
infinite recursion I have inserted a few hold()'s in the method H_evalf,
otherwise we would fall back immediately again to Nielsen polylogs. The hold()s
should have been there anyway.
Stefan Weinzierl [Sun, 12 Jan 2014 22:19:56 +0000 (22:19 +0000)]
Fix G3_evalf and G3_eval for real and negative x.
The user supplied signs of the imaginary parts are only relevant for x real
and positive. A negative sign in the case of x real and negative is irrelevant
(there is no branch cut) and led to wrong results. This is now avoided.
The reason is that expairseq::match() might assign a wildcard even if
the match fails. The first attempted submatch is sin(y)*exp(b) with
sin($0)*exp(a). It fails (as it should) but $0 == y gets assigned as
a side effect (which is wrong). Next submatch is sin(x)*exp(a) with
sin($0)*exp(a) (the same pattern as in the first submatch). This one
fails because of spurious $0 == y assignment.
Due to the unpredicatable term ordering the sequence of submatches might
be different and the match might succeed (as it should). This makes
debugging a bit more funny.
Signed-off-by: Matthias Dellweg <dellweg@tp1.uni-duesseldorf.de>
[Alexei Sheplyakov: figure out the cause of the problem, make a test case]
In general expand() treats the argument as a rational expression (and
leave transcendental functions as they are). However sometimes it's
convenient to expand transcendental functions too, like
log(a*b) = log(a) + log(b)
exp(a + b) = exp(a)*exp(b)
Applying such transformation by default doesn't seem to be a smart idea
(think of log(p^2/mu^2) transformed to 2*log(p) - 2*log(mu)). Therefore
introduce expand_options::expand_transcendental. As the name implies expand()
tries to transform transcendental functions only if this flag is set.
Signed-off-by: Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>
Quite a number of transformations can be applied if the expression
is known to be positive (negative) (for instance, sqrt(x^2*y^2) = x*y
if x >= 0 and y >= 0). However the check itself might be quite expensive.
Hence a few status_flags are introduced to cache the result.
Richard Kreckel [Sun, 11 Aug 2013 11:16:15 +0000 (13:16 +0200)]
[build] fix ginsh build for automake <=1.11.
automake <=1.11 and automake >=1.12 have different conventions for naming
C++ header files made by yacc. To work with both, we write our own rule
rather than using automake's.
Trick CTest so the test suite runs when cross-compiling.
The test suite can be run in some cross-compilation setups (say, MinGW
on Linux). Howerver CTest's add_test command does not add the .exe
suffix on its own, as a result `make test' fails. Let's help add_test a bit.
TeX Live 2012 seems to dislike files produces by doxygen (1.8.x.y).
In particular, makeindex(1) program creates invalid index entries like
\hyperpage{NNN_}
(note the trailing underscore in the page number). This breaks automatic
builds and is very annoying. This patch works around the problem by
post-processing the generated *.ind file. This hack is a bit crude, however
it gets the job done (a proper fix is welcome, though).
[build] Move archive version info into version.h (for non autotools build).
The canonical location for all version info is the ginac/version.h file
now (so we can have two build systems without duplicating the version info
in configure.ac and CMakeLists.txt).
Convert function.pl into C++ (well, almost) source and header.
The code is much more readable now, as it's (almost) plain C++ (except
simple pythonic `preprocessor' instructions). As a side effect perl is
no longer necessary for building GiNaC.
[bugfix] Always #include <lst.h> before using lst. Fixes build error on MinGW.
[temp.expl.spec] says:
6 If a template, a member template or the member of a class template
is explicitly specialized then that specialization shall be declared
before the first use of that specialization that would cause an implicit
instantiation to take place, in every translation unit in which such a
use occurs; no diagnostic is required. If the program does not provide
a definition for an explicit specialization and either the specialization
is used in a way that would cause an implicit instantiation to take place
or the member is a virtual member function, the program is ill-formed,
no diagnostic required. An implicit instantiation is never generated for
an explicit specialization that is declared but not defined.
Apparently we are breaking this rule (presumably since the commit 99901bd5c742
`Parser can now read GiNaC lists (lst) defined by braces.'). In particular,
parser.cpp does not include lst.h (neither directly nor indirectly) which
contains explicit specialization of lst::info(). However, parser.cpp
(indirectly) includes both container.h and registar.h, so the GiNaC::lst type
is declared (and is complete) before the first usage. Thus lst::info() gets
implicitly instantiated (using the general definition provided in container.h)
when compiling the parser.cpp file, and libginac fails to link properly due
to mutliply defined symbols:
configure: correctly set rpath for linking with CLN ...
... as to not break tests for libreadline and dlopen().
Problem:
When using GCC 4.6 the configure script fails to find libreadline and
libdl, although both libraries are definitely installed. See
http://www.ginac.de/pipermail/ginac-list/2012-January/001868.html for
more details.
Reason:
Apparently GCC 4.6 dislikes the -R/the/path switch (libtool way to say
-Wl,-rpath,/the/path in a cross platform manner). Previous versions of
GCC used to ignore the -R switch, however, GCC 4.6 errors out instead.
Thus the configure script fails to detect readline and dlopen.
Solution:
Set the rpath (for linking with CLN) using the compiler friendly syntax
(i.e. -Wl,-rpath -Wl,/the/path instead of -R/the/path).
Now that C++11 is out, there is no more need for oracling
about how it might eventually standardize the branch cuts of
elementary and inverse trigonometric and hyperbolic functions.