Carl Love

Carl Love

28035 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

Change the command solve(sys) to solve(sys, explicit). Then the results will be expressed as square-root expressions rather than RootOf.

The easiest change that you can make to correct the code is to change vector to Vector (uppercase V). The vector, with a lowercase v, is from a much older version of Maple. There's no reason to use the old form.

Yes, it's very easy. Wherever 10 appears in the format string, replace it with an asterisk *. Then in the sequence of values that fill formats, use decimals, value1, decimals, value2. This is IMO more robust than Acer's method and also consistent with standard C-language usage.  However, it does produce more-cryptic code. 

The observed phenomenon has nothing to do with tilde or map. The difference is between `convert/string`(...and convert(..., string) when those are applied an object of type symbol that contains nonstandard characters and is thus enclosed in backquotes. The conversion from symbol to string is a primitive, kernel operation when done as convert(..., string); it doesn't involve a call to the Maple-level procedure `convert/string`. When that procedure is called, the extra quotes are used. 

The proper use of map is map(convert, L, string). The proper use of tilde is convert~(L, string). They produce identical results. Clearly, the tilde form is more compact and produces easier-to-read code.

It's not ~y; the relevant strings are *~ and /~. These are elementwise operators. See ?elementwise. For example, suppose the A and B are sets or lists of the same size or rtables of the same size and shape. Then A *~ B is equivalent to zip(`*`, A, B), i.e., it produces a set, list, or rtable whose entries are the products of the corresponding elements of A and B.

Set interface(prettyprint= 2, labelling= true) and it'll work.

Here's an overload of eval that makes it smarter. My intention is that it's smart enough to convert any bound variable used inside a procedure to a local.

restart:
local eval;

Warning....
eval:= proc(e::uneval, V::{posint, name= anything, {list,set}(name= anything)})
local r, v;
     if nargs=1 then :-eval(e)
     elif V::'posint' then :-eval(e,V)
     else
          v:= {`if`(V::`=`, V, V[])};
          r:= :-eval(
               evalindets(
                    e,
                    function,
                    f-> subs(map(x-> lhs(x)= convert(lhs(x), `local`), v), :-eval(op(0,f)))(op(f))
               ),
               v
          );         
          if procname::'indexed' and op(procname) = 'recurse' then
              r:= `if`(:-eval(r = e), :-eval(r), eval['recurse'](:-eval(r),v))
          else r:= :-eval(r)
          end if;
          `if`(op(0,r) = :-eval, 'eval'(op(r)), r)   
     end if
end proc:         

Now, your examples:

g:= a-> int(x+a, x= a..2*a):
:-eval(g(x)=g(z), [x,z]=~ 1);  #without Carl's correction

     3 = 5/2
eval(g(x)=g(z), [x,z]=~ 1);  #with Carl's correction
     5/2 = 5/2
(:-eval = eval)(g(x), x= 2*x);
     12*x^2 = 10*x^2

g:= a-> int(sin(sin(x+a)), x= a..2*a):
evalf(:-eval(g(x)=g(z), [x,z]=~ 1));  #without Carl's correction
   
     .105207050696364 = .529440545264378
evalf(eval(g(x)=g(z), [x,z]=~ 1));  #with Carl's correction
     .529440545264378 = .529440545264378

And here are some examples for Edgardo to consider:

g:= a-> sum(f(x+a), x= a..2*a):
:-eval(g(x)=g(z), [x,z]=~ 1);  #without Carl's correction

     f(2)+f(4) = f(2)+f(3)
eval(g(x)=g(z), [x,z]=~ 1);  #with Carl's correction
     f(2)+f(3) = f(2)+f(3)

Physics:-Setup(redefinesum= true):
:-eval(g(x)=g(z), [x,z]=~ 1);  #without Carl's correction

     sum(f(2*x), x = x .. 2*x) = f(2)+f(3)
eval(g(x)=g(z), [x,z]=~ 1);  #with Carl's correction
    
f(2)+f(3) = f(2)+f(3)

[Edit 1: Code corrected and example added due to VV's comment.]
[Edit 2: Code updated to work with eval's recurse option and to return unevaluated when appropriate.]

What you're calling a chimera is technically known to logicians and computer scientists as a "bound variable". The command depends and the types dependent and freeof are used to detect them or their absence. However, those commands are irrelevant to your dsolve question because there's an easy way to deal with that: option known. Here's an example:

alpha:= proc(x)
local t;
     if not x::numeric then return 'procname'(args) end if;
     evalf(Int(sin(t^3)*cos(t^2), t= 0..x))
end proc:

Sol:= dsolve({diff(y(x), x) = alpha(x)*y(x), y(0)=1}, numeric, known= [alpha]);

Note that the procedure alpha must contain the line that makes it return unevaluated when it gets non-numeric input.

Please don't post Questions as Posts. I already moved this one.

The letter e isn't a predefined value in Maple. To get e^5, you need to use exp(5).

The problem is that (unfortunately) Heaviside(a::algebraic) evaluates to something other than itself: It evaluates to Heaviside(a)! My preference would be that it return an error message. Perhaps this should be considered a bug of Heaviside. We can quickly look through the code showstat(Heaviside) and see where things go wrong. The argument a::algebraic passes through the type check in the proc line because an expression of the form a::b is of type algebraic! (I think that this should be considered the real bug.) Then between lines 23 and 24, the argument passes the type check linear(a). (This should also be considered a bug.) Then in line 30, the return value is set to Heaviside(a). Many other standard procedures, such as sin, return unevaluated when passed a::b.

All of the bugs mentioned above would be fixed if type(a::b, algebraic) returned false. According to ?type,algebraic, it should return false because `::` is not one of the 13 types listed, and a::b typechecks as false against all 13.

Now, turning to your patmatch command: patmatch(Heaviside(x), Heaviside(a)) returns false because the arguments aren't identical. There's no real pattern in the second argument because there's no ::. A perfect identity match is expected for any parts of the pattern for which there's no ::. This also explains why it returns true when you change a to x.

The difference between patmatch and typematch is that patmatch accepts as its second argument patterns which are far more complex than those allowed by typematch. The latter basically only allows type expressions prepended with name::. Examples:

patmatch(x+2, a::name + n::posint) returns true.
typematch(x+2, a::name + n::posint) returns an error message because name+posint isn't a valid type.
typematch(Heaviside(x), Heaviside(x)) returns an error message because x isn't a valid type.

I find Christian's explanation of the difference quite confusing and misleading, although it's technically correct, I guess.

 

If you use lprint on the results, you'll see that they are essentially the same. A 1-D Array whose indices start at 1 prettyprints as if it were a Vector, and 2-D Array both of whose indices start at 1 prettyprints as if it were a Matrix. Using lprint reveals the true nature of things.

Basically, prettyprinting allows almost anything to be displayed as if it were something else without changing the underlying value. If I wanted sin(1) to display as 42, I could write a one-line procedure to do that. Of course, prettyprinting is only useful when it shows some useful mathematical representation of the underlying object. Since a 1-D Array with indices starting at 1 is essentially a Vector, that's appropriate here.

Your code above the fsolve does not define, or even use at all, any variables named Eq1 or Eq2, yet you refer to them in the fsolve command.

See ?Statistics,Lowess. One of the examples shows doing an integration.

The basic command for this is ListTools:-Classify. But it returns the elements themselves rather than their position numbers. You need to pair each element each with its position number (that's the `[]`~(a, [$1..nops(a)]) below), Classify according to the first element (x-> x[1]) of each pair, and then extract the position numbers (x-> x[2]):

{entries(((x-> x[2])~)~(ListTools:-Classify(x-> x[1], `[]`~(a, [$1..nops(a)]))), nolist)};

     {{1}, {3}, {2, 4}}

If you require that the results be returned as lists and in the order that you specifed, that can be easily done.

By the way, is there some good reason why each element of your list a is itself a list? My code above doesn't care about that, but it makes me wonder whether I am missing some nuance of your problem.

Letting p be your polynomial, it can be done like this:

v:= indets(p, suffixed({x,y,z})):
coeffs(p, v, 'M'):
[op(sort(`+`(M), order= plex(ListTools:-Reverse([v[]])[]), descending))];

First 210 211 212 213 214 215 216 Last Page 212 of 395