Carl Love

Carl Love

28015 Reputation

25 Badges

12 years, 300 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@AlexeyK Please let me know if you've been able to put any of these ideas into use, or whether you need further assistance and/or deeper explanations.

@janhardo Using the module TS from above, you can get your "book form" via

TS:-Mn(2):
TS:-Mn(i):
TS(i/(2*b))*ln(``(b*i+z)/(b*i-z));

And that can be reverted to Maple/math/active form via

subs(i=I, TS:-Value(%));

However, I think that you're also asking whether the "book form" can be produced via some automatic "simplification" process starting from Maple's output. No, because the book form has arbitrarily placed extra parentheses. There's no sensible and unambiguous rule that would place extra parentheses around b*i+z but not also around b*i-z or 2*b.

@Carl Love Here is some exposition of the "behind-the-scenes magic" that I referred to, as well as proof that the overridden method (move in this case) is a static export of the child class (dog in this case) distinct from its parent method (animal:-move), even though the method is not explicitly declared static in the child.

restart
:
animal:= module()
option object;
export 
    data1,
    move::static:= proc(_self, $) print("In Animal") end proc
;
end module:
 
#create class/module which extends the above
dog:= module()
option object(animal);
    move:= proc(_self, $) print("In Dog") end proc  
end module
:
Bear:= Object(animal):  Bear:-data1:= "bear":
Daisy:= Object(dog):  Jake:= Object(dog):
Daisy:-data1:= "beagle":  Jake:-data1:= "spaniel":
move(Daisy); move(Jake);
                            "In Dog"
                            "In Dog"
ToInert(Daisy);
_Inert_MODULE(_Inert_EXPSEQ(_Inert_ASSIGNEDLOCALNAME("data1", 
  "STRING", 36893491093222321372)), _Inert_MODDEF(
  _Inert_PARAMSEQ(_Inert_NAME("thismodule")), _Inert_LOCALSEQ(), 
  _Inert_OPTIONSEQ(_Inert_FUNCTION(_Inert_NAME("object"), 
  _Inert_EXPSEQ(_Inert_ASSIGNEDNAME("animal", "MODULE", 
  _Inert_ATTRIBUTE(_Inert_EXPSEQ(_Inert_NAME("protected", 
  _Inert_ATTRIBUTE(_Inert_NAME("protected"))), _Inert_NAME(
  "protected", _Inert_ATTRIBUTE(_Inert_NAME("protected"))))))))), 
  _Inert_EXPORTSEQ(_Inert_NAME("data1")), 
  _Inert_STATSEQ(_Inert_EXPSEQ()), _Inert_DESCRIPTIONSEQ(), 
  _Inert_GLOBALSEQ(), _Inert_LEXICALSEQ(), _Inert_EXPSEQ(), 
  _Inert_STATICLOCALSEQ(), _Inert_STATICEXPORTSEQ(
  _Inert_ASSIGNEDLOCALNAME("move", "PROC", 36893491093222288092))), 
  _Inert_EXPSEQ())

ToInert(Jake);
_Inert_MODULE(_Inert_EXPSEQ(_Inert_ASSIGNEDLOCALNAME("data1", 
  "STRING", 36893491093222321500)), _Inert_MODDEF(
  _Inert_PARAMSEQ(_Inert_NAME("thismodule")), _Inert_LOCALSEQ(), 
  _Inert_OPTIONSEQ(_Inert_FUNCTION(_Inert_NAME("object"), 
  _Inert_EXPSEQ(_Inert_ASSIGNEDNAME("animal", "MODULE", 
  _Inert_ATTRIBUTE(_Inert_EXPSEQ(_Inert_NAME("protected", 
  _Inert_ATTRIBUTE(_Inert_NAME("protected"))), _Inert_NAME(
  "protected", _Inert_ATTRIBUTE(_Inert_NAME("protected"))))))))), 
  _Inert_EXPORTSEQ(_Inert_NAME("data1")), 
  _Inert_STATSEQ(_Inert_EXPSEQ()), _Inert_DESCRIPTIONSEQ(), 
  _Inert_GLOBALSEQ(), _Inert_LEXICALSEQ(), _Inert_EXPSEQ(), 
  _Inert_STATICLOCALSEQ(), _Inert_STATICEXPORTSEQ(
  _Inert_ASSIGNEDLOCALNAME("move", "PROC", 36893491093222288092))), 
  _Inert_EXPSEQ())

ToInert(Bear);
_Inert_MODULE(_Inert_EXPSEQ(_Inert_ASSIGNEDLOCALNAME("data1", 
  "STRING", 36893491093222319868)), _Inert_MODDEF(
  _Inert_PARAMSEQ(_Inert_NAME("thismodule")), _Inert_LOCALSEQ(), 
  _Inert_OPTIONSEQ(_Inert_NAME("object")), 
  _Inert_EXPORTSEQ(_Inert_NAME("data1")), 
  _Inert_STATSEQ(_Inert_EXPSEQ()), _Inert_DESCRIPTIONSEQ(), 
  _Inert_GLOBALSEQ(), _Inert_LEXICALSEQ(), _Inert_EXPSEQ(), 
  _Inert_STATICLOCALSEQ(), _Inert_STATICEXPORTSEQ(
  _Inert_ASSIGNEDLOCALNAME("move", "PROC", 36893491093222287868))), 
  _Inert_EXPSEQ())

Note that the address of procedure move is the same for the two dogs, but different than the address of move in the animal.

@AlexeyK You wrote:

  • Concerning passing n: it's really a minor issue, but I caught myself on the thought that once you have evaluated the number of variables in the main procedure, it could be worth just assigning it to a variable and then passing it everywhere it is needed (thus, you don't need to evaluate the length again - a kind of optimality in terms of a number of operations). What do you think?

I agree, partially. The part that I agree with is that it's good to avoid recomputation. The part that I disagree with is that passing extra arguments is a good way to achieve that.

Maple has several ways to do it without passing extra arguments. Off the top of my head, the ways that I can think of are remember tables, Records, and objects. I'll describe remember tables, the easiest to use of those three.

A remember table is a component added to a procedure such that when the procedure is called with arguments with which it has previously been called, it automatically returns what it returned the last time without executing the procedure at all. This all happens behind the scenes; all that you need to do is add option remember to the procedure. So, for the case that we're talking about here, you can do this:

Arity:= 
    proc(f::procedure) option remember; nops([op](1, eval(f))) end proc
:
UV:= (f::procedure)-> 
    local x, y, XY:= map2(index~, [x,y], [$1..Arity(f)]);
    map(unapply, (evalc@[Re,Im]@f@op@(Complex@op)~)(XY), op~(XY))
:

@nm The validity of variable::type:= ... (including return-value) assertions other than for procedure parameters is checked if and only if assertlevel=2, and that checking is the only purpose of assertlevel=2. This checking must be done at run time rather than at compile (or parse) time, so it's expensive. In the case at hand, the move::static:= ... statement was in the body rather than the declarations of module dog, so, like all module bodies, it was executed immediately (which is why that code needs to be put in a ModuleLoad if the module is stored in a library).

@nm Sorry, I was undergoing a dental procedure when I sent the "Remove 'static'" message. I now see that this part may not have been obvious: I only meant for you to remove the 2nd static, the one in dog. This will work under assertlevel=2, and move will still be static because it's declared static in animal. Note that move is not being declared in dog; rather, the move that was already declared in animal is being reassigned. Through some behind-the-scenes magic that I don't understand, the dog object nonetheless retains a local copy of move.

@nm Try removing static.

@janhardo plotcompare does side-by-side plots. And, despite its somewhat generic name, it's specifically for complex functions. And two things you should know about its help page:

  • It's one of most-well-written and most-extensive help pages in all of Maple.
  • You'll learn a lot of complex analysis just from reading the help page, including how to find branch cuts on plots.

@pengcheng Xue So, using the variables already defined in your previous worksheet, the matrix to pass to approxsoln is simply

A:= <<s3[]> | s2>:

@AlexeyK 

I think that the most potentially confusing concept that the help page ?@ fails to illustrate adequately is that f@g also works when returns a sequence rather than a single value, provided that f is prepared to accept the number of arguments that g returns. In the example at hand, op is an operator that returns a sequence. The op in the subexpression Complex@op returns a pair (x[k], y[k]) for some between 1 and n, and Complex[*1] will accept two arguments. The op in the subexpression f@op returns exactly n values of the form Complex(x[k], y[k]), and f is expecting exactly n arguments. (We say that f is n-ary or that its arity is n.)

Recall from my Answer that I explained that it's not necessary to pass n. With the list-based functional-programming style that I've used, it's not even necessary to assign n as a local, its value being implicit as the length of list XY.

Footnote:
[*1] Complex(x,y) is almost the same thing as x+I*y, the difference here being that it'll remain unevaluated when x and y are just names. But, of course, it's handled sensibly by ReIm, and evalc or else it'd be worthless here. This distinction is not needed in procedure UV; I could just as well have replaced Complex with ((x,y)-> x+I*y)

@janhardo So, when you change it to x= -1..1, does it "work"?

You wrote:

  • The idea was only to show two plots besides eachother for a complex plot with a real and imaginair part. 

You should use plotcompare for that.

@AlexeyK

First, note that XY = [[x[1],y[1]], [x[2],y[2]], ..., [x[n],y[n]]]. Then

(evalc@[Re,Im]@f@op@(Complex@op)~)(XY)

means the same thing as

fxy:= f(op(map(xy-> xy[1]+I*xy[2], XY)));
evalc([Re(fxy), Im(fxy)]);

Does that help?

@janhardo What is x= 1..1 supposed to mean? Did you mean x= -1..1?

@pengcheng Xue I can't do anything with that data file until you give some description. Tell me what precisely the jth number in the ith row represents. Why are there 70 columns? Is it because there are 70 different values of x? If so, are those x values one row of the file? Do those x-values include the two boundary points?

Are there any derivatives higher than 1st order in the ODEs?

@AlexeyK If the following two reasonable conditions are met, then there's no need to pass into MainFunc; the can be determined from F. The conditions are

  1. All of the variables in all of the members of are intended to be complex-valued parameters of the resulting procedures.
  2. You're willing to use some standard order, such as alphabetical order, for the parameter sequences.

In that case, can be constructed by 

Z:= sort([indets(F, And(name, Not(constant)))[]], 'key'= (x-> ""||x));

First 104 105 106 107 108 109 110 Last Page 106 of 708