sqrt(%pi)/sqrt(2*%pi) simplification?

2 views
Skip to first unread message

Eric

unread,
Oct 11, 2010, 10:35:08 PM10/11/10
to FriCAS - computer algebra system
Hi,

Why doesn't something like
sqrt(%pi)/sqrt(2*%pi)
simplify to 1/sqrt(2) ?

Is this a bug or do I need to force this kind of simplification
somehow?

Thanks,
Eric

Waldek Hebisch

unread,
Oct 13, 2010, 12:16:28 PM10/13/10
to fricas...@googlegroups.com

Such simplification is not done by default and I think as default
would be undesirable. For example consider:

sqrt(2*%pi)*x^2 + sqrt(%pi)*x + sqrt(%pi)/sqrt(2*%pi)

When you simplify the constant term the expression (at least
for computer) gets more complicated (it contains 3 different,
dependent roots intead of 2 independent). FriCAS used to
do some similar simplifications, but ATM most is disabled
(at least by default) because they somtimes gave wrong
results. For example, standard branches are so that

-%i = 1/sqrt(-1) ~= sqrt(-1)/sqrt(-1*-1) = sqrt(-1) = %i

There should be way to explicitly trigger such simplification, but
AFAICS currently no function can do them. So I wrote a little
package to do this (attached below). To try it put the attached
code in the file 'rfact.spad', start FriCAS and do:

)compile rfact.spad

After you compile it once it is enough to do:

)lib RFACT

Below sample outputs:


(1) -> rootFactor(sqrt(%pi)/sqrt(2*%pi))

1
(1) ----
+-+
\|2
Type: Expression(Integer)
(2) -> rootFactor(sqrt(%pi)*sqrt(2*%pi))

+-+
(2) %pi\|2
Type: Expression(Integer)
(3) -> rootFactor(sqrt(9*x^3*y))

+-+ +-+
(3) 3x\|x \|y
Type: Expression(Integer)


BTW: We should probably add this function or similar one to
AlgebraicManipulations.

--------------------------<rfact.spad cut here>---------------------

)abbrev package RFACT RootFactorPackage
RootFactorPackage(R, F): Exports == Implementation where
R : Join(Comparable, UniqueFactorizationDomain, RetractableTo Integer)
F : Join(Field, FunctionSpace(R))

N ==> NonNegativeInteger
Z ==> Integer
OP ==> BasicOperator
SY ==> Symbol
K ==> Kernel F
P ==> SparseMultivariatePolynomial(R, K)
RF ==> Fraction P
REC ==> Record(ker:List K, exponent: List Z)
NTHR ==> "nthRoot"

Exports ==> with
rootFactor : F -> F
++ rootFactor(f) transforms every radical of the form
++ \spad{(a1*...*am)^(1/n)} appearing in f into
++ \spad{a^(1/n)*...*am^(1/n)}.
++ This transformation is not in general valid for all
++ complex numbers \spad{a} and b.

Implementation ==> add

rootkernels: List K -> List K

rootkernels l == select_!((z1: K): Boolean +->
is?(operator z1, 'nthRoot), l)

MPfact := GeneralizedMultivariateFactorize(K, IndexedExponents K,
R, R, P)

fp_root(fp : Factored(P), op : OP, n : N) : F ==
res : F := 1
if (u := unit(fp)) ~= 1 then
res := kernel(op, [u::F, n::F])::F
for fr in factors(fp) repeat
ne : N := (fr.exponent rem n)::N
ng := gcd(ne, n)
nn := (n exquo ng)::Z
ne := (ne exquo ng)::Z::N
ce := (fr.exponent quo n)::N
rr :=
nn > 1 => kernel(op, [(fr.factor^ne)::F, nn::F])::F
1$F
res := res*((fr.factor)^ce)::F*rr
res

pol_root(p : P, op : OP, n : N) : F ==
cp : R := content(p)$P
cp::F
pp := (p exquo cp::P)::P
fp_root(factor(pp)$MPfact, op, n)
*fp_root(map(x +-> x::P, factor(cp)
)$FactoredFunctions2(R, P), op, n)

root_factor_k(k : K) : F ==
x := first argument k
nf := second argument k
n := (retract(nf)@Z)::N
op := operator k
pol_root(numer(x), op, n)/pol_root(denom(x), op, n)

rootFactor x ==
lk := rootkernels tower x
eval(x, lk, [root_factor_k k for k in lk])

-------------------------<cut here>----------------------

--
Waldek Hebisch
heb...@math.uni.wroc.pl

Reply all
Reply to author
Forward
0 new messages