On Fri, May 17, 2024 at 10:11:18AM +0200, Ralf Hemmecke wrote: > Dear Wakdek, > > your recent contribution of rsimp is not totally satisfactory to me, since > it applies only to expressions that start with an 'nthRoot operator. It's a > good service function, but I wanted something that also applies to > combinations of such expression. So I wrote the following function to apply > rsimp recursively. > > ZZ ==> Integer > EXZ ==> Expression ZZ > recursiveRootSimplification(x: EXZ): EXZ == > liu: Union(List EXZ, "failed") := isTimes x > liu case List EXZ => > reduce(_*, [recursiveRootSimplification(z) for z in liu], 1) > liu := isPlus x > liu case List EXZ => > reduce(_+, [recursiveRootSimplification(z) for z in liu], 0) > is?(x, 'nthRoot) => > r: Kernel EXZ := retract(x)@Kernel(EXZ) > a: List EXZ := argument retract x > ra: EXZ := recursiveRootSimplification(a.1) > ex := if #a < 2 then sqrt(ra) else ra^(1/a.2) > u: Union(EXZ, "failed") := rsimp(ex)$RootSimplification > u case "failed" => ex > u :: EXZ > x > > Do you think that it makes sense to include that somewhere (where?) in > FriCAS? > > I do not care much about the name except that it should have no > abbreviation. > > The specification of rsimp does not say much about validity of the > transformation, i.e. whether x and rsimp(x) are actually the same root (over > complex numbers). Or do we have a statement in FriCAS about which of the n > possible values of an nthRoot expression, the nthRoot expression actually > represents. > > With recursive application that could lead to a completely different root > value. Maybe that must be either said in the documentation or some numerical > code must be added to ensure that not suddenly a different branch is chosen. Concerning specification: 'rsimp' is working with _fields_, not numbers. More precisely, 'rsimp' works with generators and "field descriptors". "Field descriptor" tells you how to build a field starting from base field (that is field of rational numbers or field or rational functions). 'rsimp' works with algebraic extentions of base field. Such extention is built adding successive generators and descriptor tells you minimal polynomial of new generator in terms of previously added generators. 'rsimp' is supposed to produce field that is izomorphic to input field, but has lower nesting depth.
Taking about field descriptors may be intimidating for users and also we need an easy way to specify field descriptor. Those two problems are solved by using expressions as field descriptors. More presicly, 'nthRoot' specifies apropriate field extention and simultaneously serves as generator of this extention. There is a catch here: not all expressions actually define fields. To define a field roots appearing in the expression must be independent. By extention, roots created by 'rsimp' should be independent. Concerning exact specification, 'rsimp' tries to find izomorphic field with description of lower nesting depth. AFAIK there are open theoretical questions about what exacly is possible. In particular, it seems that there are fields which can not have description with lower nesting depth, but which can be embedded in bigger field of lower nesting depth. However, here detailed problem statement matters a lot. AFAIK using my definitions problem is open. 'rsimp' is using approach which is usually called "Zippel denesting". Again, characterizing cases when this approach works is an open problem. I mean, one can write condtions which must be satisfied at each step, but since 'rsimp' transforms field descriptors in each step it is not clear how to simply formulate needed condition in terms of input data. Concerning extentions: I plan to substantially extend 'rsimp'. Some extentions look quite easy, but there is question of specification and efficiency. Namely, "well specified" "easy" extentions heavily use factorization which may lead to quite long execution time. In some cases it is possible to use cheaper methods, but that needs more code. Having said that, as long as you do not require much removing restriction on having single kernel looks easy. I consider recursive apprach like you used as completely inappropriate. First, recursive approach tends to repeat similar calculations, so it make efficiency problems worse. Second, trying to handle parts of expression like you do is likely to introduce dependent roots, which means that we no longer have a field and leads to various troubles. Concerning branches: from algebraic point of view all branches are equivalent (as long as kernels are independent). In other words, choice of branches is extenal to 'rsimp', 'rsimp' simply must be careful to avoid creating dependent roots. Of course, users may use some "established" convention like principal branch. In the future I will probably add some code to make behaviour with such conventions better. For numbers in principle it is possible to use numerical computations to track branches. This may need rather large accuracy, but other computations in 'rsimp' may be quite costly, so probably numerical computations have acceptable cost. Still, tracking needed accuracy requires appropriate code. Also, from my point of view important advantage of 'rsimp' is that it can deal with functions. But for functions principal branch convention usually leads to troubles: one have to spend large effort to get principal branch and frequently this is wrong branch, so this effort is wasted. -- Waldek Hebisch -- You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group. To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/fricas-devel/ZkdMrsmVz1MLj01M%40fricas.org.