Joe Riel

9660 Reputation

23 Badges

20 years, 10 days

MaplePrimes Activity


These are replies submitted by Joe Riel

I like the simple, compact code you wrote. There is a minor problem. In general, op(0,expr) is not a constructor for expr. For example, list(1,2,3) does not produce the list [1,2,3]. So fromTree fails with expressions consisting of lists or sets. A minor bug, easily correctible, is the use of i (a global) in the call to seq in fromTree. There are some situations where that can cause weird problems. One way to avoid it is to use proc and declare i as a local. Another way is to use map:
fromTree := x -> `if`(op(x) = x, x, x[1](map(procname, x[2..-1])[])):
Because it seems clearer to test for a list, I prefer
fromTree := x -> `if`(x::list, x[1](map(procname, x[2..-1])[]), x);
While no better, the little used builtin `?()`, normally used in an overload, could be used here,
fromTree := x -> `if`(x::list, `?()`(x[1], map(procname, x[2..-1])), x);
Here's a very compact, but somewhat less efficient technique (an unneeded call to fromTree is made):
fromTree := x -> `if`(x::list, apply(map(procname, x)[]), x);
You might want to consider writing this as a module. To get you started, here's a module with a single export, latex, that replaces Maple's latex procedure. The new procedure returns a string rather than prints to the output; that avoids using temporary files. Modified message: fomatted Maple code using the pre tag.
MyLaTeX := module()
export latex;
local buf,ModuleLoad;

    ModuleLoad := proc()
    description "replace print routine in global latex to append to the StringBuffer buf";
        buf := StringTools:-StringBuffer();
        :-`latex/lprint` := subs(printf = buf:-appendf, eval(:-`latex/lprint`));
        NULL
    end proc;

    latex := proc(expr)
    description "return a LaTeX string corresponding to the Maple input expression";
        buf:-clear();
        :-latex(expr);
        buf:-value()
    end proc;

    ModuleLoad()

end module:

output := MyLaTeX:-latex(hi);
      output := "{\it hi}
    "
Yes, but that is because there is no list to distribute over. `+`@op([1,2,3] evalutes to 6, which is then divided by 3 (nops([1,2,3]).
The theorems seem mostly worthless. Besides the error previously mentioned, the few I checked are overly conservative. Consider theorem 1:
floor(x)/(3*x+frac(x)) + frac(x)/(3*x+floor(x)) ≥ 4/15
The real limit should be 2/7, not 4/15. Similarly for theorem 6, the right side should be 4/3/x, not the conservative 1/x. Theorem 32 part 2 fails:
solve(y2 := abs(cos(floor(x))) + abs(cos(frac(x))) - abs(cos(x));
fsolve(y2, x=2.9..3);
                                2.966118521
limit(y2, x=3, left);
                           -cos(2) + cos(1) + cos(3)
evalf(%);
                                 -0.0335433542
So does Theorem 25, at multiple locations for x < 0:
y := abs(sin(floor(x))) + abs(sin(frac(x))) + abs(cos(x)):
plot([1,y], x=-10..4);
limit(y, x=-2, left);evalf(%);
                                sin(3) - cos(2)

                                 0.5572668446
The reason it works is that Maple can apply arguments to an algebraic expression. See ?evalapply for details. For example,
(3*f+a/b)(1,2);
                    3*f(1,2) + a(1,2)/b(1,2)
Division by a numeric quantity is distributed over a list. See my previous response in this thread.
To the careful observer, there is at least one piece of magic remaining in Robert's explanation. That is, Maple automatically distributes multiplication (and division) by numeric values over lists. For example,
3*[a,b,c];
                  [3*a, 3*b, 3*c]
This does not occur for elements that are not of type numeric, nor if any term (besides the list) is nonnumeric, unless one of the elements is equal to zero. Nor does it work over sets.
3*I*[a,b,c];
                 3*I*[a,b,c];
3*a*I*[a,b,c]*0;
                    a*[0,0,0]
In the first assignment to Mean4, curry(map,`+`@op)/nops, nops returns an integer which is then distributed over the list(list) structure.
Rather than tell you the answer, I'll give you a hint. You can modify
curry(map,`+`@op/nops);
to return a "procedure" that divides by the number of lists, rather than the number of items in each list, by shifting the position of one character. That is, move one of the characters in the code.
Typing _passed makes no sense and cannot be done. _passed, which is equivalent to args (an older name for the same thing), is a special symbol assigned the sequence of arguments actually passed to a procedure. The expression _passed(args) is equivalent to args(args). I doubt there is ever a practical use for that construction.
frontend(coeff, [step21,ep,2]);
will also do the trick.
Which was why I suggested it wasn't appropriate for "production". That and the complete lack of type checking. I haven't read the actual problem statement, does it define what to do with an empty list? Note, also that the empty list [] type-matches list(list), so that must be dealt with as well. Possibly the input arguments should be declared as list(list(algebraic)).
Alas, it looks better than it works. I had tested it, but with several others, at once, and didn't notice that it didn't actually work. `+` doesn't work on a list, but rather on a sequence. It can be salvaged with
Means3 := curry(map,`+`@op/nops);
but that isn't as nice looking.
How 'bout
Means3 := curry(map,`+`/nops):
I wouldn't recommend that for production work, but it is nice and short and does the job.
For the record, the same problem occurs on a Linux machine, so it is very likely to also occur on a Mac.
I hear you on Eclipse; I installed it once to see what the fuss was about, but once I saw how slow it was coming up, I immediately canned it. Of course, I likely wouldn't have kept it anyway, but I would have had less reason.
Does it make sense to consider eigenvalues of boolean matrices? They don't even form a ring.
First 157 158 159 160 161 162 163 Last Page 159 of 195