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.
Quick and dirty bug fix for the parser to read GiNaC::lst again.
The parser only accepts lst in the form lst(...) not {...}, though.
Function prototype can now have a argument size of 0 to indicate
functions with an arbitrary number of arguments (like lst).
Fixed a bug in the code for subsitutions in indexed expressions.
subs_options::no_index_renaming was ignored.
Thanks to Gerhard Hejc for reporting and suggesting a fix.
Richard Kreckel [Tue, 31 May 2011 06:46:32 +0000 (08:46 +0200)]
Care about refcounts when reclaiming memory allocated for static objects.
With commit aff357309f6 we started freeing numeric flyweights when the library
usage count drops to zero. But that triggers assertions in basic::~basic
when compiled with -DDO_GINAC_ASSERT because these flyweights are still being
used by their matching ex objects (their refcount is still 1). Instead of
removing that assertion, let's just call the ex::~ex manually and let it do
the freeing.
Richard Kreckel [Fri, 27 May 2011 06:51:05 +0000 (08:51 +0200)]
Janitorial commit.
Remove some assertions that have been wrong since a while, in particular since 8ba901b532b, when we started to factor numerical factors from power objects.
Fix some broken indentation. Fix some comment errors. Remove unused variable.
[build] configure: don't abuse AC_CHECK_FILE. Unbreaks the cross-compilation.
Checking for ginsh_parser.h in configure is not a good idea, since it
1) produces a bogus warning during an out of source build,
2) breaks cross-compilation.
Solution: just skip that bogus check (auto* tools do a similar check in
the run-time *for a reason*).
Jens Vollinga [Sun, 22 May 2011 14:19:17 +0000 (16:19 +0200)]
This patch fixes a bug on machines where char is unsigned by default, by
extending the type of clifford_max_label to include all 257 possible
return values. Thanks to Martin Guy for the bug report and patch.
Jens Vollinga [Fri, 20 May 2011 23:30:08 +0000 (01:30 +0200)]
Limiting the costly symmetrization tests inside simplify_indexed() to
cases where at least one antisymmetric or cyclic non-free index is
involved. Thanks to P.G.Clark for reporting the problem.
Jens Vollinga [Fri, 20 May 2011 21:30:38 +0000 (23:30 +0200)]
Changed naming convention for the library. Now, it is only libginac.so
without the release version included (instead of libginac-1.5.so, for
example). Since the previous commit broke the ABI, we are free to
implement this long planned change now.
Jens Vollinga [Fri, 20 May 2011 11:55:35 +0000 (13:55 +0200)]
Fixed a bug in is_polynomial() that caused expressions like
sqrt(x*x+1)*sqrt(x+1) to be wrongly identified as polynomials in x.
Thanks to Florent Hivert for reporting.
Jens Vollinga [Thu, 19 May 2011 07:44:11 +0000 (09:44 +0200)]
The patch improves the run time at the expense of using more RAM in some
situations. Please note: it doesn't improve the actual algorithm
(iteration over all permutations). Thanks to Alexei Sheplyakov.
Richard Kreckel [Sun, 15 May 2011 16:40:44 +0000 (18:40 +0200)]
Fix mul::conjugate().
Overwrite conjugate() for mul objects because the base class's conjugate
function is incorrect at branch cuts when exponents are fractional (roots).
This has been reported as Sage #10964.
While at it, fix some funny indentation and remove unneeded tests.
Richard Kreckel [Thu, 3 Feb 2011 22:48:21 +0000 (23:48 +0100)]
Merge branch 'master.msvc.support' of git://github.com/AlexeiSheplyakov/GiNaC
* 'master.msvc.support' of git://github.com/AlexeiSheplyakov/GiNaC:
Omit extra qualification (as in struct foo f() vs foo f()).
[msvc] msvc cannot handle string constants above 16k
[msvc] Yet another compiler bug work around.
[msvc] Work around strange scoping and name mangling rules.
Add few defines for msvc (__func__, __alignof__).
symmetry::compare_same_type(): const-correctness fix
clifford: fix a few GCCisms (or, not).
Don't try to tie the library version to the package version number.
Use curret:release:age to indicate ABI changes instead. Hard-code LT_RELEASE
to 1.5 to avoid spurious SONAME change (current code is binary-compatible
with GiNaC 1.5.8).
But the ability to do so is important for a lot of practical uses. So soon
after the C++98 standard was approved, a language defect report was filed
on this topic, see
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
The result is that compilers will be allowed to support reinterpret_cast
conversions of function pointers to other (pointers) types, and vice a versa.
Such conversions work with *current* compilers (GCC 4.x), but don't work
with older ones, hence this patch.
Fix the compliation error *for real* ... and restore performance
Commit 8bf0597dde55e4c94a2ff39f1d8130902e3d7a9b (titled as 'Fixed the parser
such that it can read in user defined classes again.') made the parser a bit
slower, especially if the input contains many terms of user-defined type.
The reason for that is quite simple: we throw and catch an exception every
time we construct an object of user-defined type:
// dirty hack to distinguish between serial numbers of functions and real
// pointers.
GiNaC::function* f = NULL;
try {
unsigned serial = (unsigned)(unsigned long)(void *)(reader->second);
f = new GiNaC::function(serial, args);
}
catch ( std::runtime_error ) {
if ( f ) delete f;
ex ret = reader->second(args);
return ret;
}
Fortunately functions are aligned and we can use much more efficient
technique to distinguish between serial and pointers to functions.