Lost in stack of categories

40 views
Skip to first unread message

Tobias Neumann

unread,
Feb 1, 2021, 2:57:10 PM2/1/21
to FriCAS - computer algebra system
Dear FriCAS group,

@Waldek: As it turns out 95% of the issues I was generally facing were caused by missing import's. So thank you for that and further insight.

I am currently writing functions that require series expansions, conversion from Complex(Fraction(Integer)) to Complex(Float) (CF) and back to Complex(Fraction(Integer)) (CFI) to approximate longer exact expressions in the CFI domain, possibly integration, and pattern matching.

I have started the package with domains

    R  : Join(GcdDomain, Comparable, RetractableTo Integer, _
              LinearlyExplicitOver Integer)
    FE : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory, _
              FunctionSpace R)

So if my function operates on FE, I can do series expansions

In practice I start with (call the function with) expressions in the domain Expression(Complex(Fraction(Integer))), which are fed to the FE functions. The reason I have to use FE Is because the use of 'approximate' from series expansions requires additional operations that are implied by these type constraints:

    if Coef has coerce : Symbol -> Coef then
      if Coef has "^": (Coef,RN) -> Coef then

Is there a way to just have a function in the concrete domain Expression(Complex(Fraction(Integer))) and demand that it further satisfied these constraints? Or is this not something that makes sense?

Moving on I further wanted to have some debug prints, so I had to add               "ConvertibleTo InputForm" to FE. To have the most general integration routine working I added "PrimitiveFunctionCategory, AlgebraicallyClosedFunctionSpace R" to FE and "CharacteristicZero, PolynomialFactorizationExplicit" to R.

I also want to use pattern matching on FE expressions, so I added "PatternMatchable Integer" to R. 

Now I am facing the problem that I want to approximate some expressions in FE
(I concretely call the FE function with an Expression(Complex(Fraction(Integer))) argument)) using rationalFunction$Float. So I added 
              CoercibleTo Expression(Complex(Float)), _
              CoercibleTo Expression(Complex(Fraction(Integer))), _
to FE. This allows me to convert some FE expressions to Expression(Complex(Float)) and I was hoping that in an additional step I could coerce back to FE. So
Step1: coerce FE to ECF
Step2: coerce ECF to Expression(Complex(Fraction(Integer))) and hopefully back to FE

As it turns JUST adding these additional type constraints was not a good idea, and I get a runtime crash even with an empty function: Function:  smaller? : (%, %) -> Boolean is missing from domain: Vector(Complex(Fraction(Integer)))
(Obviously this makes sense that there is no 'smaller?'). 

It looks to me like I'm lost in type constraints. Maybe all of this can be solved if I can start with a domain Expression(Complex(Fraction(Integer))) and specify additional constraints that allow me to use approximate, etc., whatever isn't implied.

I am not sure if I can expect a concrete answer to these issues, but I would be happy for some suggestions. Maybe I am missing something fundamental that would resolve such issues immediately. 

Another question: Is the ")translate" option for ")compile" still supported? The manual implies that this can be used to translate SPAD code into Aldor code.

Thank you,
Tobias

Waldek Hebisch

unread,
Feb 1, 2021, 7:21:32 PM2/1/21
to fricas...@googlegroups.com
On Mon, Feb 01, 2021 at 11:57:10AM -0800, Tobias Neumann wrote:
> I am currently writing functions that require series expansions, conversion
> from Complex(Fraction(Integer)) to Complex(Float) (CF) and back to
> Complex(Fraction(Integer)) (CFI) to approximate longer exact expressions in
> the CFI domain, possibly integration, and pattern matching.
>
> I have started the package with domains
>
> R : Join(GcdDomain, Comparable, RetractableTo Integer, _
> LinearlyExplicitOver Integer)
> FE : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory, _
> FunctionSpace R)
>
> So if my function operates on FE, I can do series expansions
>
> In practice I start with (call the function with) expressions in the domain
> Expression(Complex(Fraction(Integer))), which are fed to the FE functions.
> The reason I Expression(Complex(Fraction(Integer)))have to use FE Is because the use of 'approximate' from series
> expansions requires additional operations that are implied by these type
> constraints:
>
> if Coef has coerce : Symbol -> Coef then
> if Coef has "^": (Coef,RN) -> Coef then
>
> Is there a way to just have a function in the concrete domain
> Expression(Complex(Fraction(Integer))) and demand that it further satisfied
> these constraints? Or is this not something that makes sense?

By design FriCAS type constraints are in terms of domains and
not in term of elements. So either conditions are satisfied
when you use Expression(Complex(Fraction(Integer))) or not.
If conditions are satisfied you can just use it instead of FE.
Using FE means that your package is more general (because
potentialy other domains satisfy your contraints) and
hopefuly more clear (because contraints are explicit).
However if you cram a lot of different things into single
package, then it is no longer clear which constraint is
relevant for specific aspect, so hardcoding FE to
Expression(Complex(Fraction(Integer))) may be better.

Concerning elements: usual pattern is use of 'retractIfCan'
to test if your element logically belongs to smaller
domain (which may satisfy stronger constrants). Another
aspect is domain inheritance: contrants may be related
to availability of some functions. If you can provide
reasonable implementation of needed functions, then
you can create new domain which is essentially like
old one but adds new function.

To put is differently: types serve as compile-time assertions
about all values of given type. If your value satisfies
stronger condition, then you can create new type (new
stronger assertion) and convert value to the new type.
Note thar 'convert' here may be as trivial as using
'pretend' (if your new type uses the same representation
as on old one) or may involve substantial computation
(like convertion between Expression(Integer) and
Expression(Fraction(Integer))).

Another pattern is conditional definiton: if you want
your package to be general you can condtionally define
functions based on propertied of types. 'approximate'
above is an example of this pattern: other operations
are more general, but 'approximate' need ability to
coerce variable name (a symbol) to element of coefficnt
domain. To support Puiseux series 'approximate' needs
ability to compute fractional powers.

BTW: Logically Expression(Complex(Fraction(Integer)))
is the same as Expression(Complex(Integer)), but the
second is usually more efficient. So I wonder why
you use Expression(Complex(Fraction(Integer))).
Lack of 'smaller?' was a bug. Apparently you are doing things
differently than other folks, so you were first to notice
the problem. Thanks for info: I now commited fix to the trunk.

BTW: 'smaller?' is supposed to implement axiom of choice, that
is linear order that may have no special connection to mathematical
properties of domain. There are deep problems with current
implementation for 'Expression', but implementation for 'Vector'
do not present any difficulty.

> It looks to me like I'm lost in type constraints. Maybe all of this can be
> solved if I can start with a domain Expression(Complex(Fraction(Integer)))
> and specify additional constraints that allow me to use approximate, etc.,
> whatever isn't implied.

AFAICS Expression(Complex(Fraction(Integer))) should satisfy your
constraints without need to add anything.

In slightly different tone: if you feel that some domain/package
should have some operation and type constraints prevent using it,
then ask here. Usually there is good reason why type constraints
are there, in such case other domain/package may be more appropriate.
But there are also cases where constraints are not needed, then
we can improve FriCAS by removing spurious limitations.

> Another question: Is the ")translate" option for ")compile" still
> supported? The manual implies that this can be used to translate SPAD code
> into Aldor code.

No. This part never worked well and was removed long ago. I now
removed the remaining traces.

--
Waldek Hebisch

Tobias Neumann

unread,
Feb 1, 2021, 10:20:52 PM2/1/21
to fricas...@googlegroups.com
BTW: Logically Expression(Complex(Fraction(Integer)))
is the same as Expression(Complex(Integer)), but the
second is usually more efficient.  So I wonder why
you use Expression(Complex(Fraction(Integer))).

I haven't looked at the internal representation, but from the way the interpreter/REPL presents
it, Complex(Fraction(Integer)) seems more natural to me because it doesn't seem to
have to keep track of a (possibly huge) denominator. On the other hand just saving one (but possibly huge)
denominator is probably cheaper. If they are logically the same,
I should be able to write everything and then check in the end which version performs better.

(1) -> x^2 + x + 4 + 1/1000 + %i :: Expression(Complex(Fraction(Integer)))
         2       4001
   (1)  x  + x + ---- + %i
                 1000
                                 Type: Expression(Complex(Fraction(Integer)))

(2) -> x^2 + x + 4 + 1/1000 + %i :: Expression(Complex(Integer))

              2
        1000 x  + 1000 x + 4001 + 1000 %i
   (2)  ---------------------------------
                       1000
                                           Type: Expression(Complex(Integer))

AFAICS Expression(Complex(Fraction(Integer))) should satisfy your
constraints without need to add anything.

In slightly different tone: if you feel that some domain/package
should have some operation and type constraints prevent using it,
then ask here.  Usually there is good reason why type constraints
are there, in such case other domain/package may be more appropriate.
But there are also cases where constraints are not needed, then
we can improve FriCAS by removing spurious limitations.

Coming back to my series expansion wrapper (see below). I get the error
   >> Apparent user error:
   not known that uts has (AND (has (Expression (Complex (Fraction (Integer)))) (SIGNATURE ^ ((Expression (Complex (Fraction (Integer)))) (Expression (Complex (Fraction (Integer)))) (Fraction (Integer))))) (has (Expression (Complex (Fraction (Integer)))) (SIGNATURE coerce ((Expression (Complex (Fraction (Integer)))) (Symbol)))))

Does this ask for a coercion of Expression(Complex(Fraction(Integer))) into a Symbol?

On the other hand the interpreter seems to just do fine:

(11) -> ser := retract(puiseux((x^2 + x) :: Expression(Complex(Fraction(Integer))), 'x=0))$AnyFunctions1(UnivariatePuiseuxSeries(Expression(Complex(Fraction(Integer))),'x,0))
(12) -> approximate(ser,3)$UnivariatePuiseuxSeries(Expression(Complex(Fraction(Integer))), 'x, 0)

From bottom messages I see that
[1]  signature:   (UPXS(EXPR(COMPLEX(FRAC(INT))),x,0), FRAC(INT)) -> EXPR(COMPLEX(FRAC(INT)))
      implemented: slot (Expression (Complex (Fraction (Integer))))$(Fraction (Integer)) from UPXS(EXPR(COMPLEX(FRAC(INT))),x,0)

So here it seems to know that Expression(Complex(Fraction(Integer))) has the necessary signatures needed for approximate.

Thank you,
Tobias

--- SNIP ---
)abbrev package MYTAYL MyTaylorExpansion

MyTaylorExpansion() : Exports == Implementation where
    FI ==> Fraction(Integer)
    CFI ==> Complex(Fraction(Integer))
    ECFI ==> Expression(Complex(Fraction(Integer)))

    Exports ==> with
        my_taylor : (ECFI, Symbol, CFI) -> ECFI

    Implementation ==> add
        e_pak ==> ExpressionToUnivariatePowerSeries(CFI,ECFI)

        my_taylor(ff, sym, x0) ==
            eqn := equation(sym :: ECFI, x0 :: ECFI)$Equation(ECFI)
            uts := UnivariatePuiseuxSeries(ECFI,sym,x0::ECFI)
            any1 := AnyFunctions1(uts)
            ts := retract(puiseux((sym::ECFI), eqn)$e_pak)$any1
            approx := approximate(ts,3/1)$uts
            approx
---- SNIP----

PS: Some additional questions; I believe you are the author of the rational reconstruction packages

I'm currently not in need of any of such functions, but just curious/interested:

What is the difference between these two packages?
"Each evaluation is done module machine sized prime p"
I am (not yet) particularly familiar with polynomial/rational reconstruction. Does that
restrict the highest degree of the numerator or denominator in practice, or does that mean
that just more probes are necessary? It seems like these routines are able to handle the multivariate case?
 Are these packages in a "working" condition so that I can use them with "little" effort as a black box?
(For example there is a C++ package that can act as a simple black box https://gitlab.com/firefly-library/firefly ; arXiv:1904.00009,
 so if the need arises it could be interesting to interface some dedicated libraries to FriCAS )

Waldek Hebisch

unread,
Feb 2, 2021, 10:34:38 AM2/2/21
to fricas...@googlegroups.com
On Mon, Feb 01, 2021 at 10:20:40PM -0500, Tobias Neumann wrote:
> >
> > BTW: Logically Expression(Complex(Fraction(Integer)))
> > is the same as Expression(Complex(Integer)), but the
> > second is usually more efficient. So I wonder why
> > you use Expression(Complex(Fraction(Integer))).
> >
>
> I haven't looked at the internal representation, but from the way the
> interpreter/REPL presents
> it, Complex(Fraction(Integer)) seems more natural to me because it doesn't
> seem to
> have to keep track of a (possibly huge) denominator. On the other hand just
> saving one (but possibly huge)
> denominator is probably cheaper.

Well, it is natural to think that many small denominators are
more efficient. It happens in artificial examples. But
experimental evidence indicates that normally single large
denominator is more efficient.

> If they are logically the same,

Yes, both are fields containing Complex(Integer). In particular
Expression(Complex(Integer)) effectively contains isomorphic copy
of Fraction(Complex(Integer)). By field theory Fraction(Complex(Integer))
and Complex(Fraction(Integer)) are isomorphic. Currently
FriCAS builds internal representation in recursive way based
on type that you gave, so at machine level all domains above
are different.
Not exactly. There are two conditions above joined by AND. The second is

(has
(Expression (Complex (Fraction (Integer))))
(SIGNATURE coerce ((Expression (Complex (Fraction (Integer)))) (Symbol))))

'has' above asks if domain in second line satisfies type condition
in third line. 'SIGNATURE' is conditions requesting function with
given name, that is 'coerce' having given return type and
argument types. Types are given as Lisp list, first is return type
than argument types. Second type is 'Symbol', so it is argument type.
First is Expression(Complex(Fraction(Integer))) so it is retrun type.

This is limitiation of Spad compiler, sometimes it can not infer
that needed conditions are satisfied. Possible workaround it to
use runtime test like:

if ECFI has coerce : Symbol -> ECFI and
ECFI has _^ : (ECFI, Fraction (Integer)) -> ECFI then

a_fun(f, expo) == approximate(f, expo)

else

a_fun(f, expo) == error "impossible"

Drawback of this is that 'a_fun' must be exported (this is compiler
limitation, you can not have conditions for internal functions).

> PS: Some additional questions; I believe you are the author of the rational
> reconstruction packages
> https://fricas.github.io/api/VectorIntegerReconstructor.html
> https://fricas.github.io/api/VectorModularReconstructor.html

Yes.

> I'm currently not in need of any of such functions, but just
> curious/interested:
>
> What is the difference between these two packages?

VectorIntegerReconstructor is doing reconstruction of rational
numbers from integers modulo another integer.
VectorModularReconstructor is doing reconstruction of rational
functions with coefficients from prime field from polynomials
modulo another polynomial.

Logically you can view both packages as instances of generic
package that takes base ring (which must be a PID) as parameter.
In case of VectorModularReconstructor base ring is ring of
integers. In case of VectorModularReconstructor base ring
is ring of univariate polynomials over a prime filed.
At abstract level, if you correctly state what packages are
doing, then both packages are doing "the same thing" but
for different types.

There are two separate packages because type specific version
are more efficient. Also, for efficiency prime is passed
as extra parameter to all functions from VectorModularReconstructor,
so signatures of functions differ.

> "Each evaluation is done module machine sized prime p"
> I am (not yet) particularly familiar with polynomial/rational
> reconstruction. Does that
> restrict the highest degree of the numerator or denominator in practice,

Yes, there are restrictions. Basically packages ignore possibility
of overflow and it is caller responsibility to choose data size and
prime so that there will be no overflow. In itself using machine
size primes seem to be rather mild restriction: there is a lot
of machine sized primes. But current situation is worse, one
needs to keep sufficient safety margin to avoid overflow in
intermediate steps. Let me add that for FriCAS main interest
in low degrees (say < 100). Code works fine for degrees of
order of few thousends. In practice limitations came from
compute time (think hours or days) and memory. In cases
where this was used cofficients of polynomials had size proportional
to degree and there were several polynomials. Memory use
were in gigabytes.

> or
> does that mean
> that just more probes are necessary? It seems like these routines are able
> to handle the multivariate case?

Yes. More precisely, they are ignorant about other variables
except for main variable, but handle several polynomials
at once ("Vector" in name is becase there are doing several
computations logically in parallel). One can use the
routines to recursively perform multivariate reconstruction.

> Are these packages in a "working" condition so that I can use them with
> "little" effort as a black box?

The packages are rather intesively used, by guessing package and
for gcd of polynomials with algebraic coefficients. Concerning
use: they are low level packages where main issue is speed and
not user convenience. Hence restrictions, long parameter lists,
etc.

--
Waldek Hebisch

Tobias Neumann

unread,
Feb 2, 2021, 1:41:11 PM2/2/21
to fricas...@googlegroups.com
This is limitiation of Spad compiler, sometimes it can not infer
that needed conditions are satisfied.  Possible workaround it to
use runtime test like:

   if ECFI has coerce : Symbol -> ECFI and
      ECFI has _^ : (ECFI, Fraction (Integer)) -> ECFI then

       a_fun(f, expo) == approximate(f, expo)

   else

       a_fun(f, expo) == error "impossible"

Drawback of this is that 'a_fun' must be exported (this is compiler
limitation, you can not have conditions for internal functions).

OK, I am happy to use a workaround and it compiles fine. In practice it *does* throw the error
(3) -> my_taylor(x^2+x, 'x, 0)
   >> Error detected within library code:
   impossible

I can use the ^ and coerce functions for ECFI without any issues
(see "(ff)^((1/3) :: FI)" in the code below).

I thought that maybe something is wrong with the interpreter, but even if I use my_taylor within SPAD code
it fails, like

        testfun : Integer -> Integer
        testfun zz ==
            x := coerce('x)$ECFI
            x0 := 0 :: CFI
            tseries := my_taylor( (x^2 + x) :: ECFI, 'x, x0)
            zz

So although I can use coerce and ^ in the routines fine, the constraint in approximate, which necessitates
the constraint on my_taylor, prohibits a call of the function. I'm hoping that this is just some user error!

---- SNIP ----
)abbrev package MYTAYL MyTaylorExpansion

MyTaylorExpansion() : Exports == Implementation where
    FI ==> Fraction(Integer)
    CFI ==> Complex(Fraction(Integer))
    ECFI ==> Expression(Complex(Fraction(Integer)))

    Exports ==> with
        my_taylor : (ECFI, Symbol, CFI) -> ECFI

    Implementation ==> add
        e_pak ==> ExpressionToUnivariatePowerSeries(CFI,ECFI)

        if ECFI has coerce Symbol -> ECFI and
           ECFI has _^ : (ECFI, Fraction (Integer)) -> ECFI then

            my_taylor(ff, sym, x0) ==
                eqn := equation(sym :: ECFI, x0 :: ECFI)$Equation(ECFI)
                uts := UnivariatePuiseuxSeries(ECFI,sym,x0::ECFI)
                any1 := AnyFunctions1(uts)
                ts := retract(puiseux((sym::ECFI), eqn)$e_pak)$any1
                --approx := (ff)^((1/3) :: FI)
                approx := approximate(ts,3/1)$uts
                approx
        else
            error "impossible"
---- SNIP ----

Ralf Hemmecke

unread,
Feb 2, 2021, 4:35:01 PM2/2/21
to fricas...@googlegroups.com
I have only followed this discussion loosely, but there were some bugs
in you code. (Actually, good that you posted the code in full, otherwise
I wouldn't have taken the time to debug.)

Attached is a corrected version.

In particular, you forgot the colon between coerce and Symbol in

> if ECFI has coerce Symbol -> ECFI and

ECFI ==> Expression(Complex(Fraction(Integer)))
CFI ==> Complex(Fraction(Integer))
x := 'x :: ECFI
x0 := 0 :: CFI
my_taylor( (5*x^2 + 17*x^7) :: ECFI, 'x, x0)


The output doesn't look correct, but at least it doesn't throw an error
at me.

(6) -> my_taylor( (5*x^2 + 17*x^7) :: ECFI, 'x, x0)
EINS

(6) x

Hope that helps a bit.

Ralf
myty.spad

Ralf Hemmecke

unread,
Feb 2, 2021, 4:47:07 PM2/2/21
to fricas...@googlegroups.com
Tobias, can you perhaps give (a more mathematical) account of what you
actually want to achieve.

What are your input functions and what do you expect as output.
There is no need to answer in terms of FriCAS types, but it would be
nice to get an idea what your input class is in order to find an
appropriate type in FriCAS for it that can then more easily used to
transform you object into something you want.

Thanks
Ralf

Tobias Neumann

unread,
Feb 2, 2021, 5:03:51 PM2/2/21
to fricas...@googlegroups.com

In particular, you forgot the colon between coerce and Symbol in

 
Ouch, thank you for that! That was the whole problem after all.
(Never mind about the argument not being used, that is some debugging leftover)

I am a little worried that the compiler did not catch this, but I am certainly more and more careful now
as I know the limitations of the compiler.

(Let me respond to the problem set in a separate, longer email)

Ralf Hemmecke

unread,
Feb 2, 2021, 5:46:00 PM2/2/21
to fricas...@googlegroups.com
> (Let me respond to the problem set in a separate, longer email)

If you include a short summary, it would be easier to understand.
I rather like to ask if something is unclear.

Ralf

PS: Yes, the compiler is quite bad when it comes to throwing appropriate
error messages at you. Sometimes it is not only bad but even the error
can be at a totally different place. In particular, little things like
this missing colon can be hard to debug.

Tobias Neumann

unread,
Feb 2, 2021, 7:07:58 PM2/2/21
to fricas...@googlegroups.com
PS: Yes, the compiler is quite bad when it comes to throwing appropriate
error messages at you. Sometimes it is not only bad but even the error
can be at a totally different place. In particular, little things like
this missing colon can be hard to debug.

In that regard I already thought whether it could be better to write the code in Aldor (within FriCAS with the FriCASlib import).
I just assume that the compiler is much better, but I could be wrong. But this probably opens a new can of worms,
and I'm better off trying to compile "every additional line" or so to immediately catch issues until I'm more fluent with things.

Here's some insight into my problem set (with some additional background if you are curious):

The start is to solve Feynman loop integrals for higher-order perturbative
calculations in quantum field theory (physics). For a given (difficult)
perturbative calculation one starts typically with thousands of linearly
dependent integrals. These can be reduced to a basis of O(100) integrals,
and this itself is a problem involving solving large linear systems with
intermediate expression swell. For that purpose solvers with rational function
reconstruction have been created, but it can still require a few hundred GB of memory
and days of CPU time. Anyway, this is another problem that I am not concerned about here.

I am concerned about the actual solution of the (master) integrals, which
depend on a few parameters. They satisfy a system of first-order linear ODEs.
If the integral basis holds certain properties, it can sometimes be solved
analytically in terms of a function class called multiple-polylogarithms. But
in general elliptic functions appear and a fully analytic solution is often not
feasible. So in my case I want to solve such systems numerically. The problem
has lots of subtleties so that I can't use ODE solvers that are readily
available (in FriCAS).

For large parts of the system I can get a solution in terms of iterated integrals
of the series-expanded matrix defining the ODE system. The series expansions are typically
around regular singular points and have only a limited radius of convergence.
So I need to patch together many series expansions to transport from the
boundary condition point to the target point. As for the series, I will have
to rely on the most general implementation (GeneralUnivariatePowerSeries) so
that I can also expand around logarithmic singularities
(series(log(x)*f(x),x=0)). FriCAS seems to handle that well. Integration of
such general series is not implemented, so this is something that I am working
on. Since the terms in my series expansion are always of the form log(x)^k1 *
x^k2, I can take the series Stream, pattern match and plug in the solution.
There are also subtleties regarding taking the right branch cut when evaluating the log's and fractional
power expressions (it's not always the standard cut), but I think I have an appropriate scheme to handle that.

The Stream-type series expansion in FriCAS makes it very attractive to truncate
dynamically after some precision goal has been reached. And at some point
I will also play around with series acceleration methods (various
transformations, conformal mappings).

So this part comprises series expansion of sparse matrices (~ 70x70),
multiplication with vectors, integration (pattern matching), taking care of
correct branch cuts when evaluating the result; patching together multiple
series solutions.

For a smaller subset of the system (at a later stage) I will need to construct
homogenous solutions with the Frobenius method. And this part will be more complicated.

The integrals themselves depend on 2-3 parameters and have sharply
peaked structures and even singular points in that parameter space. The integrals will
also have to be evaluated close to the singularities; both numerical
precision and performance matter. At the last stage I need to interface with a
Fortran code, or possibly construct an interpolation mesh (or maybe play around
with radial basis function interpolation). This depends on how fast the
code is and how easy it will be to interface with the Fortran code.

Previously people have tackled solving these integrals with Mathematica,
but mostly for smaller problems and for testing. For my particular
application I need a high-performance implementation that can be
deployed on a cluster. For Mathematica there would be a license
issue to deploy it on hundreds of cores. And I believe (hope!) that
with a FriCAS implementation I can gain some significant speedup
compared to a Mathematica implementation. So far my tests seem to
indicate that it can handle things quite well and that apart from
simple issues with SPAD and the compiler I should have no roadblocks inherent
from FriCAS.

In principle, one could generalize a lot of things here, but for this specific
project I need to be goal-oriented, and the goal (for now) is not to have it
neatly generalized into independent mathematical domains and categories. Depending
on how well everything turns out I can think about that afterwards, since the method
can be applied to other perturbative calculations where the constraints and
subtleties can be generalized.

Best wishes,
Tobias

Ralf Hemmecke

unread,
Feb 2, 2021, 7:37:21 PM2/2/21
to fricas...@googlegroups.com
> Here's some insight into my problem set (with some additional background if
> you are curious):
>
> The start is to solve Feynman loop integrals for higher-order perturbative
> calculations in quantum field theory (physics).

What comes to my mind when I hear Feynman integrals is work of my
colleague in his collaboration with DESY.

https://risc.jku.at/m/carsten-schneider/

As far as I understand it, Feynman integrals can be transformed into a
summation problem, then simplified by Schneider's Mathematica package
Sigma. Obviously, some physicists find that very useful.

Not sure whether that is similar to what you are after, but of course
ther would be a Mathematica license issue as you say.

If you feel that FriCAS can in principle do the job for you, then keep
on asking about whatever blocks your way in implementing you problem.

I am a bit concerned about your wish to solve the master integrals
numerically. I'm not quite sure whether FriCAS is the best and fastest
tool for that, but perhaps I just don't understand enough of the details
of your problem.

Anyway, good luck with your endeavour.

Ralf

Tobias Neumann

unread,
Feb 3, 2021, 8:20:57 PM2/3/21
to fricas...@googlegroups.com
What comes to my mind when I hear Feynman integrals is work of my
colleague in his collaboration with DESY.

https://risc.jku.at/m/carsten-schneider/

The academic world is small, in fact I know a few collaborators of your colleague.

Here is a new problem that I came across. I have a simple wrapper over sort,
trying to sort a list of lists of integers.

The interpreter has no problems with that:

test := [[1,2],[2,1],[-1,1]]

(4) -> sort(test)
 Function Selection for sort
      Arguments: LIST(LIST(INT))
 [1]  signature:   LIST(LIST(INT)) -> LIST(LIST(INT))
      implemented: slot $$ from LIST(LIST(INT))
   (4)  [[- 1, 1], [1, 2], [2, 1]]
                                                    Type: List(List(Integer))

My wrapper implementation (code below):

(5) -> mysort(test)
 Function Selection for mysort
      Arguments: LIST(LIST(INT))
 [1]  signature:   LIST(LIST(INT)) -> LIST(LIST(INT))
      implemented: slot (List (List (Integer)))(List (List (Integer))) from MYSORT
   >> System error:
   The value
  (-1 1)
is not of type
  NUMBER
when binding SB-KERNEL::X

---- SNIP ----
)abbrev package MYSORT MySort

MySort() : Exports == Implementation where

    Exports ==> with
        mysort : List(List(Integer)) -> List(List(Integer))
    Implementation ==> add

        if List(List(Integer)) has OrderedSet then
            mysort lst ==
                sort(lst)
        else
            error "nope"
---- SNIP ----

I also tried whether I could replicate such an issue with Aldor, but interestingly this just goes
through without any issues:

---- SNIP ----
#include "fricas"

aldorsort(lst: List(List(Integer))) : List(List(Integer)) == {
    sort(lst)
}
---- SNIP ----

(5) -> aldorsort(test)
   (5)  [[- 1, 1], [1, 2], [2, 1]]
                                                    Type: List(List(Integer))

Waldek Hebisch

unread,
Feb 3, 2021, 10:41:13 PM2/3/21
to fricas...@googlegroups.com
Error looks like compiler bug. However, the correct conditon
is different, and then AFAICS code works:

if List(Integer) has OrderedSet then
mysort lst ==
sort(lst)

In this case workaround is simpler:

mysort lst == sort(_<, lst)

That is explicitely pass sorting predicate to two argument sort.

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