AlgebraicNumber

19 views
Skip to first unread message

Ralf Hemmecke

unread,
Mar 22, 2024, 8:22:27 AMMar 22
to fricas-devel
Suppose by some computation I get an expression like

z := (10*sqrt(163)+11*%i)/13/sqrt(105)

I would like to transform it into an element of AlgebraicNumber.

Unfortunately, up to now I was unable to find a function that helps to
to the retraction.

Does someone know a way for cases where I know that the input actually
can happily live in AN?

Thank you in advance.
Ralf

PS: That is one of the situations where things that look simple are hard
for users to actually perform.

Qian Yun

unread,
Mar 22, 2024, 8:37:16 AMMar 22
to fricas...@googlegroups.com
I can only think of this way:

(real z + sqrt(-1)*imag z)::AN

- Qian

Ralf Hemmecke

unread,
Mar 22, 2024, 8:38:36 AMMar 22
to fricas...@googlegroups.com
Oh, for my case I have found a simple trick.
First map to Expression(Complex Intger) to Expression(AN) and then retract.

i := sqrt(-1)@AN;
za := map(x+->(real x + i*imag(x)), z)

Ralf

PS: Yes, Qian, your answer looks close.

Qian Yun

unread,
Mar 22, 2024, 8:53:02 AMMar 22
to fricas...@googlegroups.com
Maybe this signature
retractIfCan : % -> Union(AlgebraicNumber,"failed")
should support it, when % is EXPR COMPLEX INT.

- Qian

Ralf Hemmecke

unread,
Mar 22, 2024, 8:57:53 AMMar 22
to fricas...@googlegroups.com
> Maybe this signature
>   retractIfCan : % -> Union(AlgebraicNumber,"failed")
> should support it, when % is EXPR COMPLEX INT.

Implemented where?

Ralf

Qian Yun

unread,
Mar 22, 2024, 8:59:27 AMMar 22
to fricas...@googlegroups.com
Line 615 of expr.spad.

(Related function: smp2an, k2an, R2AN).

- Qian

Ralf Hemmecke

unread,
Mar 22, 2024, 9:24:16 AMMar 22
to fricas...@googlegroups.com
Cool, Qian!

You are a genius. You seem to have digged out the right place.

Now, of course, the question is how to condition that part.
For

map(x+->(real x + sqrt(-1)@AN*imag(x)), z)

to work R must provide "real" and "imag" and
their target should be coercible to AN.

I think, just testing "R is Complex Integer" or
"R is Complex Fraction Integer" would already be
quite some progress in my eyes.

I only hope that this does not change the behaviour of the interpreter
too much so that, i.e. the interpreter shouldn't invest time in trying
to needlessly coerce something to AN.

Ralf

Waldek Hebisch

unread,
Mar 22, 2024, 12:14:35 PMMar 22
to fricas...@googlegroups.com
On Fri, Mar 22, 2024 at 01:22:23PM +0100, Ralf Hemmecke wrote:
> Suppose by some computation I get an expression like
>
> z := (10*sqrt(163)+11*%i)/13/sqrt(105)
>
> I would like to transform it into an element of AlgebraicNumber.
>
> Unfortunately, up to now I was unable to find a function that helps to to
> the retraction.
>
> Does someone know a way for cases where I know that the input actually can
> happily live in AN?

You asked almost the same thing on 6 Jul 2023. My anwer looked like
this:

Well, the trouble is %i, if you use sqrt(-1), then you will
get Expression(Integer) and things will be easy. But one can
do

(1) -> eI := Expression(Integer)

(1) Expression(Integer)
Type: Type
(2) -> eCI := Expression(Complex(Integer))

(2) Expression(Complex(Integer))
Type: Type
(3) -> iTM := ITRIGMNP(Integer, eI, eCI)

(3)
InnerTrigonometricManipulations
Integer
,
Expression(Integer)
,
Expression(Complex(Integer))
Type: Type
(4) -> z := (10*sqrt(163)+11*%i)/13/sqrt(105)

+---+
10 \|163 + 11 %i
(4) -----------------
+---+
13 \|105
Type: Expression(Complex(Integer))
(5) -> FG2F(z)$iTM

+---+ +---+
10 \|163 + 11 \|- 1
(5) ---------------------
+---+
13 \|105
Type: Expression(Integer)
(6) -> %::AlgebraicNumber

+---+ +---+ +---+ +---+
10 \|105 \|163 + 11 \|- 1 \|105
(6) ---------------------------------
1365
Type: AlgebraicNumber


> PS: That is one of the situations where things that look simple are hard for
> users to actually perform.

Well, internally Expression(Complex(Integer)) and Expression(Integer) are
represented in quite different way, so there is notrivial calculation
to convert between the two forms. And at least one reason for types
is that we want to do calculations in a single type, without "useless"
convertions. So, start from 'sqrt(-1)' and you will consistently
get Expression(Integer) or AlgebraicNumber. OTOH if you want
Expression(Complex(Integer)) then stay there...

--
Waldek Hebisch

Waldek Hebisch

unread,
Mar 22, 2024, 12:24:05 PMMar 22
to fricas...@googlegroups.com
On Fri, Mar 22, 2024 at 08:59:23PM +0800, Qian Yun wrote:
> Line 615 of expr.spad.
>
> (Related function: smp2an, k2an, R2AN).

This handles case of Expression(Integer). But to convert %i to
AlgebraicNumber one needs to do what ITRIGMNP is doing.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Mar 22, 2024, 3:11:35 PMMar 22
to fricas...@googlegroups.com
On 3/22/24 17:14, Waldek Hebisch wrote:
> You asked almost the same thing on 6 Jul 2023.

Do you see a problem?

I have at least 2.
(1) your solution was too complicated, i.e. hard to remember by heart,
(2) it involves InnerTrigonometricManipulations.
I consider an "Inner..." package as something hidden for a user.
(3) if a user does not know how to achieve
Expression(Complex(Integer))->AlgebraicNumber,
then what function name he would search for? "FG2F"?

I much more like Qian's suggestion to add this special case to
"retractIfCan".

>> PS: That is one of the situations where things that look simple are
>> hard for users to actually perform.
>
> Well, internally Expression(Complex(Integer)) and Expression(Integer)
> are represented in quite different way, so there is notrivial
> calculation to convert between the two forms.

Why shouldn't FriCAS help the user by basically exporting the
functionality of "FG2F" via "retractIfCan"?
Would you accept such a patch?

> And at least one reason for types is that we want to do calculations
> in a single type, without "useless" convertions. So, start from
> 'sqrt(-1)' and you will consistently get Expression(Integer) or
> AlgebraicNumber. OTOH if you want Expression(Complex(Integer)) then
> stay there...

Good suggestion. ;-)

You know that I like FriCAS, because it has types. However, I hate it to
waste time if I first have to dig deep into the internals until I can do
seemingly simple transformations.

My actual problem was to denest that expresssion.

%%% (1) -> z :=
sqrt(184726398605281*sqrt(-163)+14962838287027761)/(17502080*sqrt(20010))

+--------------------------------------------+
+-----+ | +-----+
\|20010 \|184726398605281 \|- 163 + 14962838287027761
(1) -------------------------------------------------------
350216620800
Type: AlgebraicNumber
%%% (2) -> rsimp(z)$RootSimplification

(2) "failed"
Type: Union("failed",...)

So I wrote a function that simply solves "x^2-radicand=0". I would have
to do it over complex numbers otherwise it wouldn't factorize. So I
ended in Expression Complex Integer.

While writing this mail, I have found out, that meanwhile
rsimp$RootSimplification can do the trick via ...(see below).
BTW, I am not sure whether I can trust the result, because there is
sqrt(-163) so it's over complex numbers and the docstring of rsimp
http://fricas.github.io/api/RootSimplification.html doesn't say anything
about how to interpret the result. Is there a particular preference over
the two possible solutions?

I still think that "retractIfCan" in Expression(Complex Integer) should
be able to yield an AlgebraicNumber if possible.

Ralf


%%% (57) -> z :=
sqrt(184726398605281*sqrt(-163)+14962838287027761)/(17502080*sqrt(20010))::Expression(Integer)

+--------------------------------------------+
| +-----+
\|184726398605281 \|- 163 + 14962838287027761
(57) -----------------------------------------------
+-----+
17502080 \|20010
Type: Expression(Integer)
%%% (58) -> rsimp(numer z)$RootSimplification

+---------------+
+-----+ |184726398605281
(58) (\|- 163 + 163) |---------------
\| 326
Type: Union(Expression(Integer),...)
%%% (59) -> rootSplit rsimp(numer z)$RootSimplification

+-----+
13591409 \|- 163 + 2215399667
(59) ------------------------------
+---+
\|326
Type: Expression(Integer)
%%% (60) -> rootSplit rsimp(numer z)$RootSimplification / denom z

+-----+
13591409 \|- 163 + 2215399667
(60) ------------------------------
+---+ +-----+
17502080 \|326 \|20010
Type: Expression(Integer)
%%% (61) -> % :: AlgebraicNumber

+-----+ +---+ +-----+
(13591409 \|- 163 + 2215399667)\|326 \|20010
(61) ----------------------------------------------
114170618380800

Waldek Hebisch

unread,
Mar 23, 2024, 11:46:09 AMMar 23
to fricas...@googlegroups.com
On Fri, Mar 22, 2024 at 08:11:31PM +0100, Ralf Hemmecke wrote:
> On 3/22/24 17:14, Waldek Hebisch wrote:
> > You asked almost the same thing on 6 Jul 2023.
>
> Do you see a problem?

Well, it was intended as gentl remaider that a lot of solutions
are in the mailing list archive. And if mailing list is too
hard to search than maybe stash this in some easily searchable
place.

>
> I have at least 2.
> (1) your solution was too complicated, i.e. hard to remember by heart,
> (2) it involves InnerTrigonometricManipulations.
> I consider an "Inner..." package as something hidden for a user.
> (3) if a user does not know how to achieve
> Expression(Complex(Integer))->AlgebraicNumber,
> then what function name he would search for? "FG2F"?
>
> I much more like Qian's suggestion to add this special case to
> "retractIfCan".
>
> > > PS: That is one of the situations where things that look simple are
> > > hard for users to actually perform.
> >
> > Well, internally Expression(Complex(Integer)) and Expression(Integer)
> > are represented in quite different way, so there is notrivial
> > calculation to convert between the two forms.
>
> Why shouldn't FriCAS help the user by basically exporting the
> functionality of "FG2F" via "retractIfCan"?
> Would you accept such a patch?

Well, it is natural from naive user point of view. But it really
streching concept of retraction. Namely, conceptually we should
have embedding homomorphism (coercion). Retraction is supposed
to check if something is in the image of coercion and if yes
return source element (since we are taking about embedding this
source element should be unique). In particular round trip
retract-corce should be identity on domain of retract. But 'FG2G'
fails this due to root transformations. Maybe convenience here
is more important than principles. Expression mostly tries to preserve
roots but not always, so one can argue that principles are already
broken. ATM I do not have string opinion either way.

> > And at least one reason for types is that we want to do calculations
> > in a single type, without "useless" convertions. So, start from
> > 'sqrt(-1)' and you will consistently get Expression(Integer) or
> > AlgebraicNumber. OTOH if you want Expression(Complex(Integer)) then
> > stay there...
>
> Good suggestion. ;-)
>
> You know that I like FriCAS, because it has types. However, I hate it to
> waste time if I first have to dig deep into the internals until I can do
> seemingly simple transformations.
>
> My actual problem was to denest that expresssion.
>
> %%% (1) -> z :=
> sqrt(184726398605281*sqrt(-163)+14962838287027761)/(17502080*sqrt(20010))
>
> +--------------------------------------------+
> +-----+ | +-----+
> \|20010 \|184726398605281 \|- 163 + 14962838287027761
> (1) -------------------------------------------------------
> 350216620800
> Type: AlgebraicNumber
> %%% (2) -> rsimp(z)$RootSimplification
>
> (2) "failed"
> Type: Union("failed",...)

Well, ATM rsimp works with single kernel. Can do

(7) -> kernels(z)

+--------------------------------------------+
| +-----+ +-----+
(7) [\|184726398605281 \|- 163 + 14962838287027761 , \|20010 ]
Type: List(Kernel(AlgebraicNumber))
(8) -> kernels(z).1

+--------------------------------------------+
| +-----+
(8) \|184726398605281 \|- 163 + 14962838287027761
Type: Kernel(AlgebraicNumber)
(9) -> rsimp(kernels(z).1)$RootSimplification

+---------------+
+-----+ |184726398605281
(9) (\|- 163 + 163) |---------------
\| 326
Type: Union(Expression(Integer),...)

I principle 'rsimp' should do this automatically, and at some moment
probably it will. It is simply not implemented now.

> So I wrote a function that simply solves "x^2-radicand=0". I would have to
> do it over complex numbers otherwise it wouldn't factorize. So I ended in
> Expression Complex Integer.
>
> While writing this mail, I have found out, that meanwhile
> rsimp$RootSimplification can do the trick via ...(see below).
> BTW, I am not sure whether I can trust the result, because there is
> sqrt(-163) so it's over complex numbers and the docstring of rsimp
> http://fricas.github.io/api/RootSimplification.html doesn't say anything
> about how to interpret the result. Is there a particular preference over the
> two possible solutions?

'rsimp' simply returns one of the roots. It is essentially random
which one. One of possible improvements is to have somewhat inteligent
selection of result, to prefer positive/real results. OTOH, for
purely algebraic puproses normalized roots are indistinguishable.
ATM in case of dependent roots 'rsimp' may silently fail. Handling
of dependent root is of rather high priority to me, but things take
time.


--
Waldek Hebisch
Reply all
Reply to author
Forward
0 new messages