acer

32333 Reputation

29 Badges

19 years, 323 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@mvms271091 You may use an empty string "" for the second legend item, which will get suppressed. For example,

f := (3*t)/(1 + t^3):
g := (3*t^2)/(1 + t^3):
plot([[f,g,t=-40..-1.5],[f,g,t=-0.6..40]],
     style=point,symbol=cross,symbolsize=12,
     colour=coral,legend=[foo,""]);

You could do the same thing using, say,
  `[]`~(f,g,t=~[-40..-1.5,-0.6..40])
instead of,
  [[f,g,t=-40..-1.5],[f,g,t=-0.6..40]]

@Ivi Please don't post duplicate Question threads for this, though it might not yet be answered here to your satisfaction.

Here is an example of doing it with a procedure.

The scaling=constrained is needed so that the icon doesn't get distorted. An alternative that would estimate the plot assembly's final size (aspect ratio) -- and use that to adjust the icon -- could become tricky in general.

restart;

with(ImageTools):

img := Scale(Read(cat(currentdir(),"/smdrone.jpg")),1..75)[1..70]:

R := Rotate(img,':-right'):

M := Matrix(70,70,'datatype'=':-float[8]'):

 

Qf := (x0::realcons,y0::realcons,h::realcons) ->
  PLOT(GRID(evalf(x0-h/2)..evalf(x0+h/2),
            evalf(y0-h/2)..evalf(y0+h/2),
            M, COLOR(RGB,R)),STYLE(PATCHNOGRID)):

 

plots:-display(
  seq(Qf(a,sin(a)+0.2,0.3), a=[seq(i*Pi/4, i=1..7)]),

  plot(sin(x),x=0..2*Pi),

  scaling=constrained, size=[700,300],
  xtickmarks=[seq(i*Pi/4=i*Pi/4,i=0..4)]);

Download image_plot2.mw

Yet another alternative is to build a background image for the whole plot-window, with instances of the icon as carefully placed subimages. Then the aspect-ratio of the icon images could be handled based on any forced size option choice. This approach wouldn't allow the icons to be laid over a densityplot example, however.

@mmcdara In terms of (kernel, at least) efficiency an improvement would be a procedure.

It could accept, say an x,y pair as center point and width/length (or two opposite corner x,y positions). It could then construct that PLOT(GRID(...)..) structure directly. The only thing needing computation would be the two ranges that are the first two arguments of the GRID(...) substructure.

That would be more efficient than `plottools` commands `transform` or `translate`. It would also allow the two float[8] rtables to remain as such, which might even be kinder to the GUI.

@mvms271091 In my Answer I already gave,

DocumentTools:-Tabulate(widthmode = percentage, width = 75,
                                          [[seq([seq(p[3*(i - 1) + j], j = 1 .. 3)], i = 1 .. iquo(11, 3))],
                                           [seq(p[3*iquo(11, 3) + i], i = 1 .. irem(11, 3))]]):

where that latter part,
    [seq(p[3*iquo(11, 3) + i], i = 1 .. irem(11, 3))]
provides the 10th and 11th plots in a fourth row. It's harder to get that last row center-aligned without resorting to the building-blocks in which Tabulate is written (which is done in one manner in my Answer's second example).

Yes, your fresh attempt using,
   [seq([seq(p[i], i = (j-1)*iquo(11,3) + 1..j*iquo(11,3))], j = 1..iquo(11,3)+1)]
does not work because for the fourth row it refereces member p[12] which is not a plot. That is the whole point of the code fragment in my previous paragraph here.

Another terse way is something like,

DocumentTools:-Tabulate(widthmode = percentage, width = 75,
                        [[seq([seq(p[3*(i - 1) + j], j = 1 .. 3)], i = 1 .. 3)],
                         [p[10], "", p[11]]]):

where the middle cell now appears empty.

An alternative to the above is, say,

plots:-display(Array([seq([seq(p[3*(i-1)+j],j=1..3)],i=1..3),
                      [p[10], plot(axes = none), p[11]]]));

where the empty cell gets an empty plot.

Getting the last (fourth) row to be spaced exactly as you showed is trickier. That is why I also showed as a second example like this:

with(DocumentTools): with(DocumentTools:-Layout): with(DocumentTools:-Components):

InsertContent(Worksheet(Table(widthmode=pixels,width=600,alignment=center,interior=none,
                              seq(Row(seq(Cell(InlinePlot(p[3*(i-1)+j])),j=1..3)),i=1..iquo(11,3)),
                              Row(Cell(Table(exterior=none,interior= none,alignment=center,
                                             widthmode=pixels,width=400,
                                             Row(seq(Cell(InlinePlot(p[3*iquo(11, 3) + i]),padding = 0),
                                                     i=1..irem(11,3)))),padding=0,columnspan=3))))):

 

[edit] The general idea above is to use iquo and irem to construct first the 3 rows or 3, and then a row of the remaining items. Those are common techniques for splitting N objects into groups. Here's another way. If you are ok with using plots:-display, and don't need the botton row to have (center-aligned) fewer cells, then for a list p of N=11 plots you could also get it rendered in 3 columns as follows: question5_acc.mw

plots:-display(Matrix(ceil(11/3), 3,
                      (i, j) -> `if`(3*(i-1) + j > 11,
                                     plot(axes = none),
                                     p[3*(i - 1) + j])));

@Scot Gould I suspect that you're talking about a problem that affects all array-plots done using plots:-display, and not about the current query about how to deal with an odd number of plots.

There is a long-standing quirk in the GUI, such that when plots:-display is used for array-plotting the plots are all rendered left-aligned in their respective Table cells. There are two manual ways to correct for that: 1) using the mouse-pointer, select an outer (say, right) exterior border of the Table and adjust its position slightly, and 2) right-click in the Table and adjust its width property slightly. Those both cause the plots to properly realign at the Cell's centers.

This is one of several reasons why I prefer DocumentTools:-Tabulate over plots:-display, for handling Arrays/lists/Matrices/Vectors of plots, ie. the former doesn't suffer from this bug. And customized solutions using DocumentTools primitives even offers programmatic control of several choices of alignment.

I reported this problem (with intial Table rendering after calling plots:-display) years ago.

@Scot Gould Thank you. It was a typo in the accompanying text (now corrected). The code was already correct.

At the default settings (Digits=10<=15 and UsehardwareFloats=deduced) the Eigenvalues command will use parallelism within LAPACK.

The timings you describe hint that you are using a higher working precision, with software (rather than hardware double precision floats). We cannot tell because you haven't bothered to provide the code of your computation.

If the two attachments are the dotm (.m) format of your Matrices then you should inform us of that.

If this is a continuation of your very recent Question then you should provide the code you're using. You should provide the code anyway. It's OK if that means using read on .m files. But you really ought to provide the calls you make to do the computation as well as the Digits, etc.

There seems to be a problem with getting to the particular LAPACK function that benefits most from symmetric positive-definite A and symmetric B for the generalized eigen-problem. Instead it is calling the general (nonsymmetric routine) which is slower. But that is secondary to the slowdown you'll see moving from hardware Digits<=15 to higher precision software floats. But if you really need the higher precision then this might well be important. (I have not looked at the conditioning...yet.)

It's difficult to say more without your providing adequate details.

The fact that you appear to have unnecessarily split this into a separate Question thread is not very helpful.

note: The "generic" CLAPACK external code for higher (software float) precision is not parallelized. So it's slower for two reasons: 1) it's using software Maple-floats, and 2) it's not got the the same LAPACK parallelism as the hardware double-precision Intel MKL implementation. I don't know whether it is possible to beat the software float, generic, unparallelized eigenvector QRQZ compiled code with a Maple Threads/Grid parallelized implementation that does, say, separate nullspace (eigenspace basis) computations in parallel after finding the eigenvalues.

@mmcdara You may also declare names local at the top-level.

restart;

local Temperature, gamma:

Temperature[1] := 10;

10

gamma[r] := 10;

10

 

Then it becomes as straightforward to encapsulate such code within procedures. (Note that :- colon-minus syntax allows the original global name to still be referenced, if needed.)

IMO being able to declare the names (including a collection of nonpredetermined number) as local within a procedure is important. So often it becomes desirable to turn one-off code into reusable procedure(s). I reserve using double-underscore for base names that I'll never want to use to create several names (especially if the number may vary).

@mmcdara It's a personal preference, but I'd prefer to concatenate as little as possible. (The aliasing below re-uses the assigned displacements.)

Also, in general there might be other aliases in play, so you could target the ones you want here more precisely, again re-using displacements in the lookup.

restart:

mass_names := [A, B, C]

[A, B, C]

masses        := seq(M__||m, m in mass_names);
displacements := seq(x__||m, m in mass_names);

stiffnesses   := Matrix(3$2, (i,j) -> `if`(i=j, 0, K__||(cat(mass_names[i],mass_names[j]))));
dampings      := seq(xi__||m, m in mass_names);

masses := `#msub(mi("M"),mi("A"))`, `#msub(mi("M"),mi("B"))`, `#msub(mi("M"),mi("C"))`

displacements := `#msub(mi("x"),mi("A"))`, `#msub(mi("x"),mi("B"))`, `#msub(mi("x"),mi("C"))`

stiffnesses := Matrix(3, 3, {(1, 1) = 0, (1, 2) = `#msub(mi("K"),mi("AB"))`, (1, 3) = `#msub(mi("K"),mi("AC"))`, (2, 1) = `#msub(mi("K"),mi("BA"))`, (2, 2) = 0, (2, 3) = `#msub(mi("K"),mi("BC"))`, (3, 1) = `#msub(mi("K"),mi("CA"))`, (3, 2) = `#msub(mi("K"),mi("CB"))`, (3, 3) = 0})

xi__A, xi__B, xi__C

map(f->alias(f=f(t)), [displacements]):

a:=map(f->alias:-GlobalToContent[f],[displacements]):

velocities := diff(a, t):

accelerations := diff(a, t$2):

masses *~ accelerations =~ stiffnesses . `<,>`(displacements)
                           +~ dampings *~ velocities^~2;

Vector[column]([[M__A*(diff(x__A(t), `$`(t, 2))) = K__AB*x__B+K__AC*x__C+xi__A*(diff(x__A(t), t))^2], [M__B*(diff(x__B(t), `$`(t, 2))) = K__BA*x__A+K__BC*x__C+xi__B*(diff(x__B(t), t))^2], [M__C*(diff(x__C(t), `$`(t, 2))) = K__CA*x__A+K__CB*x__B+xi__C*(diff(x__C(t), t))^2]])

Download purpose_ac.mw

Alternatively, if you create your new list (ie, your `a`) prior to making the aliases then you don't have to resort to concoctions to form it afterwards. Eg,

restart:

mass_names := [A, B, C]:

masses        := seq(M__||m, m in mass_names):
displacements := seq(x__||m, m in mass_names):

stiffnesses   := Matrix(3$2, (i,j) -> `if`(i=j, 0, K__||(cat(mass_names[i],mass_names[j])))):
dampings      := seq(xi__||m, m in mass_names):

a := apply~([displacements],t):

alias~(Equate([displacements],a)):

velocities := diff(a, t):

accelerations := diff(a, t$2):

masses *~ accelerations =~ stiffnesses . `<,>`(displacements)
                           +~ dampings *~ velocities^~2;

Vector[column]([[M__A*(diff(x__A(t), `$`(t, 2))) = K__AB*x__B+K__AC*x__C+xi__A*(diff(x__A(t), t))^2], [M__B*(diff(x__B(t), `$`(t, 2))) = K__BA*x__A+K__BC*x__C+xi__B*(diff(x__B(t), t))^2], [M__C*(diff(x__C(t), `$`(t, 2))) = K__CA*x__A+K__CB*x__B+xi__C*(diff(x__C(t), t))^2]])

Download purpose_acc.mw

ps. You've been showing quite a bit of code using concatenations over the past year. But that doesn't allow safe local declaration within procedures, and so hinders programmatic encapsulation via procedures. Why do you use concatenated names instead of indexed names? (Both pretty-print with subscripts...) For example,

restart:

mass_names := [A, B, C]:

masses        := seq(M[m], m in mass_names):
displacements := seq(x[m], m in mass_names):

stiffnesses   := Matrix(3$2, (i,j) -> `if`(i=j, 0,
                                           K[mass_names[i],
                                             mass_names[j]])):
dampings      := seq(xi[m], m in mass_names):

a := apply~([displacements],t):

alias~(Equate([displacements],a)):

velocities := diff(a, t):

accelerations := diff(a, t$2):

masses *~ accelerations =~ stiffnesses . `<,>`(displacements)
                           +~ dampings *~ velocities^~2;

Vector[column]([[M[A]*(diff(x[A](t), `$`(t, 2))) = K[A, B]*x[B]+K[A, C]*x[C]+xi[A]*(diff(x[A](t), t))^2], [M[B]*(diff(x[B](t), `$`(t, 2))) = K[B, A]*x[A]+K[B, C]*x[C]+xi[B]*(diff(x[B](t), t))^2], [M[C]*(diff(x[C](t), `$`(t, 2))) = K[C, A]*x[A]+K[C, B]*x[B]+xi[C]*(diff(x[C](t), t))^2]])

Download purpose_accc.mw

@sand15 The addresses of the names returned by alias() are not the same as the addresses of the original global names. That is why your attempt did not work. (This relates to the magic way that the kernel builtin procedure alias:-BuiltinAlias works.)

An alternative might be,

restart;

alias(f=f(t)):
alias(g=g(t)):

a:=[indices(alias:-ContentToGlobal,':-nolist')];

            a := [f, g]

diff(a,t);

            d     d
           [-- f, -- g]
            dt    dt

I will file a report.

It returned both (as lists) in my Maple 16.02, but not in 17.02.

@John2020 

frontend(taylor,[cos(theta(t)),theta(t)=0,7],
         [{`+`,`*`,`=`,specfunc(cos)},{}]);

1-(1/2)*theta(t)^2+(1/24)*theta(t)^4-(1/720)*theta(t)^6+O(theta(t)^8)

subsindets(evalindets('taylor(cos(theta(t)),theta(t)=0,7)',
                      specfunc(theta),freeze),name,thaw);

1-(1/2)*theta(t)^2+(1/24)*theta(t)^4-(1/720)*theta(t)^6+O(theta(t)^8)

Download taylor_frontended.mw

And, as alternate, using frontend rather than explicitly freezing,

restart;
with(Physics):

r := x*(diff(theta(t), t))^2+y*(diff(varphi(t), t))^2:
g := (4*(f+T))*(diff(theta(t), t))^2+u*(diff(varphi(t), t))^2:

frontend(solve,[identity(r=g,diff(theta(t),t)),[x,y]],
         [{`+`,`*`,`=`,list,specfunc({identity})},{}]);

           [[x = 4 T + 4 f, y = u]]

@John2020 If you load the Physics package then the name diff is rebound.

I wasn't suggesting that you instead try to freeze calls to Physics:-diff. I was trying to suggest that you'd need to distinguish between Physics:-diff and the original, global name (and try to ensure that it is the latter which gets frozen). I posted my earlier reply from a phone, which is why it is terse. Sorry.

The code I originally provided freezes calls to the name diff, without forcibly referring to the original global name :-diff rather than the current binding of that name. But it will continue to work -- even with Physics loaded -- provided that you refer explicitly to that global name :-diff instead of the rebound diff.

restart;

with(Physics):

r := x*(diff(theta(t), t))^2+y*(diff(varphi(t), t))^2:
g := (4*(f+T))*(diff(theta(t), t))^2+u*(diff(varphi(t), t))^2:

solve(identity(subsindets(r=g,specfunc(:-diff),freeze),
               freeze(:-diff(theta(t),t))),
      [x,y]);

             [[x = 4 T + 4 f, y = u]]
First 115 116 117 118 119 120 121 Last Page 117 of 591