Richard Kreckel [Mon, 5 Apr 2021 18:46:55 +0000 (20:46 +0200)]
[PATCH] Make ex::operator[] const dispatch to basic::operator[] const.
It turned out that ex::operator[] const dispatched to non-const
basic::operator[] because
* member variable ex::bp is non-const and
* ptr<T>::operator*() returns a non-const T &.
As a result, indexing failed for multiply referenced objects.
Thanks to Vitaly Magerya <vmagerya@gmail.com> for reporting this.
Avoid multiple definitions of `lst::info` (MinGW compile fix)
[55/59] Linking CXX shared library bin/libginac.dll
FAILED: bin/libginac.dll ginac/libginac.dll.a
[skipped long list of object files]
/usr/bin/x86_64-w64-mingw32-ld: ginac/CMakeFiles/ginac.dir/lst.cpp.obj: in function `GiNaC::ptr<GiNaC::basic>::~ptr()':
/home/asheplyakov/work/sw/ginac/_build_w64/../ginac/container.h:150: multiple definition of `GiNaC::container<std::__cxx11::list>::info(unsigned int) const'; ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.obj:/home/asheplyakov/work/sw/ginac/_build_w64/../ginac/container.h:116: first defined here
integration_kernel.cpp makes use of GiNaC::lst without including the `lst.h`
header. That's possible since there's a typedef in `registrar.h` (included
by virtually all GiNaC sources) and a defintion in `container.h` (included
via `add.h` -> `expairseq.h` -> `indexed.h` -> `exprseq.h`), so the compiler
can instantiate container<std::list>. However the explicit specialization
of `lst::info` is not available (in integration_kernel.cpp). This violates
17.8.3.6 [templ.expl.spec] which demands
If a template, a member template or a 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 ina 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.
On ELF platforms libginac appears to link just fine despite having two
instantiations of `lst::info` since the of them (in `integration_kernel.o`)
is a weak symbol:
$ find ginac -type f -name '*.o' | xargs -n 1 nm --print-file-name --defined | c++filt | grep -e 'list>::info('
ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.o:0000000000000000 W GiNaC::container<std::__cxx11::list>::info(unsigned int) const
ginac/CMakeFiles/ginac.dir/lst.cpp.o:0000000000000000 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
so the linker discards the wrong instantiation of `lst::info` method.
However on MinGW there are no weak symbols (in ELF sense):
$ find ginac -type f -name '*.obj' | xargs -n 1 x86_64-w64-mingw32-nm --print-file-name --defined | c++filt | grep -e 'list>::info('
ginac/CMakeFiles/ginac.dir/lst.cpp.obj:0000000000000010 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.obj:0000000000000000 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
Hence the above multiple definition error.
To avoid the problem #include "lst.h" (so explicit specialization is available).
While at it explicitly instantiate lst::info method in lst.cpp
A better solution would be to remove declaration of lst from registrar.h,
but that's too disruptive since GiNaC uses lst a lot: subs, unarchive, etc.
Richard Kreckel [Sun, 22 Nov 2020 20:40:58 +0000 (21:40 +0100)]
Avoid 'variable uninitialized when used within its own initialization' warning.
Initialize the static flyweight ex objects with the pointeed numeric
objects instead of using self-assignment. This is 100% equivalent to
before: The objects have already been initialized by the library_init
ctor so all the static object's ctor does is increment the pointeed
object's refcount.
According to the resolution of C++ core language defect 363 the warning is
incorrect because it is allowed to pass a reference to the object, see
<https://wg21.link/cwg363>. Incrementing the bp's refcount is okay too,
because the pointee numeric object has been fully initialized by the
library_init ctor. However, the compiler can hardly know this, so CLang++
issues a warning.
Richard Kreckel [Mon, 12 Oct 2020 18:42:49 +0000 (20:42 +0200)]
Rename test suite files...
...to match any of the three types:
exam* test result for specific input (like a pupil's exam)
check* test coherence of results among each other, for random input
time* measure run-time
All tests are still there, but maybe elsewhere:
* rename match_bug.cpp => exam_match.cpp
* rename heur_gcd_bug.cpp => exam_heur_gcd.cpp
* rename bugme_chinrem_gcd.cpp => exam_chinrem_gcd.cpp
* rename parser_bugs.cpp => exam_parser.cpp
* rename exam_cra.cpp => check_cra.cpp
* include numeric_archive.cpp => exam_archive.cpp
* include pgcd_infinite_loop.cpp => exam_pgcd.cpp
* include pgcd_relatively_prime_bug.cpp => exam_pgcd.cpp
These two have been deleted, since memory leaks are best looked for
using tools on real programs on a regular basis (they were also not
automatically executed):
* delete parser_memleak.cpp
* delete mul_eval_memleak.cpp
[PATCH 3/3] Stronger normalisation method for powers.
Now normalisation method try to express powers with the same base
as monomials of some dummy variables. This allows to make cancellations
of the sort:
(x-1)/(sqrt(x)-1) -> sqrt(x)+1
Signed-off-by: Vladimir V. Kisil <V.Kisilv@leeds.ac.uk>
Richard Kreckel [Sat, 10 Oct 2020 18:20:59 +0000 (20:20 +0200)]
Remove deprecated initialization via overloaded comma operator.
This feature has been marked as deprecated since 1.7.0. There's been more
than four years to switch to initializer lists. Let's hope people have
modified their code since.
Stefan Weinzierl [Sat, 10 Oct 2020 15:11:09 +0000 (17:11 +0200)]
Added new routines for the numerical evaluation of iterated integrals like
elliptic multiple polylogarithms or iterated integrals of modular forms.
Changes to be committed:
modified: check/CMakeLists.txt
modified: check/Makefile.am
new file: check/exam_inifcns_elliptic.cpp
modified: doc/tutorial/ginac.texi
modified: ginac/CMakeLists.txt
modified: ginac/Makefile.am
modified: ginac/ginac.h
modified: ginac/inifcns.h
new file: ginac/inifcns_elliptic.cpp
new file: ginac/integration_kernel.cpp
new file: ginac/integration_kernel.h
new file: ginac/utils_multi_iterator.h
modified: ginsh/ginsh_parser.ypp
* GiNaC can be included as a (CMake) subproject. One can put GiNaC
sources (either from git or a tarball) into a subdirectory (say,
`ginac`) and use the following CMakeLists.txt to build everything:
build: windows: enable automatic imports by default
For now there are no dllexport/dllimport markings in GiNaC and CLN, so
export all symbols when building GiNaC DLL, and enable automatic imports
when linking with it. Note: this works with GNU linker only.
build: CMake: made it easier to run tests in parallel
As of now `make -jN check` executes test suite sequentially
(although it builds test executables in parallel). This takes
a bit too long, so it would be nice to run tests in parallel.
`ctest -jN` or `make test ARGS=-jN` runs tests concurrently,
however it does not build test executables, instead it fails
if any test binary is missing.
Also `test` target is a bit special and it's impossible to add
dependencies to it, see
https://gitlab.kitware.com/cmake/cmake/issues/8438
To work around the problem define `test_suite` target which
builds the tests suite without running it, so one can both
compile and run tests in parallel
config.h is necessary for excompiler only, the rest of the library
is pretty portable. Not including dynamically generated headers
saves compilation time due to more (c)cache hits.
This makes building GiNaC a bit easier for users of "old" distributions
where python 3 is not installed by default (Ubuntu 16.04), or even not
available (CentOS 7).
Scripts themselves work just fine with python 2.7 and python 3.x, so
only minor changes to CMakeLists.txt are required (autotools scripts
already handle python2/3)
Richard Kreckel [Fri, 21 Aug 2020 15:47:19 +0000 (17:47 +0200)]
Avoid unnecessary expansion in sqrfree_yun().
Don't make the polynomial primitive inside Yun's algorithm. Computing the
primitive part will incur an extra expansion of the polynomial and this
may distroy a pre-factored structure in the other variables. In the multi-
variate case, working with primitive polynomials isn't sufficient anyways
to avoid a final division to discover lost factors.
Richard Kreckel [Mon, 3 Aug 2020 16:20:27 +0000 (18:20 +0200)]
Make workarounds for sqrfree_yun() obsolete.
Since Yun's algorithm is based on polynomial GCD, it only finds factors
up to a unit. Callers shouldn't have to work around this, so sqrfree_yun()
now does a final polynomial long division to compute the lost factor and
fixes the result before returning.
Richard Kreckel [Mon, 3 Aug 2020 16:09:30 +0000 (18:09 +0200)]
[BUGFIX] Fix factor_univariate(poly, x) for constant poly.
The modular factorization fails to find a prime in this case, leading to
an infinite loop. At least one caller (factor_sqrfree) happens to produce
such constant polys in some cases.
Richard Kreckel [Tue, 7 Apr 2020 21:56:25 +0000 (23:56 +0200)]
[PATCH] Check number of parameters when reading function from archive.
Functions where looked up by their function name in archives. However,
some functions have overloads for different numbers of parameters
('zeta', 'G', 'psi'). Reading archives could pick the wrong overload.
Fixed by requiring that the actual number of function parameters in the
archive node must equal the function's declared number of parameters.
Richard Kreckel [Sun, 22 Sep 2019 11:19:00 +0000 (13:19 +0200)]
Remove exhashmap<T> class.
Class exhashmap<T> was a workaround for missing std::hash_map<Key, T>
in the original C++98 standard. It was put in GiNaC because map<Key, T>
was deemed too slow. Since C++11 there is std::unorderd_map<Key, T>,
which is hash-based. To be able to use it, add specializations of
std::hash<ex> and std:equal_to<ex>.
Richard Kreckel [Fri, 3 May 2019 19:14:20 +0000 (21:14 +0200)]
[DOC] Change library order in tutorial example.
Some systems care about library ordering: Dependent libraries must be
linked last. Let's link with -lginac before -lcln in the example so it
will work on any system, even on Windows.
Richard Kreckel [Sat, 9 Mar 2019 17:40:32 +0000 (18:40 +0100)]
Refactor matrix::determinant_minor() a bit.
Remove special cases for small matrices and for for last column
minor computation. Add early return for the case that all minors
relevant for one column turn out to be zero. Improve some comments.
Richard Kreckel [Sat, 16 Feb 2019 11:58:38 +0000 (12:58 +0100)]
Fix elusive bug in expairseq ctor.
When an expair turns out to represent a number, that should go into
the expairseq's overall_coeff. This was accomplished by class mul,
thanks to the override of expair_needs_further_processing(), but not
always for class add.
This patch fixes the base class' expair_needs_further_processing()
with similar logic as that already in place for class mul.
Vitaly Magerya [Fri, 12 Oct 2018 18:45:27 +0000 (20:45 +0200)]
Handle un-normal zeros properly in the division-free elimination.
Call .normal() instead of just .expand(), such that matrix::pivot() finds
the pivot.
Note that this problem also affects matrix::solve() with 'algo'
set to solve_algo::automatic.
Of course, using .normal() makes division_free_elimination only
truly "division-free" if the input matrix didn't have fractions.
In other cases, GCDs will be computed.