acer

32727 Reputation

29 Badges

20 years, 94 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

I suggest that you do not use the MapletBuilder, if you can instead write the Maplet code by hand.

A reason is that the Builder can produce code which is more difficult to manually correct or enhance, especially as the project gets larger. But the Builder is not all-powerful, and at some point you may well face a problem that you cannot surmount with it. At that point you'd have to either start over from scratch, authoring by hand, or you'd have the more difficult task of untangling what the Builder had authored.

acer

@PatrickT If you overlay with a transparent image, then that is a foreground and not a background.

If a layer is overlaid on top (or, anywhere but at the very back) of the composite of several images, then it is not the background of the result (by defn). It's hard to see why a transparent foreground used in a final composite would earlier have been the background of either of the separate images. Why would anyone create something with a transparent background? Just so that they could superimpose on top of something else? That seems strained -- why not a transparent foreground on the original?

Anyway... Maple plots have neither convenient foreground nor background. Maybe we might keep it simple for now, and focus on the background.

I think that it would be useful if an area larger than what can get bounded by the axes were to be such a background. I'd rather have light text overlaid on top of a black background be consistent with light axes and tickmarks that are completely contained by the background. This is not possible to achieve now, with any of the techniques of plotting a "filled region" (unless the axes are faked, which can be too much work).

An image or background color for a Plot Component might suffice, as long as its access were fully programmatic.

The situation is more severe for 3D plots where, due to possible rotation, the background really must be painted before any part of the plot is. And it has to be wider as the plot's visible dimensions change with rotation.

@Christopher2222 Thanks for explaining about the missing answer. Using implicitplot sounds like a relatively costly way to fill the whole region, compared with a single polygon (one of the basic PLOT structure elements). Perhaps that was the reason for some of the down votes.

But in any case, something simpler that either of those two would be nice.

There is another kind of awkwardness situation with manually supplied filler. Suppose one builds a plot, P1, carefully placing the black background filler correctly in the sequence of plotted objects so that gets painted below all else. And it displays fine. Then the same again, for new plot P2. So a little extra effort was made in forming P1 and P2. And now one wishes to display them both together. But neither order for supplying P1 and P2 directly to plots:-display will work, because the black background of whichever is painted on top will completely obscure the entire other plot. So either piecemeal reconstruction, or removal of all but the lowest background layer, becomes necessary. I just mention it as another issue, along with having to rejig the foreground colors, etc. Ideally, the system would do all this for us.

@PatrickT Using the procedure BF that I posted above:

Without proper Array bounds (or shifts and offsets) that BF code currently only gets the bottom left quadrant of the wikipedia images for the Gauss map, since it cannot hande the negative values (the Array bounds are strctly positive, for one thing...). Also recall that the image is currently produced upside down, but can be flipped with one command.

# Gauss iterated map

m := BF(r+exp(-4.9*(x-1)^2),0,2,800,800,50000,-0.5):

ImageTools:-View(ImageTools:-Flip(m,'vertical'));

m := BF(r+exp(-6.3*(x-1)^2),0,2,800,800,50000,-0.5):

ImageTools:-View(ImageTools:-Flip(m,'vertical'));

As you likely already found, the Tent map is straightforward.

# Tent map

m := BF(r*min(x,1-x),1,2,800,800,50000,0.5):

ImageTools:-View(ImageTools:-Flip(m,'vertical'));

@carizard Try spelling it correctly, as VectorCalculus instead of VektorCalculus.

@carizard Try spelling it correctly, as VectorCalculus instead of VektorCalculus.

@Bruce Scranton 

It sounds as if your particular use case is not so much to get a very specific pixel-size for your plot as it is to just get it inserted by the GUI as large. And you have precomputed the plot structure, and even have it saved to a name.

If that's so, then this might help as an alternative approach. The Standard GUI can remember the size of a plot output region, and re-use that size when overwriting with a recalculated plot. I believe that this may even be turned on/off with the option checkbox labeled "Remember plot attributes when re-executing", in Tools->Options->Interface from the GUI's main menubar. You can enable this, and try it instead to get what you're after.

So insert a new execution group (in your Worksheet) or a new paragraph (in your Document). Plot something simple, like `plot(sin(x),x=...)`, in that execution group. Resize the resulting displayed plot output region, using the mouse-pointer. Then copy-and-paste something else into the input line, overwriting the `plot(sin(x),x=...)` call. Replace it by pasting in something else that would normally result in a 2D plot being displayed, such as kochstar(i) or plots:-display(kochstar(i)). Then execute that input line. The result should "re-use" the same plot output region, which you have already re-sized as desired.

acer

@PatrickT Here is one (crude) way, using subs. There are no offsets to make handling the indices nicer, though, so it doesn't give much more functionality.

restart:

BF := proc(fexpr,ra,rb,xr,yr,n,init::float)
local img_h,img_s,img_v,worker;
   uses LinearAlgebra, ImageTools, Compiler;
   worker := subs(':-DUMMY'=fexpr,
                  proc(data::Array(datatype=float[8],order=Fortran_order),
                       ra::float[8],rb::float[8],xr::posint,yr::posint,
                       n::posint,init::float[8])
                  local ix::posint,iy::posint,r::float[8],rscale::float[8],
                        x::float[8],y::posint;
                  rscale := (rb - ra) / (xr - 1);
                  for ix to xr do
                     r := ra + rscale * (ix - 1);
                     x := init;
                     for iy to 0 do
                        x := DUMMY;
                     end do;
                     for iy to n do
                        x := DUMMY;
                        y := trunc(x * yr) + 1;
                        if ix>=0 and xr>=ix and y>=0 and yr>=y then
                           data[y, ix] := data[y, ix] + 1;
                        end if;
                     end do;
                  end do;
                  NULL;
               end proc);
   worker := Compile(worker):
   img_h := Array(1..xr,1..yr,'datatype'='float[8]','order'='Fortran_order');
   try
      worker(img_h,HFloat(evalf(ra)),HFloat(evalf(rb)),xr,yr,n,init);
   catch:
   end try;
   rtable_options(img_h,'subtype'=Matrix);
   MatrixScalarMultiply(img_h,360.0/max(img_h),'inplace');
   img_v:=Array(img_h);
   rtable_options(img_v,'subtype'=Matrix);
   MatrixScalarMultiply(img_v,1/3.6,'inplace');
   rtable_options(img_h,'subtype'=Array);
   rtable_options(img_v,'subtype'=Array);
   img_s:=Array(1..xr,1..yr,fill=1,'datatype'='float[8]',
                'order'='Fortran_order'):
   HSVtoRGB(CombineLayers(img_h, img_s, img_v)):
end proc:

m := CodeTools:-Usage( BF(r*x*(1-x), 0, 4, 900, 900, 5000, 0.5) ):

ImageTools:-View(m);

@PatrickT 

If the procedure `f` which implements the formula is itself evalhf'able then you can pass it to evalhf(`worker`(..,`f`,..)) and have it be interpreted as fast as evalhf can do, without penalty of escaping evalhf for usual, slower interpreting. But we want `worker` Compiled instead, so that it executes 15 or more times faster even than evalhf(worker(...)).

It can likely be done by either using `subs` to overwrite a version of `worker` that has a DUMMY name as placeholder. Or possibly by taking the expression formula and unapplying it as an `option inline` operator which then becomes fully explicit as a replacement of a function call inside `worker`. (Sorry, that last sentence is hideous.) AFAIK the Compiler does not currently support references from within a given proc out to other Compiled procs (or at least, not with kludging).

More later -- have to rush off now.

@Bruce Scranton 

As Joe mentions, in general you could create a catch-all folder for such add-on material. The key thing there is that certain locations for folders named "lib" will automatically get added to `libname` upon Maple startup.

But the underlying mechanism (read: trick) at work for this sized plot insertion is that it has to first save to an .hdb help file. Offhand, I can't recall whether the private .hdb file it's using for that is referenced with a hard-coded location. I suspect that it tries to write to a particularly named .hdb file, the specific location of which may or may not matter. It's probably safe to try moving it to cat(kernelopts(mapledir),"/toolbox"), as Joe described.

I keep meaning to come back to this thing. I now believe that I might be able to wrap the two relevent INTERFACE_XYZBLAH() calls inside streamcall() and by doing so get the full effect with just a single procedural top-level return. By which I mean I should be able to get rid of that second function call, to insert into the current worksheet.

Ideally the plot should be placed into an output area, when inserted into the running worksheet. And it might be nice to (optionally) allow the actual plot command in question to be inserted into the corresponding input area. Hopefully, that would mean (behaving as usual) that subsequent re-execution of that inserted plot command would re-fill the presized output and retain the specified size. And the `Resize` call could be deleted by the worksheet author, immediately following insertion. The `Resize` call isn't wanted, longterm, as re-execution of the worksheet would cause repeated insertions, not overwrites.

Lastly, food for thought in this holiday season: the underlying mechanism allows on-the-fly insertion of programatically constructed portions of worksheet XML. What other kinds of compound and complex worksheet objects do we want to be able to programatically construct and insert, live, into a running Worksheet or Document? (I have a running wishlist of my own,...)

@Joe Riel 

It works with both the right-click context-menu .eps export and the programmatic `plotsetup` .eps driver when using the Standard GUI.

I did mention the Standard GUI in the first sentence of the Post, but I apologize to all for not explicitly stating that this was not intended to be related to the Classic GUI.

@headbam 

Your conclusion is correct.

See Atomic Identifiers for an alternative was to subscript names so that they are not table member references (and so are fully distinct from the base name).

@headbam 

Your conclusion is correct.

See Atomic Identifiers for an alternative was to subscript names so that they are not table member references (and so are fully distinct from the base name).

@PatrickT 

1) I suspect that the warmup is a attempt to not get a line of zeros as false partial results.

2) A common interpretation is that, on the "color wheel", hue is cyclic. See google for illustration. The ImageTools package interprets hue in this way, at least, in terms of degrees round a circle. Now, the logistic map was incrementing entries of Array `img_h` with each placement. So `img_h` comes out of the `worker` with nonnegint values. Scaling them all down by the maximal value gets them all to the range 0 to 1. Then scaling up by 360 places them around the circle, as hue values for ImageTools. I merged those together, scaling by 360/max(img_h). The scaling of one of the other hsv layer Arrays was just rough, for convenience and taste.

3) LinearAlgebra:-MatrixScalarMultiply calls an external compiled BLAS function, which will be faster than evalhf. But LinearAlgebra currently only accepts Matrices and Vectors and not Arrays. And ImageTools wants Arrays. Fortunately, the `subtype` of an rtable can be toggled, inplace and with no data copying cost, if the indexing matches. You should be able to use this, instead, if you really wanted to not call LinearAlgebra there,

map[evalhf,inplace]( `*`, img_h, 360.0/evalf(max(img_h)) );

I really love how Erik's color image above has sharp, consistent changes in color whenever it bifurcates. But there are lots of choices, such as non-constant scalings for example. It might be nice to analyse the distribution of the raw img_h values, so as to smear them more evenly (once) around the hue wheel.

The code is pretty much hard-coded for a particular map. So one nice improvement would be to rework it to allow the formula as a parameter. That would necessitate some changes to keep the computed discrete values within bounds of the Arrays.

There's a lot of scope for playing around with the colouring.

restart:

BF8 := proc(ra,rb,xr,yr,n)
local img_h,img_s,img_v,img_hsv;
  img_h := Array(1..xr,1..yr,'datatype'='float[8]','order'='Fortran_order');
  worker(img_h,HFloat(evalf(ra)), HFloat(evalf(rb)),xr,yr,n);
  rtable_options(img_h,'subtype'=Matrix);
  LinearAlgebra:-MatrixScalarMultiply(img_h,360.0/max(img_h),'inplace');
  img_v:=Array(img_h);
  rtable_options(img_v,'subtype'=Matrix);
  LinearAlgebra:-MatrixScalarMultiply(img_v,1/3.6,'inplace');
  rtable_options(img_h,'subtype'=Array);
  rtable_options(img_v,'subtype'=Array);
  img_s:=Array(1..xr,1..yr,fill=1,'datatype'='float[8]',
               'order'='Fortran_order'):
  img_hsv:=ImageTools:-CombineLayers(img_h, img_s, img_v):
  return ImageTools:-HSVtoRGB(img_hsv):
end proc:

worker := proc( data::Array(datatype=float[8],order=Fortran_order),
  ra::float[8],rb::float[8],xr::posint,yr::posint,n::posint)
local ix::posint,iy::posint,r::float[8],rscale::float[8],
      x::float[8],y::posint;
  rscale := (rb - ra) / (xr - 1);
  for ix to xr do
    r := ra + rscale * (ix - 1);
    x := HFloat(0.5);
    for iy to 3 do
      # Warmup.
      x := r * x * (1-x);
    end do;
    for iy to n do
      x := r * x * (1-x);
      y := trunc(x * yr) + 1;
      data[y, ix] := data[y, ix] + 1;
    end do;
  end do;
  NULL;
end proc:

worker := Compiler:-Compile(worker):

m := CodeTools:-Usage( BF8(2.6, 4, 1200, 1200, 500) ):

#ImageTools:-Preview(m);
#ImageTools:-View(m);

ImageTools:-Write(cat(kernelopts(homedir),"/bifucolor.jpg"),
                  m,'format'='JPEG'):

 

 

acer

First 427 428 429 430 431 432 433 Last Page 429 of 599