Carl Love

Carl Love

28075 Reputation

25 Badges

13 years, 58 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

With a few modifications (fewer than I was anticipating), we can preserve the exact parameter sequence of the input procedure, meaning that the output procedure will include any parameter type declarations and default-value parameter assignments from the input. This involves a "transplant surgery" of the parameter sequence between the inert forms of the input and output procedures.

Params:= proc(f::procedure)
option remember;
local 
    PSq:= op(1, ToInert(eval(f))), #_Inert_PARAMSEQ(...)
    r:= [op(map(Param, PSq))]
; 
    if r[-1]="$" then
        error "end-of-parameters marker $ not allowed"
    else
        convert~(parse~(r), `local`), 
        PSq, 
        hastype(PSq, specfunc(_Inert_ASSIGN))
    fi
end proc
:
#This didn't need any changes. I just changed the indentation:    
Param:= (e::function)->
    if e::specfunc({_Inert_NAME, _Inert_ASSIGNEDNAME}) then 
        op(1,e)
    elif e::specfunc({_Inert_ASSIGN, _Inert_DCOLON}) then 
        op(thisproc(op(1,e)))
    elif e::specfunc(_Inert_SET) then
        error "keyword parameters not allowed", FromInert(e)
    else 
        error "unknown InertForm", e
    fi
:
Iter:= proc(f::procedure, n::nonnegint, p::posint:= 1)
local P, PSq, proc_flag, body, form;
    if n=1 then return eval(f) fi;
    (P, PSq, proc_flag):= Params(f);
    body:= 
        `if`(n=0, P[p], f(P[..p-1][], thisproc(f, n-1, p)(P[]), P[p+1..][]))
    ;
    form:= `if`(proc_flag, proc(_P) _F end proc, _P-> _F); 
    FromInert(subsop(1= PSq, ToInert(subs(_P= P[], _F= body, eval(form))))) 
end proc
:
#Examples:
y:= 1: #Global assigned value, for testing

for k from 0 to 3 do
    Iter((x::{name, function}, y, z)-> f(x,y,z), k) 
od;  
     (x::{name, function}, y, z)-> x 
     (x::{name, function}, y, z)-> f(x, y, z)
     (x::{name, function}, y, z)-> f(f(x, y, z), y, z)
     (x::{name, function}, y, z)-> f(f(f(x, y, z), y, z), y, z)

#If there are parameters with default values, then both the input and
#return procedures must be in proc form:
for k from 0 to 3 do 
    Iter(
        proc(x::{name,function}, y, z::{name,function,posint}:= 3) 
            f(x,y,z) 
        end proc, 
        k, #kth iterate
        2  #Iterate on the 2nd position
    ) 
od;
proc (x::{name, function}, y, z::{name, posint, function} := 3) 
    y 
end proc
proc (x::{name, function}, y, z::{name, posint, function} := 3) 
    f(x, y, z) 
end proc
proc (x::{name, function}, y, z::{name, posint, function} := 3) 
    f(x, f(x, y, z), z) 
end proc
proc (x::{name, function}, y, z::{name, posint, function} := 3) 
    f(x, f(x, f(x, y, z), z), z) 
end proc

 

@auliani3 There are 2- and 3-route solutions both in Brian Bovril's integer linear programming worksheet and in VV's "brute force" plaintext code.

@acer If by "nice form" you mean with no "large" square roots (i.e., no square roots of non integers), I can get that for sin(Pi/7) with evala(Normal(simplify(...))). In the following worksheet, `CPi/14` stands for cos(Pi/14), etc.
 

restart:

CP:= expand(cos(7*x));

64*cos(x)^7-112*cos(x)^5+56*cos(x)^3-7*cos(x)

`CPi/14`:= allvalues(RootOf(subs(cos(x)= _Z, CP), evalf(cos(Pi/14))));

(1/12)*6^(1/2)*((-28+(84*I)*3^(1/2))^(1/3)*((-28+(84*I)*3^(1/2))^(2/3)+14*(-28+(84*I)*3^(1/2))^(1/3)+28))^(1/2)/(-28+(84*I)*3^(1/2))^(1/3)

`CPi/7`:= eval(expand(cos(2*x)), cos(x)= `CPi/14`);

(1/12)*((-28+(84*I)*3^(1/2))^(2/3)+14*(-28+(84*I)*3^(1/2))^(1/3)+28)/(-28+(84*I)*3^(1/2))^(1/3)-1

`SPi/7`:= (numer/denom)(evala(Normal(simplify(eval(sqrt(1-x^2), x= `CPi/7`)))));

-(1/336)*7^(1/2)*(I*(-28+(84*I)*3^(1/2))^(2/3)*3^(1/2)+(4*I)*(-28+(84*I)*3^(1/2))^(1/3)*3^(1/2)-(-28+(84*I)*3^(1/2))^(2/3)-8*(-28+(84*I)*3^(1/2))^(1/3)+56)

evalf(abs(sin(Pi/7)-`SPi/7`));

0.5061624214e-9

 


 

Download sin_Pi_over_7.mw

I don't know how it could happen, but it looks like displayprecision was set to 7, but only inside the plot window. Yeah, it could be a bug, but there's much less chance of fixing it if it's not known how to reproduce it.

@tomleslie Thank you, Tom, for stepping up.

@Stretto Using 1D Input (aka Maple Input), enter the command that I originally gave, a %/ b * c. If you don't know what 1D Input means, I'll explain later. 

This should work in any input mode: 

`%/`(a,b)*c

but hopefully you won't need to "go there".

My comments about needing parentheses and needing to see the worksheet pertained to your examples with 3s and exponents, not to your original Question.

@Stretto I understand (and did understand) exactly what you want; no further explanation of that is necessary; I don't need to see (nor did I ask to see) a worksheet of your original problematic output; I know that it puts under c. In order to help you properly, I need to see the output of

interface(version); interface(prettyprint); interface(typesetting);

You make it exasperating for us to help you, and exasperating for yourself, by going off on tangents, such as what happens for expressions with exponents.

 

@Rouben Rostamian Your solution works if k evaluates to a name (as opposed to, say, a number), and f behaves reasonably when given symbolic input. If either of these things are not true, unevaluation quotes are needed, as in

['f(k)' $ 'k'= 0..5]

One thing that I like about is that it doesn't require introducing a bound variable, the k in this case.

If speed is a concern, seq is usually faster than either of these, and also faster than map. Unfortunately seq has ugly syntax.

@Stretto You're right, it's no different. To answer properly, I need to see exactly how it displays on your screen. Can you post an executed worksheet?

If you're using the command-line interface, I don't think that it's going to be possible to get the display that you want.

If you want it to simplify to 9, just use the regular operators, not the inert ones.

@Stretto Unfortunately, the operators do not have the same precedence as their regular counterparts. I'll admit that this is bad design on Maple's part. So, you need to use parentheses to clarify:

(3^3) %/ 3

This is different from (3^3)(%/3). This latter expression is probably something that you'd never actually want. And I'll explain what it does, if you'd care to know.

To answer properly, I need to know exactly how the output of the things that you show appears on the screen. The copy-and-paste mangles it.

If you give the command 

interface(displayprecision);

what is the result? If it's anything other than -1, then do

interface(displayprecision= -1);

Then explicitly delete the plot output (Ctrl-Delete), and rerun the plotting command. I'm just guessing that this might work.

@CyberRob The problem is that in what you said that you were "expecting", you have treated nurdel differently from the other variables. The operand numbers that Kitonum used are the only needed for that special treatment. I think that you just made an oversight about nurdel. In that case, the solution given by simply factor should be good enough.

Acer, I'd be pleased to see your critique of the above. It's the first time that I've done "surgery" on ToInert of a procedure.

@shkarah Since I don't use or even have a copy of Excel, it'd likely be better if someone else answers.

Show me what happens when you use the command that I gave you:

ExcelTools:-Export(op([1,1], P[H]));

@Stretto 

You can give parameters default values like this:

f:= proc(x, y:= 1) x^2+y^2 end proc:
f(3), f(3,2);
                             10, 13

The syntax rules for this are

  1. It must be a proc, not an arrow expression (lambda expression).
  2. Parameters with default values must occur after those without them (if there are any).
First 228 229 230 231 232 233 234 Last Page 230 of 709