acer

32722 Reputation

29 Badges

20 years, 86 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Now Nasser Abbasi has updated his page and the numbers indicate a key difference for Matrix size > 2500. He posits that Mathematica 10.1 may be switching algorithms at that point.

As I mentioned above, there are other Rank revealing algorithms other than computing all singular values (and usually comparing magnitudes w.r.t. the largest, or otherwise estimating how many are nonzero or sufficiently small). Most of them are based on the QR decomposition.

I notice in my Mathematica 10.1 installation that the help page for its MatrixRank command still describes its methodology as being equivalent to computing how many nonzero values are returned by its SingularValueList command. So it would seem to me that either Wolfram staff have found a faster way to compute singular values (which might be remarkable) or they are using some other rank revealing algorithm. If the latter is the case then I can imagine potential (and possibly rare) issues, as I'm not aware of another algorithm which is known to always produce the same results as might be obtained by singular values examination.  I don't see any new option to control the choice of method (without simply electing to use SingularValueList instead of MatrixRank), or a documented description of any possible change in behaviour.

A lot of very smart people have examined this topic, and there is quite a bit of published material on it, because knowing the effective matrix rank can potentially reduce computation time for several popular computational tasks. And there have been improvements to rank estmation based on QR. As I said I'm not aware of any alternate method which is completely equivalent at both low and high rank estimation. Here is just one link of interest, not so very new but still interesting. But many other references can be found (using google, which naturally may use page rank computations with related math underneath!).

It should be possible to implement an alternate algorithm for Maple too. The easiest would be to use DGEQP3 from LAPACK, but that might just be a staring point. But I would hope that its implementation were not opaque, and that LinearAlgebra:-Rank would offer any such alternates by choice with a method option.

By coincidence, a few days ago I was reading an old 2009 article about finding John Francis the developer of the QR algorithm. (Frank Uhlig's article on p.19 here)

 

@tomleslie In Maple 13 there was no easy "empty plot". So to avoid an execution error for your code, the blank corner could be done as,

plot([[0,0]],axes=none)

rather than as your,

plot(axes=none)

Which version of Maple?

You can set up a PlotComponent from the Embedded Components palette, and then use SetProperty(...,refresh) to update it while your looping code is running.

There are even easier ways, in Maple 2015, which is why I ask about the version.

acer

An ellpise can also look nicer than a rectangle, for longer labels.

restart:

quad2ellipse := proc(P::specfunc(anything,:-PLOT))
  subsindets(P,
             And(specfunc(':-POLYGONS'),
                 satisfies(p->nops(p)>0
                           and op(1,p)::[[numeric,numeric],[numeric,numeric],
                                         [numeric,numeric],[numeric,numeric]])),
             proc(p) local t,r;
               (t,r):=selectremove(type,[op(p)],list(list(numeric)));
               ':-POLYGONS'(seq(op(plottools:-ellipse([(op([1,1],pp)+op([3,1],pp))/2,
                                    (op([1,2],pp)+op([2,2],pp))/2],
                                   1.3*abs(op([1,1],pp)-op([3,1],pp))/2,
                                   1.2*abs(op([2,2],pp)-op([1,2],pp))/2)),
                                pp in t), op(r)); end proc);
end proc:

with(GraphTheory):

G := Graph({{"blah","FOO"},{"bleh","FOO"},{"FOO","blah"},
            {"FOO",4444},{4444,5555},{5555,"Z"},{"Z",4444}}):
HighlightVertex(G, Vertices(G), gold):
HighlightEdges(G, G, COLOR(RGB,0.2,0.2,0.7)):

P:=DrawGraph(G): P;
quad2ellipse(P);

This hack is only a good as the original rectangle to fogure out the width. And the original goes wrong for very long labels.

@Alejandro Jakubi The purpose of the comment in my code is to to describe somewhat what the code is doing, as it might differ from what others do in such cases. It's not an instruction for the world, or a description of what I expect of other people.

I am not angry at all. Indeed I am amused by your long-standing tendency to see conspiracy and ulterior motive where none exists. Which leads me to ask, in the words of Jack Burton,

https://www.youtube.com/watch?v=WLSSh6G3Bx0 

@Alejandro Jakubi It may be OK if simplify (or another command) utilizes length while measuring the size of an expression. That depends on the structure of the expression. But I do not believe that length alone is a sensible measure of expression size for all purposes.

Suppose that one wishes to simplify a non-constant expression for the purpose of reducing the time for evaluating at a point. In that case it would not be sensible to rely on the following, as the length of the names ought not matter. Consider the following example, for which the cost of evaluation ought not (within reasonable bounds) depend on the length of the names,

length(aaaaaa+bbbbbbbbbb);
                                      23

length(a+b);
                                       9

But `simplify/size/length` does a more sensible job here, returning the same value (9, if it matters) for both of those two expressions. And MmaTranslator:-Mma:-LeafCount also returns the same value (3, if it matters) for both those expressions.

It's not difficult to come up with other problematic examples too. For example a multivariable expression which might factor in two different ways (according to choice of variable). It doesn't seem very sensible and useful for the purpose of evaluation cost (at least) if one factorization is chosen by virtue of being the one which has the least instances of the much longer name. More sensible and useful for the purpose of evaluation cost reduction would be the choice which minimizes operations regardless of name lengths.

Also, the worksheet I posted made use of simplify(...,size) and so it makes sense to use the same metric to gauge the relative success of that operation. I often see people use raw length calls in order to gauge the success of their calls to simplify(...,size), and that is not as sensible as would be using the metric that simplify(...,size) itself uses. The person who posted this Question did that very thing, which is partly why I added the comment.

You often read too much into my comments, or misinterpret them.

Now, if the purpose is to simplify so that the expression takes less space on disk, or as .m format in a .mla archive, then it could well be a whole other ballgame. I wrote my response worksheet with an eye toward evaluation cost,and if that it not what the OP intended then I hope it'll be clarified as followup.

By the way, another interesting metric can be had using the codegen[cost] command, although unfortunately it is difficult to make programmatic use of the result. What's appealing there is that its result includes the separate detail of the number of function costs. It might be nice to have some similar command which could return a list of the various counts, to which a custom weighting could be applied after the fact.

 

Without specifying the dimensions as arguments the calls Matrix([[]]) and Matrix([]) each produce a Matrix with 1 row and 0 columns.

The calls Matrix() , Matrix(0,0,[[]]) , Matrix(0,0,[]) and Matrix(0,0) each produce a Matrix with 0 rows and 0 columns.

You can build a Matrix with 0 rows and 1 column with the call Matrix(0,1) but I don't see how that could be produced by the Matrix command without specifying the dimensions explicitly in the call. (It can be done with the angle-bracket constructors, though.)

I suspect that your intended meaning for your first sentence is wrong. It's hard to be sure since the grammar is poor.

Why don't you tell us what you're trying to accomplish?

acer

This is a good question, because the displayed result from Maple are unattractive and not close to the beautiful results obtainable with some other software. I'm not aware of any very simple fix, even for configuring the node shapes.

Additional customizability would be a far better solution than would yet another hard-coded look&feel.

While that doesn't sound very encouraging, I think that additional pressure by the community to get it made a priority would not hinder progress.

acer

A little more can be squeezed out of this orange. The interpretation of positions along the curve as the sum of coordinates from three contributing circles includes a choice. For any particular set of values the order of the nesting of the circles is a matter of choice. Considered as the sum of three vectors, the end-point doesn't depend on the order in which the three contributing terms are added.

I refactored the code somewhat, to make choosing the order of nesting of the circles simpler to implement.

restart:

cycler := proc(k, p, m, n, T,
               {showcircles::truefalse:=false, showlines::truefalse:=false,
                showaxes::truefalse:=false, forceview::truefalse:=true,
                nesting::string:="B M G"}, $)
  local t, v, c, r, col, tab, terms, perm;
  uses plottools, plots;
  tab := table(["B"=1,"M"=2,"G"=3]);
  terms := [exp(I*t), -exp((k+1)*I*t), I*exp((1-p*k)*I*t)];
  r := [m*n, n, m];
  col := ["black", "magenta", "green"];
  perm := map2(`?[]`,tab,`[]`~(StringTools:-Split(nesting," ")));
  (r,col,terms) := r[perm], col[perm], terms[perm];
  c := eval([seq([Re,Im](add(terms[i]*r[i], i=1..j)), j=0..3)], t=T);
  v := add(abs(r[i]), i=1..3);
  plots:-display(
    `if`(showcircles,
         [seq(circle(c[i], r[i], ':-linestyle'=':-dot', ':-color'=col[i]), i=1..3),
          pointplot([seq(c[i], i=2..4)], ':-symbol'=':-solidcircle',
                    ':-symbolsize'=15, ':-color'=col)][], NULL),
    `if`(showlines,
         [seq(line(c[i],c[i+1], ':-color'=col[i]),i=1..3)][], NULL),
    complexplot(add(terms[i]*r[i], i=1..3), t=0..T),
    `if`(forceview, ':-view'=[-v..v,-v..v], NULL),
    ':-scaling'=':-constrained',
    ':-axes'=`if`(showaxes, ':-boxed', ':-none') );
end proc:

#cycler(5, 3, 2, 3, 2*Pi, showcircles);

cycler(5, 3, 2, 3, Pi/3, showcircles, showlines);

# The option controller=listbox is new to point release Maple 2015.1 and without
# that option the controller for the nesting parameter `perm` would be a combobox.
# The listbox controller is nice here since its value can be changed while playing.
#
# By selecting different nestings of the three circles (while it plays from
# T=0 to T=2*Pi) it can be seen that the end-point (triple vector-sum) doesn't
# depend on the choice of nesting. That's expected, but nice to visualize.

Explore( cycler(k, p, m, n, T, showcircles=circles, showlines=lines,
                showaxes=boxed, forceview=fullview, nesting=perm),
         parameters = [ [perm = ["B M G","B G M","M B G","M G B","G B M","G M B"],
                         controller=listbox, orientation=vertical, label=nesting],
                        [circles = [true,false], orientation=vertical],
                        [lines = [true,false], orientation=vertical],
                        [boxed = [false,true], orientation=vertical, placement=bottom],
                        [fullview = [true,false], orientation=vertical, placement=bottom],
                        k = -10 .. 10, p = -10 .. 10,
                        m = -10.0 .. 10.0, n = -10.0 .. 10.0,
                        [ T = 0 .. 2*Pi, animate ] ],
         initialvalues = [ k = 3, p = 3, m = 2, n = 4, T = 2*Pi ],
         placement = left, animate = false, loop, numframes = 100 );

acer

@J F Ogilvie Interesting.

The problem with Classic goes away for me using Maple 2015.0 if I remove the option ':-gridlines'=':-false' from the cycler procedure.

That option isn't even a necessary part of the code. I often include it just because the backend maplenet server being used by Mapleprimes had a bug where it always rendered 2D plots with grid lines, unless the option to disabled it were given explicitly.

Individual frames (2D plots) seem to display by themseleves in the Classic GUI. But when gridlines=false is specified then the display as an animation generates an error. I don't see the problem in the Standard GUI.

Here is a revision which hopefully makes the effects of parameters m, n, and p a little more clear.

The ratio of the radius of the magenta circle to the radius of the black circle is 1/m.

The ratio of the radius of the green circle to the radius of the black circle is 1/n.

The rate at which the magenta point travels around the magenta circle is k+1 times the rate at which the black point travels around the black circle.

The rate at which the green point travels around the green circle is p-1 times the rate at which the magenta point travels around the magenta circle.

The black and magenta points both travel counterclockwise around their respective circles, since the corresponding terms in expr share the same sign. The green point travels clockwise around the green circle, with its corresponding term in expr having the opposite sign.

I've rewritten the formula here so that the black circle now has radius n*m, but the explanations involving relative ratios remain pretty much the same. I just thought it might(?) be easier to understand. In the original Post the black circle would have fixed radius of value 1 while the magenta and green circles would get large as m or n became very small.

restart:

cycler := proc(k, p, m, n, T,
               {showcircles::truefalse:=false},
               {showaxes::truefalse:=false},
               {forceview::truefalse:=true}, $)
  local expr, t, u, up, v;
  uses plottools, plots;
  u := exp(k*I*t);
  up := exp(-k*I*t*p);
  expr := exp(I*t)*(m*n-n*u+m*I*up);
  v := abs(m*n)+abs(m)+abs(n);
  plots:-display(
    `if`(showcircles,
         [circle([0,0], m*n),
          circle([m*n*cos(T), m*n*sin(T)], n,
                 ':-linestyle'=':-dot', ':-color'="magenta"),
          circle(eval([Re(exp(I*t)*(m*n-n*u)), Im(exp(I*t)*(m*n-n*u))],
                      t=T), m,
                 ':-linestyle'=':-dot', ':-color'="green"),
          pointplot(eval([[Re(exp(I*t)*(m*n)), Im(exp(I*t)*(m*n))],
                          [Re(exp(I*t)*(m*n-n*u)), Im(exp(I*t)*(m*n-n*u))],
                          [Re(expr), Im(expr)]
                         ], t=T),
                    ':-symbol'=':-solidcircle', ':-symbolsize'=15,
                    ':-color'=["black","magenta","green"])][],
         NULL),
    complexplot(expr, t = 0 .. T, ':-color'="red"),
    `if`(forceview,':-view' = [-v .. v, -v .. v],NULL),
    ':-scaling'=':-constrained', ':-gridlines'=':-false',
    ':-axes' = `if`(showaxes,':-boxed',':-none')
                );
end proc:
cycler(5, 3, 2, 3, 2*Pi);

cycler(5, 3, 2, 3, 2*Pi, showcircles);

Explore( cycler(k, p, m, n, T, showcircles=circles,
                showaxes=boxed, forceview=fullview),
         parameters = [ [circles = [true,false], orientation=vertical],
                        [boxed = [false,true], orientation=vertical],
                        [fullview = [true,false], orientation=vertical],
                        k = -10 .. 10, p = -10 .. 10,
                        m = -10.0 .. 10.0, n = -10.0 .. 10.0,
                        [ T = 0 .. 2*Pi, animate ] ],
         initialvalues = [ k = 3, p = 3, m = 2, n = 4, T = 2*Pi ],
         placement = left, animate = false, numframes = 100 );

And with a traditional animation,

plots:-animate(cycler, [3,3,2,4,t,showcircles], t=0..2*Pi, frames=100);

 

acer

@J F Ogilvie The revised procedure is defined to expect only five arguments, whereas the original was defined to expect six.

When I revised the procedure to compute with the expression exp(-p*k*I*i) instead of exp(k*I*t)^(-p) I also removed the first procedural parameter `t`. It was just a dummy name, and wasn't otherwise useful.

A revised version of the procedure given as, say,

cycler := proc(k, p, m, n, T) local expr, t, u, up, v;
  u := exp(k*I*t);
  up := exp(-k*I*t*p);
  expr := exp(I*t) * (1 - u/m + I*up/n);
  v := 1 + abs(1/n) + abs(1/m);
  plots:-complexplot( expr, t = 0 .. T, axes = none, color=red,
                      view = [-v .. v, -v .. v] );
end proc:

would be called like so:

cycler(5, 3, 2, 3, 2*Pi);

Note how this differs from the example in the original Post: there is no longer a first (out of six) argument `t`.

That works for me in every recent version of Maple that I can find.

Obviously calling `Explore` on a function call of `cycler` would also need to involve the correct number and type of arguments.

@Carl Love Sure, there is no need to change the name for `t`, so it could be a local. Thanks.

The integer valued parameter `p` adjusts the relative frequency for the opposing term.

The parameters `m` and `n` are just simple scaling factors for the contributing terms.

Here's a reformulation that is more clear, perhaps.

cycler := proc(k, p, m, n, T) local expr, t, u, up, v;
  u := exp(k*I*t);
  up := exp(-k*I*t*p);
  expr := exp(I*t) * (1 - u/m + I*up/n);
  v := 1 + abs(1/n) + abs(1/m);
  plots:-complexplot( expr, t = 0 .. T, axes = none,
                      view = [-v .. v, -v .. v] );
end proc:

Note (not for Carl, who will already have done this in his head),

evalc( exp( k*I*t ) );

                             cos(k t) + sin(k t) I

evalc( exp( -k*I*t*p ) );

                           cos(k t p) - sin(k t p) I

I used only integer values for p. So the two formulations are equivalent. But if parameter `p` were instead set to take on float values then the plots would differ for Pi<t<2*Pi.

simplify( exp(I*t)^(-p) - exp(-p*I*t) ) assuming t>0, t<Pi, p::integer;

                               0

Also, the view=[-v..v,-v..v] adjusts the visible scale "nicely" when animating by duration `t` so that the dynamic scaling is suppressed visibly, and it mostly keeps the display centered but not when k=1. It might be interesting to have a version where `m` and `n` (or their reciprocals, if the whole thing was rescaled?) were Explore "markers" that could be moved around the plot area with the mouse cursor. I haven't looked.

@lham If you want to multiply through by that term then just apply the `expand` command to your expression instead.

@lham I think that it did work for you (and that you also re-executed the command ee:=% a second time after simplifying. Just look at the size of the simplified result compared to the original expression.

First 338 339 340 341 342 343 344 Last Page 340 of 599