acer

32385 Reputation

29 Badges

19 years, 335 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

This weird behaviour seems to have started with Maple 18.00.

restart:

hhh:=400/Unit(1/kg);
                              400       
                       -----------------
                                  / 1  \
                       Units:-Unit|----|
                                  \'kg'/

with(Units:-Standard,`/`,`*`,normal);
                         [/, *, normal]

simplify(hhh);
                     400 Units:-Unit('kg')

normal(hhh); # ???
                                     / 1  \
                     -400 Units:-Unit|----|
                                     \'kg'/

:-normal(hhh);
                              400       
                       -----------------
                                  / 1  \
                       Units:-Unit|----|
                                  \'kg'/

hhh;
                              400       
                       -----------------
                                  / 1  \
                       Units:-Unit|----|
                                  \'kg'/

1/hhh; # ???
                       1                   
                    - --- Units:-Unit('kg')
                      400                  

hhh/1; # ???
                                     / 1  \
                     -400 Units:-Unit|----|
                                     \'kg'/

I will submit a bug report.

acer

Is it a part of your problem that Maple is parsing your input as if it were multiplication, ie, like D(F) * (x) ?

If so and if you are using Maple 2015 then this might be related to the GUI preference for so-called Smart Operators.

acer

@Tycoon51 If plots:-matrixplot satisfies your needs then great. You did state that you wanted the x- and y-axes to be coordinates of the 2-dimensional "array".

It may be worth mentioning that sometimes one wants the coordinate values to be interpreted as if from some pair of x- and y-ranges, rather than just as discrete coordinate values. In such cases the command plots:-surfdata can help, as it also accepts optional arguments to specifiy the x- and y-ranges to be used for generating x- and y-axis tickmarks.

A:=Matrix(1..51, 1..31, (i,j)->evalf( ((j-1-15)*2/30)^2 * sin(2*Pi*(i-1)/50)) ):

plots:-matrixplot(A, axes=box);

plots:-surfdata(A, 1..51, 1..31, axes=box);

plots:-surfdata(A, 0..2*Pi, -1..1, axes=box);

Why do you need each entry to be read back in as an individual assignment statement?

Why not use ExportMatrix to write all the entries to a file at once, after the loop finishes? And then import then all at once using ImportMatrix in your new sessions?

If you prefer you could still export each entry individually using fprintf (or other) inside the loop. But you could still re-import them in bulk, using ImportMatrix (which should be faster as well as simpler).

You can make the call to ImportMatrix be done with a single assignment. Eg,

M := ImportMatrix(outfile,...)

So in this way you can have your values be in a data file, rather than in a file of Maple commands.

acer

I'm not really understanding your comments that motivated this, but you can write your own custom `D/A` extension.

I'm not really sure that I understand why you want to have it work for D[...]A(a,b,c) rather than with 2-argument `eval` applied to the result like say eval(diff(A(s,t,m),...),[s=a,t=b,m=c]).

Of course it's up to you to make sure that it does what you want.

I just made up these examples, and the results may or may not make sense. It's just to illustrate the idea.

Here's the first example,

restart;

A:=proc(x,y,m)
  if m>0 then
    return B(x) + B(y) + 'A'(x,y,m-1);
  else
    return 1;
  end if
end proc:

(D[1](A))(1,2,3);

(D[1](A))(1, 2, 3)

`D/A`:=proc(d)
  if nops(d)=1 then
    if d[1]=1 then
      return proc(x,y,m)
        if m>0 then
          return D(B)(x);
        else
          return 0;
        end if
      end proc;
    elif d[1]=2 then
      # Now, how shall we handle the derivative of this returned proc?
      return proc(x,y,m)
        if m>0 then
          return D(B)(y) + eval(subs(__d=d[],'D[__d](A)')(x,y,m-1));
        else
          return 0;
        end if
      end proc;
    end if;
  else
    # You may wish to also handle case of nops(d)>1 , etc.
  end if;

  # default return value
  subs(__d=d[],'D[__d](A)');
  
end proc:

D[1](A);
D[2](A);

proc (x, y, m) if 0 < m then return (D(B))(x) else return 0 end if end proc

proc (x, y, m) if 0 < m then return (D(B))(y)+eval((subs(__d = [2][], 'D[__d](A)'))(x, y, m-1)) else return 0 end if end proc

(D[1](A))(s,t,0);

0

(D[1](A))(s,t,1);

(D(B))(s)

(D[2](A))(s,t,0);

0

(D[2](A))(s,t,1);

(D(B))(t)

(D[2](A))(s,t,2);

2*(D(B))(t)

(D[2](A))(s,t,3);

3*(D(B))(t)

 

Download sometoyD.mw

And here's another example,


restart;

A:=proc(x,y,m)
  if m>0 then
    return B(x) + B(y) * 'A'(x,y,m-1);
  else
    return 1;
  end if
end proc:

(D[1](A))(1,2,3);

(D[1](A))(1, 2, 3)

`D/A`:=proc(d)
  if nops(d)=1 then
    if d[1]=1 then
      return proc(x,y,m)
        if m>0 then
          return D(B)(x) + B(y) * eval(subs(__d=d[],'D[__d](A)')(x,y,m-1));
        else
          return 0;
        end if
      end proc;
    elif d[1]=2 then
      # Now, how shall we handle the derivative of this returned proc?
      return proc(x,y,m)
        if m>0 then
          return D(B)(y) * 'A'(x,y,m-1)
                 + B(y) * eval(subs(__d=d[],'D[__d](A)')(x,y,m-1));
        else
          return 0;
        end if
      end proc;
    end if;
  else
    # You may wish to also handle case of nops(d)>1 , etc.
  end if;

  # default return value
  subs(__d=d[],'D[__d](A)');
  
end proc:

(D[1](A))(s,t,0);

0

(D[1](A))(s,t,1);

(D(B))(s)

(D[1](A))(s,t,2);

(D(B))(s)+B(t)*(D(B))(s)

(D[1](A))(s,t,3);

(D(B))(s)+B(t)*((D(B))(s)+B(t)*(D(B))(s))

(D[2](A))(s,t,0);

0

(D[2](A))(s,t,1);

(D(B))(t)*A(s, t, 0)

(D[2](A))(s,t,2);

(D(B))(t)*A(s, t, 1)+B(t)*(D(B))(t)*A(s, t, 0)

(D[2](A))(s,t,3);

(D(B))(t)*A(s, t, 2)+B(t)*((D(B))(t)*A(s, t, 1)+B(t)*(D(B))(t)*A(s, t, 0))

 


Download anothertoyD.mw

acer

A result that agrees with that of member vv, but via a change of variables rather than by switching the order of integration.

restart;

with(VectorCalculus):

v1 := x^2 + y - sin(z):

v2 := x^2 + 1/y - 2*z:

v3 := y^2 + 3*x + z:

vv := VectorField(<v1, v2, v3>, 'cartesian'[x, y, z]):

NULL

G := Flux(vv, Sphere(`<,>`(0, 0, 0), r), inert);

Int(Int(-sin(phi)*(sin(phi)*cos(theta)^3*cos(phi)^2*r^3+sin(phi)*cos(theta)^2*sin(theta)*cos(phi)^2*r^3-cos(theta)^2*cos(phi)^3*r^3-sin(phi)*cos(theta)^3*r^3-r^3*sin(phi)*cos(theta)^2*sin(theta)+cos(theta)^2*cos(phi)*r^3+cos(theta)*sin(theta)*cos(phi)^2*r^2+cos(phi)^3*r^3-3*sin(phi)*cos(theta)*cos(phi)*r^2+2*r^2*cos(phi)*sin(phi)*sin(theta)+sin(phi)*cos(theta)*sin(r*cos(phi))*r-cos(theta)*sin(theta)*r^2-cos(phi)^2*r^2-cos(phi)*r^3-1)*r, phi = 0 .. Pi), theta = 0 .. 2*Pi)

``

This is easier if the dummy variables of integration are not escaped locals.

 

G := subsindets(G, name, convert, `global`):

 

Do a change of variables on the inner integral, then  get its value.

 

value(IntegrationTools:-Change(op(1, G), cos(phi) = t, t));

-r*(-(3/8)*Pi*cos(theta)^3*r^3-(3/8)*Pi*cos(theta)^2*sin(theta)*r^3-(4/3)*cos(theta)*sin(theta)*r^2-(2/3)*r^2-2)

 

Replace the inner integral with that result. Then get the value of the outer integral.

 

value(subsop(1 = %, G));

(4/3)*Pi*r^3+4*Pi*r


Download flux3.mw

acer

Is ImageTools:-Complement what you're looking for? Eg,

with(ImageTools):

img:=Scale(Read(cat(kernelopts(datadir),"/images/rollercoaster.jpg")),0.6):

Embed([img,Complement(img)],exterior=none,interior=none);

img:=Scale(Read(cat(kernelopts(datadir),"/images/tree.jpg")),0.6):

Embed([img,Complement(img)],exterior=none,interior=none);

That's `color inversion' in this sense (in the RGB colorspace): green<->magenta, blue<->yellow, red<->cyan.

acer

Another technique, the earliest use of which I'm aware is by Alec Mihailovs (and used inside plots:-shadebetween I believe):

 

restart;

(f,g):=2,1/sqrt(1-x^2):
plottools:-transform(unapply([x,y+g],x,y))(plot(f-g,x=0..sqrt(3)/2,filled=true));

 

 

Download shadeb.mw

acer

Is Example 4 on this page the kind of thing you mean? (Also see the trig identity example here.)

Another way to manipulate expressions (and equations) and see steps taken is to use the Equation Manipulator.

Or are you trying to achieve step-by-step integration? If so, see the this tutor or this overview.

acer

You can use plots:-spacecurve to plot this in your Maple 18.

And you can Explore the spacecurve, to see how the parameters affect the curve. See the attachement below.

spacecurve.mw

acer

How about something like this? You'd apply it to your expression or name, instead of applying numelems.

nelems := e->`if`(e::indexable,numelems(e),0):

acer

The entries in a list can be rotated using ListTools:-Rotate.

The order of entries in a set is not something you'd control.

acer

A few years ago I would have tried implementing this kind of thing using an appliable module with its own overloading exports for arithmetic, etc. It's a pretty good approach, but it has its drawbacks. One issue (which is seen with Units, say) is that the rebound arithmetic operators and other exports only have an effect when used at the top-level. System commands saved in the system library archives have the original global names bound for those operators, and so they don't utilize the redefined or overloaded versions.

Some of these kinds of issues can be alleviated by using the newer objects in Maple. In the attached Document I put a preliminary definition of a phasor-style object in the Startup Code region.

I named my class of phasor objects using the name `&angle;` so that that entry in the Operators Palette would work. (I suspect that could be similarly useful as the name of Carl's appliable module as well.)

Please let me know if I didn't get some of the math right, or if you have a suggestion. I'm sure that this could be improved.

I used the palette to enter the prettyprinted angle symbol in 2D Input mode. I'd have to investigate whether I could teach it to command-completion also, for pure typing input.

 

``

a := `&angle;`(30)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

argument(a)

30

abs(a)

1

b := -`&angle;`(270)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

b := `&angle;`(-1, 270)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

a+b

module `&angle;` () local ModulePrint, larg, labs; option object; end module

`&angle;`(4, 45.0)+`&angle;`(5, 30.0)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

`&angle;`(4, 45)+`&angle;`(5, 30)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

evalf[20](%)

module `&angle;` () local ModulePrint, larg, labs; option object; end module

`&angle;`(2, 180)+3

module `&angle;` () local ModulePrint, larg, labs; option object; end module

x*b

module `&angle;` () local ModulePrint, larg, labs; option object; end module

6.0*b

module `&angle;` () local ModulePrint, larg, labs; option object; end module

``

 

Download phasorobject1.mw

Here's that first shot at the code for it, from that document's Startup Code region. Sorry if any of the angle names in this 1D plaintext code get rendered like the typeset entity -- it's a problem with this site for code within pre-tags. (I already see something to improve, the case when it gets called with no arguments.)

module `&angle;`()
  option object, `Copyright (c) 2015 by R. Acer. All rights reserved.`;
  local ModulePrint, larg, labs;
  export ModuleApply::static:=proc()
    Object(`&angle;`, _passed);
  end;
  export ModuleCopy::static:=proc(new::`&angle;`,proto::`&angle;`,
                                  v::scalar)
    if nargs=3 then (new:-labs,new:-larg):=1,v;
    elif nargs=4 then (new:-labs,new:-larg):=args[3],args[4];
    else error "invalid arguments"; end if;
  end proc;
  export argument::static:=proc(a) a:-larg; end proc;
  export abs::static:=proc(a) a:-labs; end proc;
  export `+`::static:=proc()
    local a,o,R,z;
    (a,o):=selectremove(type,[args],`&angle;`);
    if nargs=1 then return args[1];
    else
      R:=add(abs(z)*exp(argument(z)*Pi*I/180),z=a) + add(z,z=o);
      `&angle;`(simplify(radnormal(:-abs(R)),size),
                simplify(radnormal(:-argument(R)*180/Pi),size));
    end if;
  end proc;
  export `*`::static:=proc()
    local a,o,R,z;
    (a,o):=selectremove(type,[args],`&angle;`);
    R:=mul(abs(z)*exp(argument(z)*Pi*I/180),z=a) * mul(z,z=o);
      `&angle;`(simplify(radnormal(:-abs(R)),size),
                simplify(radnormal(:-argument(R)*180/Pi),size));
  end proc;
  export evalf::static:=proc(a)
    `&angle;`(:-evalf(a:-labs,_rest),:-evalf(a:-larg,_rest));
  end proc;
  ModulePrint:=proc(a)
    '`&angle;`'(a:-labs,a:-larg);
  end proc:
end module:

acer

Your current approach does all the work of recomputing the transformation Matrix for each of the M*N entries, when used in constructing the new Array. So for XYZ_D50_to_D65, say, it does the same two Matrix-Matrix multiplications and the Matrix-inversion each of M*N times. It's more efficient to just compute those just once.

Here's one way to do the first of those constructions, in your document. Instead of using the Array() constructor I'll just map onto the input Array a procedure which applies the transformation Matrix to a Vector entry.

F := XYZ_to_LMS^(-1) . LMS_D50_to_D65 . XYZ_to_LMS;

map( v -> F . v, CCXYZ_D50 );

Alternatively, if you want it as a named operator,

XYZ_D50_to_D65 := subs(_OP = XYZ_to_LMS^(-1) . LMS_D50_to_D65 . XYZ_to_LMS, v -> _OP . v):

map(XYZ_D50_to_D65, CCXYZ_D50);

acer

Use the form,

if is( 2 < sqrt(5) ) then
  ...
end if;

Note that is can also return FAIL, in the case that it cannot determine whether the result is true or false. So for more complicated examples you might use the variant  if is(....)=true then ... and perhaps also have an elif case to for FAIL.

In your example is will utilize shake to test the result in floating point. So for your simple example you could also do,

if evalf( 2 < sqrt(5) ) then ...

acer

First 218 219 220 221 222 223 224 Last Page 220 of 336