acer

32343 Reputation

29 Badges

19 years, 328 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Hmm.  Wouldn't it be better if the default value of currentdir() were the same as the result of kernelopts(homedir) when Maple is started from some icon launcher which doesn't specify the working location?

There are other values that would also be much more sensible than the current default. The present default appears to be kernelopts(mapledir), which is not a good default at all. There likely are many Maple users who are inadvertantly saving documents to the Maple installation folder under Program Files. That doesn't seem very wise. (A file or subfolder crucial for Maple's proper operation might too easily be clobbered, for example.)

acer

I hope that these have the correct form and do what you intended. (Note: I haven't done anything special, about the cases that you had. In fact, I just commented out part of it, since you say that the particular function is not material; you want to know how to use NLPSolve for procedures, etc.)

# First, using "Matrix Form"
# note: This didn't work well, unless I provided the gradient of f.
#       Also, threw in the jacobian of the constraint proc, for fun.
 
f := proc(x::Array)
  #if (x[1]^2+x[2]+x[3]+x[4] < 15 and x[1]^2+x[2]+x[3]+x[4] > 10) then
     2*x[1]^2+3*x[2]+4*x[3]+2*x[4];
  #else
  #   1/x[1]+x[2]^2+x[3]+x[4]^2;
  #end if;
end proc:
 
fgrad := proc(x::Array, xd::Array)
  # Acts in-place on xd, so returns NULL
  #if (x[1]^2+x[2]+x[3]+x[4] < 15 and x[1]^2+x[2]+x[3]+x[4] > 10) then
    xd[1] := 2*x[1];
    xd[2] := 1;
    xd[3] := 1;
    xd[4] := 2*x[4];
  #else
  #  xd[1] := -1/x[1]^2;
  #  xd[2] := 2*x[2];
  #  xd[3] := 1;
  #  xd[4] := 2*x[4];
  #end if;
  NULL;
end proc:
 
pcons := proc(X::Vector, Y::Vector)
  # Acts in-place on Y, so returns NULL
  Y[1] := add(X[i],i=1..4) - 20;
  NULL:
end proc:
 
pconsjac := proc(X::Vector, J::Matrix)
  # Acts in-place on J, so returns NULL
  J[1,1] := 1; # del pcons_Y[1] / del X[1]
  J[1,2] := 1;
  J[1,3] := 1;
  J[1,4] := 1; # del pcons_Y[1] / del X[4]
  NULL;
end proc:
 
bds := [Vector([1,1,1,1]),Vector([5,5,5,5])]:
 
Optimization:-NLPSolve(4,f,1,pcons,[],bds,initialpoint=Vector([1,1,1,1]),
                       objectivegradient=fgrad,constraintjacobian=pconsjac,
                       maximize);
 
# Second, using "Procedure Form"
 
F := proc(x1,x2,x3,x4)
  #if (x1^2+x2+x3+x4 < 15 and x1^2+x2+x3+x4 > 10) then
     2*x1^2+3*x2+4*x3+2*x4;
  #else
  #   1/x1+x2^2+x3+x4^2;
  #end if;
end proc:
 
b1 := proc(x1,x2,x3,x4) x1+x2+x3+x4 - 20; end proc:
 
bds := 1..5,1..5,1..5,1..5:
 
Optimization:-NLPSolve(F,{b1},bds,initialpoint=[1,1,1,1],maximize);

acer

I hope that these have the correct form and do what you intended. (Note: I haven't done anything special, about the cases that you had. In fact, I just commented out part of it, since you say that the particular function is not material; you want to know how to use NLPSolve for procedures, etc.)

# First, using "Matrix Form"
# note: This didn't work well, unless I provided the gradient of f.
#       Also, threw in the jacobian of the constraint proc, for fun.
 
f := proc(x::Array)
  #if (x[1]^2+x[2]+x[3]+x[4] < 15 and x[1]^2+x[2]+x[3]+x[4] > 10) then
     2*x[1]^2+3*x[2]+4*x[3]+2*x[4];
  #else
  #   1/x[1]+x[2]^2+x[3]+x[4]^2;
  #end if;
end proc:
 
fgrad := proc(x::Array, xd::Array)
  # Acts in-place on xd, so returns NULL
  #if (x[1]^2+x[2]+x[3]+x[4] < 15 and x[1]^2+x[2]+x[3]+x[4] > 10) then
    xd[1] := 2*x[1];
    xd[2] := 1;
    xd[3] := 1;
    xd[4] := 2*x[4];
  #else
  #  xd[1] := -1/x[1]^2;
  #  xd[2] := 2*x[2];
  #  xd[3] := 1;
  #  xd[4] := 2*x[4];
  #end if;
  NULL;
end proc:
 
pcons := proc(X::Vector, Y::Vector)
  # Acts in-place on Y, so returns NULL
  Y[1] := add(X[i],i=1..4) - 20;
  NULL:
end proc:
 
pconsjac := proc(X::Vector, J::Matrix)
  # Acts in-place on J, so returns NULL
  J[1,1] := 1; # del pcons_Y[1] / del X[1]
  J[1,2] := 1;
  J[1,3] := 1;
  J[1,4] := 1; # del pcons_Y[1] / del X[4]
  NULL;
end proc:
 
bds := [Vector([1,1,1,1]),Vector([5,5,5,5])]:
 
Optimization:-NLPSolve(4,f,1,pcons,[],bds,initialpoint=Vector([1,1,1,1]),
                       objectivegradient=fgrad,constraintjacobian=pconsjac,
                       maximize);
 
# Second, using "Procedure Form"
 
F := proc(x1,x2,x3,x4)
  #if (x1^2+x2+x3+x4 < 15 and x1^2+x2+x3+x4 > 10) then
     2*x1^2+3*x2+4*x3+2*x4;
  #else
  #   1/x1+x2^2+x3+x4^2;
  #end if;
end proc:
 
b1 := proc(x1,x2,x3,x4) x1+x2+x3+x4 - 20; end proc:
 
bds := 1..5,1..5,1..5,1..5:
 
Optimization:-NLPSolve(F,{b1},bds,initialpoint=[1,1,1,1],maximize);

acer

I could envision a new user falling into this kind of trap.

> f := proc(x) if signum(x)=1 then cos(x) else -cos(x) end if; end proc:

> evalf(Int(f,-Pi/2..Pi/2)); # correct
                                      0.
 
> int(f,-Pi/2..Pi/2); # wrong
                                      -2

It might be better if int(f,a..b) and value(Int(f,a..b)) issued errors.

Evaluating a procedure at a dummy and then computing with the resulting expression, is a poor way to mimic functionality over operators.

fsolve does something similar, and it too can be quite easily fooled. It'd be better to leave operators alone, and to treat them as black boxes for numerical computation.

acer

I could envision a new user falling into this kind of trap.

> f := proc(x) if signum(x)=1 then cos(x) else -cos(x) end if; end proc:

> evalf(Int(f,-Pi/2..Pi/2)); # correct
                                      0.
 
> int(f,-Pi/2..Pi/2); # wrong
                                      -2

It might be better if int(f,a..b) and value(Int(f,a..b)) issued errors.

Evaluating a procedure at a dummy and then computing with the resulting expression, is a poor way to mimic functionality over operators.

fsolve does something similar, and it too can be quite easily fooled. It'd be better to leave operators alone, and to treat them as black boxes for numerical computation.

acer

Thanks, Alex. I must have accidentally used my earlier defn when I wrote that last int() call. I ought to have forseen my mistake.

Anyway, this looks like what sometimes gets called "premature evaluation", where the applied function argument is unintentionally evaluated up front. A usual way of dealing with it is to delay the evaluation. That can often be done using operator form, or using uneval quotes, or by redefining the proc to return unevaluated on non-numeric input. Those workarounds can allow numeric routines like plot(), evalf(Int(...)), fsolve(), Minimize() to work with f(x).

But symbolic int() doesn appear to be able to do anything meaningful with them. It doesn't "know" how to handle them, in the way that it "knows" how to handle piecewise structures. It doesn't generate an error, but it also doesn't compute the result.

> f:=proc(x) if x>=0 and x<1 then 1 else 0 fi; end proc:

> int(f(x),x=0..2);
Error, (in f) cannot determine if this expression is
true or false: 0 <= x and x < 1

> int('f'(x),x=0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0
 
> int(f,0..2); # As Alex mentioned
Error, (in f) cannot determine if this expression is true
or false: 0 <= x and x < 1

> f:=proc(x)
> if type(x,numeric) then
>  if x>=0 and x<1 then 1 else 0 fi;
> else 'procname'(args);
> end if;
> end proc:

> int(f(x),x=0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0
 
> int(f,0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0

Yet int() does know how to deal with (many) piecewise structures, as illustrated above.

It may be of interest to compare with the differential operator D, which has more knowledge (tricks) for delving into procs.

> f:=proc(x) if x>=0 and x<1 then 1 else 0 fi; end proc:

> D(f);
           proc(x) if 0 <= x and x < 1 then 0 else 0 end if end proc

Of course, D is intended for use on operators, while int() is intended for use on expressions. Note that the help-page for int() describes its calling sequences as each working on an expression rather than on an appliable function. There is mention of the following form for uppercase Int(), which looks a little like an expression-operator form mismatch,

   Int(expression, a..b)

I can imagine why that gets a help-page mention, because one might subsequently want to apply evalf to that Int() call.

It appears that for lowercase int() the operator form is really just faked, by evaluating at a dummy name. That functionality for int(f,a..b) allows things like this to work

> f := t -> sin(t):

> int(f,a..b);
                                cos(a) - cos(b)

But as far as I can see, that really only works well when int(f(x),x=a..b) would also work. So its upside is mostly (only?) that of minor convenience. But the downside is that it gives the surface impression that int() works with operators in general (which it doesn't -- see the original posted example).

acer

Thanks, Alex. I must have accidentally used my earlier defn when I wrote that last int() call. I ought to have forseen my mistake.

Anyway, this looks like what sometimes gets called "premature evaluation", where the applied function argument is unintentionally evaluated up front. A usual way of dealing with it is to delay the evaluation. That can often be done using operator form, or using uneval quotes, or by redefining the proc to return unevaluated on non-numeric input. Those workarounds can allow numeric routines like plot(), evalf(Int(...)), fsolve(), Minimize() to work with f(x).

But symbolic int() doesn appear to be able to do anything meaningful with them. It doesn't "know" how to handle them, in the way that it "knows" how to handle piecewise structures. It doesn't generate an error, but it also doesn't compute the result.

> f:=proc(x) if x>=0 and x<1 then 1 else 0 fi; end proc:

> int(f(x),x=0..2);
Error, (in f) cannot determine if this expression is
true or false: 0 <= x and x < 1

> int('f'(x),x=0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0
 
> int(f,0..2); # As Alex mentioned
Error, (in f) cannot determine if this expression is true
or false: 0 <= x and x < 1

> f:=proc(x)
> if type(x,numeric) then
>  if x>=0 and x<1 then 1 else 0 fi;
> else 'procname'(args);
> end if;
> end proc:

> int(f(x),x=0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0
 
> int(f,0..2);
                                    2
                                   /
                                  |
                                  |   f(x) dx
                                  |
                                 /
                                   0

Yet int() does know how to deal with (many) piecewise structures, as illustrated above.

It may be of interest to compare with the differential operator D, which has more knowledge (tricks) for delving into procs.

> f:=proc(x) if x>=0 and x<1 then 1 else 0 fi; end proc:

> D(f);
           proc(x) if 0 <= x and x < 1 then 0 else 0 end if end proc

Of course, D is intended for use on operators, while int() is intended for use on expressions. Note that the help-page for int() describes its calling sequences as each working on an expression rather than on an appliable function. There is mention of the following form for uppercase Int(), which looks a little like an expression-operator form mismatch,

   Int(expression, a..b)

I can imagine why that gets a help-page mention, because one might subsequently want to apply evalf to that Int() call.

It appears that for lowercase int() the operator form is really just faked, by evaluating at a dummy name. That functionality for int(f,a..b) allows things like this to work

> f := t -> sin(t):

> int(f,a..b);
                                cos(a) - cos(b)

But as far as I can see, that really only works well when int(f(x),x=a..b) would also work. So its upside is mostly (only?) that of minor convenience. But the downside is that it gives the surface impression that int() works with operators in general (which it doesn't -- see the original posted example).

acer

If `e` is rebound to the name of an export of a module, then it can be used with the `networks` package, I believe.

One should be able to issue any of these fragments, prior to the networks calls, and then use e as a name for a vertex, etc.

 

loce:=module() option package; export e; end:with(loce,':-e'):

bind((module() option package; export e; end):-e):

loce:=module() export e; end:bind(loce:-e):

Of course, the original, global name can still be accessed as :-e.

In a similar way, it seems possible to rebind D and then use it naturally with the geometry package. The global differential operator :-D is then still available.

acer

If `e` is rebound to the name of an export of a module, then it can be used with the `networks` package, I believe.

One should be able to issue any of these fragments, prior to the networks calls, and then use e as a name for a vertex, etc.

 

loce:=module() option package; export e; end:with(loce,':-e'):

bind((module() option package; export e; end):-e):

loce:=module() export e; end:bind(loce:-e):

Of course, the original, global name can still be accessed as :-e.

In a similar way, it seems possible to rebind D and then use it naturally with the geometry package. The global differential operator :-D is then still available.

acer

Oh, sure, a re-implementation of solve might well try that (or close variants to the formulaic pattern, as well). Your point is good, and is hopefully not lost.

But I was more wondering whether anyone's found an incantation to pump it out in Maple 12, using the usual suspects such as solve, expand, convert, simplify, collect, assuming, etc.

acer

Oh, sure, a re-implementation of solve might well try that (or close variants to the formulaic pattern, as well). Your point is good, and is hopefully not lost.

But I was more wondering whether anyone's found an incantation to pump it out in Maple 12, using the usual suspects such as solve, expand, convert, simplify, collect, assuming, etc.

acer

I may be missing something obvious, but how can one get solve to provide the obvious solution y=a^2 (if real a>0, say) to,

> eval(ln(y)/ln(a) = ln(y-1)/ln(b),b=sqrt(a^2-1));

                              ln(y)   2 ln(y - 1)
                              ----- = -----------
                              ln(a)       2
                                      ln(a  - 1)

acer

I may be missing something obvious, but how can one get solve to provide the obvious solution y=a^2 (if real a>0, say) to,

> eval(ln(y)/ln(a) = ln(y-1)/ln(b),b=sqrt(a^2-1));

                              ln(y)   2 ln(y - 1)
                              ----- = -----------
                              ln(a)       2
                                      ln(a  - 1)

acer

> f:=sin(x):
> Dn := (n,L) -> (2/L)* int(f*sin(n*Pi*x/L), x=0..L):
> Dn(n,Pi) assuming n::posint;
                                       0

> _EnvAllSolutions:=true: # hoping for a piecewise
> Dn(n,Pi) assuming n::posint;
                            /{  Pi                  \
                            |{ ----          n = 1  |
                          2 |{  2                   |
                            |{                      |
                            \{  0          otherwise/
                          ---------------------------
                                      Pi

> sum( Dn(n,Pi)*sin(n*x)*cos(n*t), n=1..infinity );
                       1/2 sin(x + t) - 1/2 sin(-x + t)

> simplify(convert(expand(convert(%,expln)),trig));
                                 sin(x) cos(t)

acer

> f:=sin(x):
> Dn := (n,L) -> (2/L)* int(f*sin(n*Pi*x/L), x=0..L):
> Dn(n,Pi) assuming n::posint;
                                       0

> _EnvAllSolutions:=true: # hoping for a piecewise
> Dn(n,Pi) assuming n::posint;
                            /{  Pi                  \
                            |{ ----          n = 1  |
                          2 |{  2                   |
                            |{                      |
                            \{  0          otherwise/
                          ---------------------------
                                      Pi

> sum( Dn(n,Pi)*sin(n*x)*cos(n*t), n=1..infinity );
                       1/2 sin(x + t) - 1/2 sin(-x + t)

> simplify(convert(expand(convert(%,expln)),trig));
                                 sin(x) cos(t)

acer

First 498 499 500 501 502 503 504 Last Page 500 of 592