Alejandro Jakubi

MaplePrimes Activity


These are replies submitted by Alejandro Jakubi

@erik10 

I think just because it was not implemented. I do not see any good reason why it wasn't, and this imposibility is not properly documented.

@erik10 

No, I think that the documentation on this subject, lists and sets is not fine. In particular, a topic search in the Standard GUI help browser for "examples", or in ?examples,index , shows no entry for ?examples,list or ?examples,set , something that looks very basic, as you say.

Certainly, in most usage situations, poor documentation is the key inefficiency factor...

This is an interesting question. The code of (the library part of) `<,>` checks in line 1 for type scalar in its arguments. If one of them checks false, and there is more than one argument, it constructs a Matrix (line 6):

> showstat(`<,>`);
`<,>` := proc()
local x, dims, rows, cols, r, offset, i;
   1   if member(false,map(type,{args},'scalar')) then
   2     if nargs = 1 then
   3       if type(args,rtable) then
   4         Matrix(args)
           else
   5         Vector['column']([args])
           end if
         else
   6       Matrix([[args]],('scan') = ('columns'))
         end if
       else
   7     Vector['column']([args])
       end if
end proc

Now, ?type,scalar states:

A scalar is anything which is not a vector or matrix.

But, e.g. a list or a set check as not scalar, hence a "vector" or a "matrix", whatever is meant by that:

> type([1],scalar);
                                     false
> type({1},scalar);
                                     false

So, in my opinion, the bug is mainly in type(...,scalar) (its code, its design, its documentation, or some combination).

This is an interesting question. The code of (the library part of) `<,>` checks in line 1 for type scalar in its arguments. If one of them checks false, and there is more than one argument, it constructs a Matrix (line 6):

> showstat(`<,>`);
`<,>` := proc()
local x, dims, rows, cols, r, offset, i;
   1   if member(false,map(type,{args},'scalar')) then
   2     if nargs = 1 then
   3       if type(args,rtable) then
   4         Matrix(args)
           else
   5         Vector['column']([args])
           end if
         else
   6       Matrix([[args]],('scan') = ('columns'))
         end if
       else
   7     Vector['column']([args])
       end if
end proc

Now, ?type,scalar states:

A scalar is anything which is not a vector or matrix.

But, e.g. a list or a set check as not scalar, hence a "vector" or a "matrix", whatever is meant by that:

> type([1],scalar);
                                     false
> type({1},scalar);
                                     false

So, in my opinion, the bug is mainly in type(...,scalar) (its code, its design, its documentation, or some combination).

Or actually it is not much effort to write a transformation rule that holds everywhere on the complex plane by using the unwinding number (see ?unwindK ), which takes account of the branch cuts. For this purpose, it is convenient to use the customized command applyrule1 so that the rule is applied only once:

r11i:=z::algebraic^a::nonunit(algebraic)*w::algebraic^a::nonunit(algebraic)=
(z*w)^a*exp(a*2*Pi*I*unwindK(ln(z)+ln(w))): > applyrule1(r11i,(x)^(1/2)*(y)^(1/2)); argument(x) + argument(y) - Pi ceil(1/2 ------------------------------) 1/2 Pi (x y) (-1)

This means that there is no need to throw caution to the winds...

Or actually it is not much effort to write a transformation rule that holds everywhere on the complex plane by using the unwinding number (see ?unwindK ), which takes account of the branch cuts. For this purpose, it is convenient to use the customized command applyrule1 so that the rule is applied only once:

r11i:=z::algebraic^a::nonunit(algebraic)*w::algebraic^a::nonunit(algebraic)=
(z*w)^a*exp(a*2*Pi*I*unwindK(ln(z)+ln(w))): > applyrule1(r11i,(x)^(1/2)*(y)^(1/2)); argument(x) + argument(y) - Pi ceil(1/2 ------------------------------) 1/2 Pi (x y) (-1)

This means that there is no need to throw caution to the winds...

@Carl Love 

As documented in ?combine,power , the relevant transformation rule is the 6th one a^n*b^n ==> (a*b)^n, where as stated, a,b are integers >1  and n is rational. In this context, the symbolic option would play no role. Actually, some additional numeric cases for a,b are handled:

> combine((x)^(1/2)*(y)^(1/2), power, symbolic);
                                    1/2  1/2
                                   x    y
> combine((2)^(1/2)*(3)^(1/2), power);
                                       1/2
                                      6
> combine((1/2)^(1/2)*(1/3)^(1/2), power);
                                       1/2
                                      6
                                      ----
                                       6
> combine((-2)^(1/2)*(-3)^(1/2), power);
                                       1/2
                                     -6

Certainly, applyrule seems to me the simplest way to extend the stock of transformation rules.

@Carl Love 

As documented in ?combine,power , the relevant transformation rule is the 6th one a^n*b^n ==> (a*b)^n, where as stated, a,b are integers >1  and n is rational. In this context, the symbolic option would play no role. Actually, some additional numeric cases for a,b are handled:

> combine((x)^(1/2)*(y)^(1/2), power, symbolic);
                                    1/2  1/2
                                   x    y
> combine((2)^(1/2)*(3)^(1/2), power);
                                       1/2
                                      6
> combine((1/2)^(1/2)*(1/3)^(1/2), power);
                                       1/2
                                      6
                                      ----
                                       6
> combine((-2)^(1/2)*(-3)^(1/2), power);
                                       1/2
                                     -6

Certainly, applyrule seems to me the simplest way to extend the stock of transformation rules.

I agree, by automatic simplification (simpl), is, and a lot of other routines, from the packages SolveToolsPiecewiseTools, etc, are being called:

> stopat(is):
> assume(z>0, beta>0);
> b:= 3*beta*Pi*(3-4*cos(z)+cos(2*z))/(16*z):
> -b+sqrt(b^2);
is:
   1*  if _EnvInside_assume = true then
         ...
       else
         ...
       end if
DBG> where
TopLevel: -b+sqrt(b^2)
	[9/256*beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
sqrt:-ModuleApply: sqrt(op(1,x))*sqrt(subsop(1 = 1,x),args[2 .. nargs])
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
sqrt:-ModuleApply: s := signum(x)
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
signum: r := subs(_Envsignum0 = 0,`signum/main`(x,_Envsignum0))
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2, _Envsignum0]
`signum/main`: sg := signum(w)
	[beta^2]
signum: r := subs(_Envsignum0 = 0,`signum/main`(x,_Envsignum0))
	[beta^2, _Envsignum0]
`signum/main`: if type(op(2,x),'even') and Im(op(1,x)) = 0 and (member(Env,{1, '_Envsignum0'}) or is(op(1,x) <> 0)) then r := 1 elif type(op(2,x),'odd') and Im(op(1,x)) = 0 and (member(Env,{-1, 0, 1, '_Envsignum0'}) or is(op(1,x) <> 0)) then r := signum(op(1,x)) elif member(Env,{0, 1, '_Envsignum0'}) then r := signum(op(1,x))^op(2,x) end if
	[beta]
`simpl/Im`: `simpl/simpl/Im`(x)
	[beta]
`simpl/simpl/Im`: `simpl/simpl/Im/is`(x)
	[beta]
`simpl/simpl/Im/is`: t := traperror(is(x,'real'))
	[beta, real]
...

I agree, by automatic simplification (simpl), is, and a lot of other routines, from the packages SolveToolsPiecewiseTools, etc, are being called:

> stopat(is):
> assume(z>0, beta>0);
> b:= 3*beta*Pi*(3-4*cos(z)+cos(2*z))/(16*z):
> -b+sqrt(b^2);
is:
   1*  if _EnvInside_assume = true then
         ...
       else
         ...
       end if
DBG> where
TopLevel: -b+sqrt(b^2)
	[9/256*beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
sqrt:-ModuleApply: sqrt(op(1,x))*sqrt(subsop(1 = 1,x),args[2 .. nargs])
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
sqrt:-ModuleApply: s := signum(x)
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2]
signum: r := subs(_Envsignum0 = 0,`signum/main`(x,_Envsignum0))
	[beta^2*Pi^2*(3-4*cos(z)+cos(2*z))^2/z^2, _Envsignum0]
`signum/main`: sg := signum(w)
	[beta^2]
signum: r := subs(_Envsignum0 = 0,`signum/main`(x,_Envsignum0))
	[beta^2, _Envsignum0]
`signum/main`: if type(op(2,x),'even') and Im(op(1,x)) = 0 and (member(Env,{1, '_Envsignum0'}) or is(op(1,x) <> 0)) then r := 1 elif type(op(2,x),'odd') and Im(op(1,x)) = 0 and (member(Env,{-1, 0, 1, '_Envsignum0'}) or is(op(1,x) <> 0)) then r := signum(op(1,x)) elif member(Env,{0, 1, '_Envsignum0'}) then r := signum(op(1,x))^op(2,x) end if
	[beta]
`simpl/Im`: `simpl/simpl/Im`(x)
	[beta]
`simpl/simpl/Im`: `simpl/simpl/Im/is`(x)
	[beta]
`simpl/simpl/Im/is`: t := traperror(is(x,'real'))
	[beta, real]
...

@Kitonum 

Apparently, it understands in parts:

> is((3^n)::odd) assuming n::posint;
                                      true
> is((3^n)::odd) assuming n::0;
                                      true

But not together:

> is((3^n)::odd) assuming n::nonnegint;
                                      FAIL
> is((3^n)::odd) assuming n::{0,posint};
                                      FAIL
> is((3^n)::odd) assuming n::OrProp(0,posint);
                                      FAIL

Presumably, any such syntax should work the same as here:

> is((2*n+1)::odd) assuming n::nonnegint;
                                      true
> is((2*n+1)::odd) assuming n::{0,posint};
                                      true
> is((2*n+1)::odd) assuming n::OrProp(0,posint);
                                      true

So, this is a workaround:

> (op@map2)(`assuming`,['is((3^n)::odd)'],{[n::posint],[n::0]});
                                      true

@Kitonum 

Apparently, it understands in parts:

> is((3^n)::odd) assuming n::posint;
                                      true
> is((3^n)::odd) assuming n::0;
                                      true

But not together:

> is((3^n)::odd) assuming n::nonnegint;
                                      FAIL
> is((3^n)::odd) assuming n::{0,posint};
                                      FAIL
> is((3^n)::odd) assuming n::OrProp(0,posint);
                                      FAIL

Presumably, any such syntax should work the same as here:

> is((2*n+1)::odd) assuming n::nonnegint;
                                      true
> is((2*n+1)::odd) assuming n::{0,posint};
                                      true
> is((2*n+1)::odd) assuming n::OrProp(0,posint);
                                      true

So, this is a workaround:

> (op@map2)(`assuming`,['is((3^n)::odd)'],{[n::posint],[n::0]});
                                      true

@PatrickT 

Yes, gamma is type name, and type constant, and there is code that evaluates its numerical value, but it is not type numeric:

type(gamma,name);
                              true
type(gamma,constant);
                              true
type(gamma,numeric);
                             false

So, that usage of the expression "numerical constant" is somewhat confusing. Presumably it means an object of type numeric or extended_numeric:

alias(2=pp);
Error, (in alias) aliases cannot be numeric or string constants

alias(infinity=pp);
Error, (in alias) aliases cannot be numeric or string constants

Note also this error message talking about a "string constant". Probably nowhere in the documentation this expression is being used instead of just "string".

@PatrickT 

Yes, gamma is type name, and type constant, and there is code that evaluates its numerical value, but it is not type numeric:

type(gamma,name);
                              true
type(gamma,constant);
                              true
type(gamma,numeric);
                             false

So, that usage of the expression "numerical constant" is somewhat confusing. Presumably it means an object of type numeric or extended_numeric:

alias(2=pp);
Error, (in alias) aliases cannot be numeric or string constants

alias(infinity=pp);
Error, (in alias) aliases cannot be numeric or string constants

Note also this error message talking about a "string constant". Probably nowhere in the documentation this expression is being used instead of just "string".

@Carl Love 

Actually the procedure that needs to be "neutralized" is `evalf/constant/gamma`. This is in Maple 17.01:

> `evalf/constant/gamma`:=:-gamma: 
> local gamma:=`&gamma;`:
Warning, A new binding for the name `gamma` has been created. The global
instance of this name is still accessible using the :- prefix, :-`gamma`.  See
?protect for details.
> evalf(gamma); 
                                    γ
> evalf(:-gamma);
                                    :-gamma
> evalf('gamma');
                                    :-gamma
First 40 41 42 43 44 45 46 Last Page 42 of 109