Preben Alsholm

13728 Reputation

22 Badges

20 years, 249 days

MaplePrimes Activity


These are replies submitted by Preben Alsholm

@pgr Using that  sqrt(2)*[0,0,1] is not simplified to [0,0,sqrt(2)] you could fake a third term term like this:

phi:=(x,y,z)->sqrt(2)*N+(1-sqrt(2))*N+2*([x,y,z]-N)/norm2([x,y,z]-N);

#Maple adds two list of the same length: [a,b]+[c,d] = [a+c,b+d] (automatic simplification, i.e. done before actual evaluation, so that also '[a,b]+[c,d]'; results in [a+c,b+d]). Also '2*[a,b]'; results in [2*a,2*b].
Similarly, '1.234*[a,b]'; results in [1.234*a, 1.234*b]. However, x*[a,b] is not in general simplified to [x*a,x*b], automatically or not, and that is likely the way it should be. The problem is rather with the procedure 'transform' in the plottools package, which ought to have caught the fact that phi(x,y,z) didn't evaluate to a list.
Vectors behave differently: x*; evaluates to.

Simplification of a sum of terms of the form x*[a,b] could be done like this:

#In your example:
evalindets( N+2*([x,y,z]-N)/norm2([x,y,z]-N), list, convert, Vector);
phi:=unapply(convert(%,list),x,y,z);

#In general you can define `simplify/list` like this:

`simplify/list`:=proc(u) convert(evalindets(u,list,convert,Vector),list) end proc;

#Then you would have the desired effect from

simplify( x*[a,b],list);
simplify( sqrt(2)*[a,b]+y*[a,b],list);

PS. Here is another way of 'faking' a 3rd term:

phi:=(x,y,z)->if not type([x,y,z],list(realcons)) then
            [1,2,3]
          else
            N+2*([x,y,z]-N)/norm2([x,y,z]-N)
          end if;

The effect of this is to make the count of dimensions correct. Instead of [1,2,3] you could have any list with 3 elements, or indeed any object with 3 operands, like e.g. q(k,i,j) (q unassigned), since nops(q(k,i,j)) =3.



@pgr Using that  sqrt(2)*[0,0,1] is not simplified to [0,0,sqrt(2)] you could fake a third term term like this:

phi:=(x,y,z)->sqrt(2)*N+(1-sqrt(2))*N+2*([x,y,z]-N)/norm2([x,y,z]-N);

#Maple adds two list of the same length: [a,b]+[c,d] = [a+c,b+d] (automatic simplification, i.e. done before actual evaluation, so that also '[a,b]+[c,d]'; results in [a+c,b+d]). Also '2*[a,b]'; results in [2*a,2*b].
Similarly, '1.234*[a,b]'; results in [1.234*a, 1.234*b]. However, x*[a,b] is not in general simplified to [x*a,x*b], automatically or not, and that is likely the way it should be. The problem is rather with the procedure 'transform' in the plottools package, which ought to have caught the fact that phi(x,y,z) didn't evaluate to a list.
Vectors behave differently: x*; evaluates to.

Simplification of a sum of terms of the form x*[a,b] could be done like this:

#In your example:
evalindets( N+2*([x,y,z]-N)/norm2([x,y,z]-N), list, convert, Vector);
phi:=unapply(convert(%,list),x,y,z);

#In general you can define `simplify/list` like this:

`simplify/list`:=proc(u) convert(evalindets(u,list,convert,Vector),list) end proc;

#Then you would have the desired effect from

simplify( x*[a,b],list);
simplify( sqrt(2)*[a,b]+y*[a,b],list);

PS. Here is another way of 'faking' a 3rd term:

phi:=(x,y,z)->if not type([x,y,z],list(realcons)) then
            [1,2,3]
          else
            N+2*([x,y,z]-N)/norm2([x,y,z]-N)
          end if;

The effect of this is to make the count of dimensions correct. Instead of [1,2,3] you could have any list with 3 elements, or indeed any object with 3 operands, like e.g. q(k,i,j) (q unassigned), since nops(q(k,i,j)) =3.



@Axel Vogt You may find it strange, but it works clearly the way it was intended to work. Giving the default value makes the argument optional.

Also according to specifications:

g:=proc(n::posint:=Pi) return n+1; end proc;
g(k);
g();
#If you want an error from g(k); you could close with a dollar sign:
g:=proc(n::posint:=Pi,$) return n+1; end proc;
g(k);
g();

@Axel Vogt You may find it strange, but it works clearly the way it was intended to work. Giving the default value makes the argument optional.

Also according to specifications:

g:=proc(n::posint:=Pi) return n+1; end proc;
g(k);
g();
#If you want an error from g(k); you could close with a dollar sign:
g:=proc(n::posint:=Pi,$) return n+1; end proc;
g(k);
g();

You probably meant plot([seq(Cplot( beta,lambda), beta = 0 .. 15, 5)], lambda = 0 .. 60).

But besides that it doesn't work right. It always produces the expression after 'else'.

It should be noted that the correct results can easily be made with piecewise:

lambda0 := 0.22e-1*beta^2+(7/1000000000000000)*beta+5.6;
f:=piecewise(lambda < lambda0,0.1e-2,((1/2)*lambda+(1/2)*(-1)*0.22e-1*beta^2+(1/2)*(-5.6))*exp((-1)*.17*lambda));
plot([seq(f,beta=0..30,5)],lambda=0..60);

You probably meant plot([seq(Cplot( beta,lambda), beta = 0 .. 15, 5)], lambda = 0 .. 60).

But besides that it doesn't work right. It always produces the expression after 'else'.

It should be noted that the correct results can easily be made with piecewise:

lambda0 := 0.22e-1*beta^2+(7/1000000000000000)*beta+5.6;
f:=piecewise(lambda < lambda0,0.1e-2,((1/2)*lambda+(1/2)*(-1)*0.22e-1*beta^2+(1/2)*(-5.6))*exp((-1)*.17*lambda));
plot([seq(f,beta=0..30,5)],lambda=0..60);

@pagan Excellent!

Singularities to the left could be included as well, and a message printed out if so desired.

sol:=dsolve({diff(f(x),x)=1/x/(x+2), f(-1)=1/10},numeric,output=listprocedure):
 

g:=proc(x)
   try
      sol(x);
   catch "cannot evaluate the solution further right of %1, probably a singularity","cannot evaluate the solution further left of %1, probably a singularity":
   StringTools:-FormatMessage(lastexception[2..-1])
   end try;
end proc:

g(1);
g(-3);

Instead of explicitly inputting the strings substitution could be made like this:

sol(1);
lastexception;
s1:=lastexception[2];
sol(-3);
s2:=lastexception[2];
#Here the construction of g is done in two steps for clarity. g1 doesn't work, of course.
g1:=proc(x)
   try
      sol(x);
   catch "STRING":
   StringTools:-FormatMessage(lastexception[2..-1])
   end try;
 end proc:
g:=subs("STRING"=(s1,s2),eval(g1)):
g(1);
g(-3);

@pagan Excellent!

Singularities to the left could be included as well, and a message printed out if so desired.

sol:=dsolve({diff(f(x),x)=1/x/(x+2), f(-1)=1/10},numeric,output=listprocedure):
 

g:=proc(x)
   try
      sol(x);
   catch "cannot evaluate the solution further right of %1, probably a singularity","cannot evaluate the solution further left of %1, probably a singularity":
   StringTools:-FormatMessage(lastexception[2..-1])
   end try;
end proc:

g(1);
g(-3);

Instead of explicitly inputting the strings substitution could be made like this:

sol(1);
lastexception;
s1:=lastexception[2];
sol(-3);
s2:=lastexception[2];
#Here the construction of g is done in two steps for clarity. g1 doesn't work, of course.
g1:=proc(x)
   try
      sol(x);
   catch "STRING":
   StringTools:-FormatMessage(lastexception[2..-1])
   end try;
 end proc:
g:=subs("STRING"=(s1,s2),eval(g1)):
g(1);
g(-3);

As Psedomodo says, you don't need to assign the values to the names in order to use them. In most cases I wouldn't want to do that.

In any case you could use an elementwise operation like this:

The list SUBS can be used by subs or eval:

SUBS:=convert(store[..,1]=~store[..,2],list);
#Simultaneous substitutions will be made when one list or one set of substitutions is used and is the only valid syntax for 'eval'. The success of sequential substitution, which is an option in 'subs', is dependent on the proper order in the sequence. Thus notice that
subs(SUBS,S1); #CX3 not substituted since not seen
subs(op(SUBS),S1); #CX3 still not substituted: Wrong order in the sequence.
subs(SUBS,S1):  subs(SUBS,%); #In this case two uses of 'subs' does it.
#You could solve for a1, CX3, and S1, then there will be no problem with simultaneous substitution using either 'subs' or 'eval':

store[..,1]=~store[..,2];
SUBS2:=solve(convert(%,list),indets(store) minus {x});
subs(SUBS2,S1);#OK
eval(S1,SUBS2);#OK

#If you prefer assignment then you can use the two elementwise operations assign~ and  =~  :
assign~(store[..,1]=~store[..,2]):
a1,CX3,S1;


As Psedomodo says, you don't need to assign the values to the names in order to use them. In most cases I wouldn't want to do that.

In any case you could use an elementwise operation like this:

The list SUBS can be used by subs or eval:

SUBS:=convert(store[..,1]=~store[..,2],list);
#Simultaneous substitutions will be made when one list or one set of substitutions is used and is the only valid syntax for 'eval'. The success of sequential substitution, which is an option in 'subs', is dependent on the proper order in the sequence. Thus notice that
subs(SUBS,S1); #CX3 not substituted since not seen
subs(op(SUBS),S1); #CX3 still not substituted: Wrong order in the sequence.
subs(SUBS,S1):  subs(SUBS,%); #In this case two uses of 'subs' does it.
#You could solve for a1, CX3, and S1, then there will be no problem with simultaneous substitution using either 'subs' or 'eval':

store[..,1]=~store[..,2];
SUBS2:=solve(convert(%,list),indets(store) minus {x});
subs(SUBS2,S1);#OK
eval(S1,SUBS2);#OK

#If you prefer assignment then you can use the two elementwise operations assign~ and  =~  :
assign~(store[..,1]=~store[..,2]):
a1,CX3,S1;


@PatrickT Just a minor comment: Warnings do come in connection with singularities but seem to come from some plotting procedures:

restart;
sol:=dsolve({diff(f(x),x)=1/x, f(-1)=1/10},numeric,output=listprocedure):
sol(1); #Error
F:=subs(sol,f(x));
plot(F,-1..1); #No warnings nor errors reported
DEtools[DEplot](diff(f(x),x)=1/x,f(x),x=-1..1,[[f(-1)=1/10]]); #Warning about error!
plots:-odeplot(sol,[x,f(x)],-1..1); #Warning

@PatrickT Just a minor comment: Warnings do come in connection with singularities but seem to come from some plotting procedures:

restart;
sol:=dsolve({diff(f(x),x)=1/x, f(-1)=1/10},numeric,output=listprocedure):
sol(1); #Error
F:=subs(sol,f(x));
plot(F,-1..1); #No warnings nor errors reported
DEtools[DEplot](diff(f(x),x)=1/x,f(x),x=-1..1,[[f(-1)=1/10]]); #Warning about error!
plots:-odeplot(sol,[x,f(x)],-1..1); #Warning

@PatrickT My point was that  catch:  catches all exceptions no matter what you write after the colon.

Thus in the following three examples the error is caught, but only in the first case is the message of any use.

a:="56";
try
sin(a)
catch: StringTools:-FormatMessage(lastexception[2..-1]);
45
end try;

a:="56";
try
sin(a)
catch: StringTools:-FormatMessage("Once upon a time ... ");
45
end try;

a:="56";
try
sin(a)
catch: "Once upon a time ... ";
45
end try;

@PatrickT My point was that  catch:  catches all exceptions no matter what you write after the colon.

Thus in the following three examples the error is caught, but only in the first case is the message of any use.

a:="56";
try
sin(a)
catch: StringTools:-FormatMessage(lastexception[2..-1]);
45
end try;

a:="56";
try
sin(a)
catch: StringTools:-FormatMessage("Once upon a time ... ");
45
end try;

a:="56";
try
sin(a)
catch: "Once upon a time ... ";
45
end try;

@PatrickT I think that

try
.....
catch:
.....
end try;

catches all errors (not warnings!).

The addition of StringTools:-FormatMessage after the colon just has the effect of printing the message. If you want the relevant message printed you can use

StringTools:-FormatMessage(lastexception[2..-1]);

Example:

a:="56";
try
sin(a)
catch: StringTools:-FormatMessage(lastexception[2..-1]);
45
end try;

First 199 200 201 202 203 204 205 Last Page 201 of 230