Richard Kreckel [Fri, 5 Feb 2016 23:47:08 +0000 (00:47 +0100)]
[bugfix] fix elusive bug in quo, rem,...
The power of two rational numeric objects needs not be rational. As a
result, some care is required when transforming (b^e)*l -> (b*l^(1/e))^e
for some rational e and l. This is a common transformation in order to
convert a polynomial over Q into a polynomial over Z when computing
their quotient, remainder, etc. Failure to be careful can potentially
introduce spurious non-rational numbers into rational polynomials and
make those operations fail. This patch avoids this transformation when
l^(1/e) is not a rational number.
Richard Kreckel [Thu, 28 Jan 2016 21:45:56 +0000 (22:45 +0100)]
Remove 'level' argument of normal().
The 'level' argument was modeled after that of the eval() methods
(removed in 6c946d4c). It has never been very useful except for
confusing developers and it hasn't been documented in the tutorial.
Moreover, I have no indication that it has ever been used.
Richard Kreckel [Thu, 28 Jan 2016 21:11:46 +0000 (22:11 +0100)]
Remove 'level' argument of evalf().
The 'level' argument was modeled after that of the eval() methods
(removed in 6c946d4c). It has never been very useful except for
confusing developers. Moreover, I have no indication that it has
ever been used.
Richard Kreckel [Wed, 6 Jan 2016 21:34:23 +0000 (22:34 +0100)]
Avoid x^0 and Order(x^0) terms together in series expansion.
At the branch cut, the series expansions of log(), atan(), and atanh()
assembled pseries objects which contained both x^0 and Order(x^0) terms.
This patch removes the extra x^0 term if the order is 0. It also adds
a GINAC_ASSERT for these kinds of invariants to the pseries ctor and
simplifies the loops in pseries' degree(), ldegree(), eval() and evalf()
member functions.
Clarification on symmetries of metric of clifford object.
The metric of a clifford object may be non-symmetric. Even if
a metric is defined by a symmetric tensor, clifford object may
not be aware of the symmetry and it needs to be explicitly declared.
Signed-off-by: Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>
Richard Kreckel [Thu, 17 Dec 2015 21:45:50 +0000 (22:45 +0100)]
Remove useless code in add::eval().
With commit ae6c004b, we have actually a more rigorous solution for the
bug fixed first (and wrongly) on September 23 2010 with commit 89d5356b.
This patch removes the now useless code and adds the new regression check
from master, just in case.
Richard Kreckel [Wed, 16 Dec 2015 20:22:36 +0000 (21:22 +0100)]
Make .eval() evaluate top-level only.
With the previous patch, some old workarounds have become unnecessary:
If all expressions are evaluated, any object which is an aggregate of
expressions will only ever have to evaluate the top level. As such, it
has become pointless to evaluate child objects of an expression prior
to doing its own term-rewriting. This patch removes the evaluation of
children from all GiNaC objects. It also removes the now superfluous
parameter 'level' of the eval methods.
Richard Kreckel [Wed, 16 Dec 2015 12:00:30 +0000 (13:00 +0100)]
Make add::eval(), mul::eval() work without compromise.
If a user asks to evaluate an object, the expectation is that the
library returns an evaluated, canonical expression. Everything else is
a bug. (It doesn't matter whether the user asks explicitly or by
assigning to an ex.) It turns out that it was possible to construct
objects which didn't fully evaluate. This patch fixes this by making
eval() a little bit more careful.
This obsoletes the need to go through combine_ex_with_coeff_to_pair()
when constructing an epvector that is then used to construct an add
or mul. (Alas, this was omitted frequently enough...)
Richard Kreckel [Mon, 30 Nov 2015 22:06:53 +0000 (23:06 +0100)]
Improve method of setting status_flags::dynallocated.
There seems to be no way to obsolete the need to mark an object derived
from basic and handled by ex as being 'on the heap', at least none that
doesn't have significant performance impact. Having said that, this
patch aims at making this process simpler and more intuitive.
Where, before, one would return from a function returning an ex with
return (new mul(a, b))->setflag(status_flags::dynallocated);
this patch lets us return with
return dynallocate<mul>(a, b);
which should be much clearer. In any case, it involves less typing.
The two points where the status_flags::dynallocated are set are now
* the dynallocate<B>(args...) template function and
* the virtual duplicate() member functions.
This patch rolls out the new functionality throughout the library.
Richard Kreckel [Sun, 29 Nov 2015 11:33:59 +0000 (12:33 +0100)]
Rename array of precomputed data in test suite.
Reason: C++17 may introduce a std::data<> template. Right now, the GCC 6.0
prerelease bails out at this code, when compiler with -std=c++17.
<http://en.cppreference.com/w/cpp/iterator/data>
Richard Kreckel [Sat, 28 Nov 2015 14:43:46 +0000 (15:43 +0100)]
Use neseted initializer lists to construct matrix objects.
Add constructor of initializer_list<initializer_list<ex>> to matrix.
Use this syntax where, previously, ctor from comma-separated list of
elements was used. Deprecate the ctor from comma-separated list.
Note: The output format '[[a,b],[c,d]]' and ginsh syntax are
unchanged because lists are printed '{a,b,c}' and a matrix is not a
list of lists.
Richard Kreckel [Thu, 26 Nov 2015 20:36:46 +0000 (21:36 +0100)]
Use initializer lists to construct container<>, lst.
Add constructor of initializer_list<ex> to container<C<ex>>. In
particular, this means that we can finally declare lst objects as
lst{a,2*b,2}. Convert GiNaC to this syntax throughout. Deprecate
the old constructors taking 1..16 ex parameters and the ones from
comma seaparated lists (without braces).
Richard Kreckel [Thu, 26 Nov 2015 11:20:20 +0000 (12:20 +0100)]
Make ample use of the contextual keyword 'override'.
This patch adds the C++11 contextual keyword 'override' to every overridden
virtual function declaration except where that would incur macro duplications.
Along the way, it fixes some comments about member functions 'virtuality'.
Richard Kreckel [Wed, 25 Nov 2015 10:28:10 +0000 (11:28 +0100)]
In power::expand_add(), don't reserve excess monomial sizes.
There is no need to reserve n terms in each of the monomials of the
result of power(+(x,y,z...;0),n): We can compute it exactly as the
number of nonzero exponents in the multinomial expansion. The good
thing is that this counting is the same for each composition of a
partition, so it can be hoisted out of the loop over compositions.
Richard Kreckel [Wed, 25 Nov 2015 10:22:34 +0000 (11:22 +0100)]
Make specialized power::expand() helpers static member fuctions.
The class power member functions expand_add(), expand_add_2(), and
expand_mul() do not access any member variable of class power. (In
fact, the only reason not to hide them entirely is that they invoke
protected members of classs expairseq, add, and mul which requires
them to be friends of these classes.)
Richard Kreckel [Tue, 24 Nov 2015 10:14:51 +0000 (11:14 +0100)]
mul::can_make_flat(): Finish ancient unfinished code.
This makes mul(expairseq({a*b,2},{b})) construct the canonical
mul(expairseq({a,3},{b,2})). Normally, such term rewriting is done
by the .eval() methods, but this is not done when a plain object of
a class derived from basic is constructed.
Richard Kreckel [Mon, 23 Nov 2015 20:21:18 +0000 (21:21 +0100)]
Make (a+b+c+...)^n work for huuuge terms.
This fix is neccessary for results exceeding 2^31 terms. While at it,
also restructured power::expand_add_() a bit to look more like the
more general power::expand_add().
Richard Kreckel [Sat, 7 Nov 2015 12:03:05 +0000 (13:03 +0100)]
Remove 'discardable' option from ctors of container and derived classes.
The whole idea of this was to allow the ctor to pilfer the data from the
constructed-from object, which is precisely the move semantics which
C++11 supports with rvalue references.
Richard Kreckel [Sat, 7 Nov 2015 00:50:00 +0000 (01:50 +0100)]
Add trivial shortcuts in expair plumbing of class add.
These little shortcuts in add::split_ex_to_pair(ex) and in
add::combine_ex_with_coeff_to_pair(ex, ex) avoid the creation of
new ex objects. These pieces of code are executed so often that this
patch speeds up GiNaC by 5-10%, depending on test.
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>