acer

32505 Reputation

29 Badges

20 years, 11 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

In Maple 17 the so-called "action code" behind an embedded component is accessible using right-click context-menu items like "Edit Value Changed Action" on the component themselves.

In Maple 16 all the action codes were accessible only from the Properties popup panel, which itself is accessed via right-click context-menu of the components.

When an embedded component is inserted into the worksheet from the Components palette its action code is essentially empty; it usually just contains this fragment (with its rather poor advice to use DocumentTools:-Do),

use DocumentTools in 
# Enter Maple commands to be executed when the specified
# action is carried out on the component.
# Use: 
#    Do( %component_name );
# and
#    Do( %component_name = value );
# to set and get properties of the component.
# You can also use arbitrary expressions
# involving components, e.g.:
#    Do( %target = %input1 + 2*%input2 );
# Note the %-prefix to each component name.
# See ?CustomizingComponents for more information.

end use; 

I find DocumentTools:-Do to be quite inadequate for serious work; its special evaluation rules hinder more than help, and it lacks the full power of DocumentTools:-GetProperty and SetProperty.

A somewhat common practice is to put just a one or a few function calls behind in the components -- as such action code -- with the procedures defined in the Startup or Code-edit regions. That makes it easier to edit them all at once, and easier to share common controlling code amongst several similar components.

acer

You are assigning to `T` (the module local name) the numeric result from the first instance of calling fsolve.

But then the second time you call build the expression eqT it contains that numeric value instead of an unassigned symbol.

Try something more like this, using a separate name for the result.

test:=module()

   uses DT = DocumentTools;
   export suwak;
   local T;
	 

   suwak:=proc()
   local amb, solT;

      amb := evalf(DT:-Do(%SL_test)); #slider value
      eqT := 11728.59290-6.614552014*T
             = (T-amb)*(10+4.819840000*10^(-8)*(T^2+88804)*(T+amb)); #equation to fsolve
      solT:= fsolve(eqT, T = 0 .. 2000); #solution
      DT:-Do(%mc_test=amb); #slider value to mathcontainer
      DT:-SetProperty('LBL_test', 'caption',
                      cat("= ", sprintf("%.3f", solT))); # results from fsolve to label

   end proc;

end module;

acer

While your OpenMaple programme is running, interrupt it. I mean, if you are running it in a commandline shell then try Ctl-c. If you've coded your program with suitable calls to `queryInterrupt` then you can make use of this as you see fit.

The purpose of the queryInterrupt, I believe, is to detect the interrupt-request in such a way that your OpenMaple code can handle it as you see fit.

This can also be useful for define_external (or call_external calls) used from regular Maple. While in some compiled "external" function Maple may not get enough control to halt, even if the user has emiited Ctl-c or pressed the red-button on the GUI menubar. But if the external code were to make periodic calls to `queryInterrupt` then that could provide the opportunity to detect the interrupt (and act how you wish... emit an error, or what have you...)

That's my rough understanding, at least.

acer

One consideration is the power to control the namespace. For example, allowing names used as exports from some packages to be used also (concurrently) as assigned names (in procedures as locals, or wherever).

Another consideration is convenience. How easily can the user specify that a package name is to be used. Especially relevant for convenience is the case where the user does not need or want to assign to the name.

Power and flexibility vs ease of use is an eternal struggle for software design. And each of the ways you mention can be considered in those two respects. How well they fare will also involve how often the package names get utilized in those scenarios.

ps. I prefer packagename:-packageexport over packagename[packageexport] in the case that the package has been implemented as a module. Some reasons relate to the colondash help-page and tragi-comic scenarios where packagename[':-packageexport'] might be needed over packagename[packageexport]. I believe it a great shame that the square-bracket indexing was used throughout the help of module based packages implemented back in Maple 6,7,8 just because not all table based packages had been updated to modules. I find the need to iterate programmatically over a package's exported routine names -- using the square bracket indexing form -- is rare in most people's usage and doesn't justify having suboptimal Help.

acer

This might work, even if `a` is assigned some indexable value (eg. a:=[3,4] or whatever).

   plot(sin(x), labels=[typeset('a[0]'), "some text"]);

acer

In Maple 17 your original example appears to work ok.

In Maple 16 you might be able to try one of these kinds of workaround (depending on your more involved situation),

restart:
with(Statistics):

probfunc := i->piecewise(i=1,0.25,i=2,0.4,i=3,0.35,0):

Y := RandomVariable(ProbabilityFunction=probfunc,Support=1..3):

Mean(Y);

                          2.100000000

Variance(Y);

                          0.5900000000

Z := RandomVariable(ProbabilityTable([0.25,0.4,0.35])):

Mean(Z);

                              2.10

Variance(Z);

                            0.590000

X := RandomVariable(EmpiricalDistribution(<1,2,3>,
                    probabilities=[0.25,0.4,0.35])):

Mean(X);

                        2.0999999999999996

Variance(X);

                          0.5900000000

acer

SetCoordinates not SetCoordinate.

acer

The Explore command has special evaluation rules on its first argument (so that your `plot` call doesn't evaluate before `k` gets a numeric value, etc.) This makes things awkward.

One way to work with this behaviour is to put evaluation of your expressions inside a procedure, and simplyexplore a function call of that procedure. There are a few examples using procedures calls on the Explore example worksheet.

restart:

k := 4* 10-5 ;
mpg[o] := 45;
mpg[ave] := mpg[o] - k*(md /2 );
mpg[mave] := mpg[o] - k*(m / 2);

F:=proc(MD)
  eval('plot'(7.28*m*((1/mpg[mave])-(1/mpg[ave])),m=0..200000),md=MD);
end proc:

F(15000);

Explore(F(md), parameters=[md = 150000..200000]);

Another way is to use GUI equation labels (if enabled, they appear on the right-hand side of your GUI displayed output, and are entered using Ctl-L I believe). In your original example you might instead have used the labels from the mpg[mave] and mpg[ave] assignment lines inside the first argument of your original Explore example, as replacements for appearances of mpg[mave] and mpg[ave].

The special evaluation rules on Explore's first argument are unfortunate, and have been there since its first inception (Maple 11, was it?). It gives the thing a rather un-Maple'ish feel, I think. It's not even really needed, to get the plot explorations possible using context-menu to launch the PlotBuilder on a given output expression. It would be more consistent with other parts of Maple such as the plots:-animate and `frontend` commands to allow a calling sequence something like (this won't work in Maple 17, or course):

   Explore( plot,
            [ 7.28*m*( (1/(mpgo - k*m/2 ) - (1/mpgo - k*md/2) ) ), m=0 .. 200000 ],
            parameters = [k=1/3000 .. 1/2000, mpgo = 40 .. 50] );

acer

For fun...

S := (a,n) -> Matrix([seq([seq(a^k*combinat[stirling2](i,k),
                          k=1..i),0$(n-i)],i=1..n)]):

S(1,3);

                                  [1  0  0]
                                  [       ]
                                  [1  1  0]
                                  [       ]
                                  [1  3  1]
S(a,5);

                        [a    0      0      0    0 ]
                        [                          ]
                        [     2                    ]
                        [a   a       0      0    0 ]
                        [                          ]
                        [      2     3             ]
                        [a  3 a     a       0    0 ]
                        [                          ]
                        [      2      3     4      ]
                        [a  7 a    6 a     a     0 ]
                        [                          ]
                        [       2      3      4   5]
                        [a  15 a   25 a   10 a   a ]

acer

`op` works for a list or a set.

`rtable_num_elems` works for a Vector, Matrix, or Array.

But `numelems` works for them all.

Why do you need to call `solve` more than once here?

restart:

tau:=proc(jj)
   if not type(jj,numeric) then
      return 'procname'(args); end if;
   cat(tau,jj); end proc:
eta:=proc(cc)
   if not type(cc,numeric) then
      return 'procname'(args); end if;
   cat(eta,cc); end proc:
mix:=proc(jj,cc)
   if not ( type(jj,numeric) and type(cc,numeric) ) then
      return 'procname'(args); end if;
   cat(mix,jj,cc); end proc:

basesol:=solve({log(pC[j,c]/(1-pC[j,c]))=mu+tau(j)+eta(c)+mix(j,c)},pC[j,c])[1]:
solform:=eval(pC[j,c],basesol):

K:=50;C:=20;
cat(p,'C',1..20):=seq([seq(solform,j=2..K)],c=1..20):

acer

I believe that writing it from scratch in Maple would be an easier way to get an efficient implementation than would be attempting as you have here to translate (close to line-by-line) an implementation from Matlab or some other language.

I particular, the many calls to SearchArray (to replicate `find`, say), the many elementwise `~` operations, all producing copies of Arrays, is slow. Not using datatype=float[8] throughout does not help.

I suggest doing initial edge detection -- using convolution say. Then threshold a bit, perhaps. The write a proc to populate a float[8] accumulator Array, inplace, using the edge info Array. Make it evalhfable & Compilable, Then right another proc which analyzes the accumulator results (to "de-Hough" or threshold, etc). The at the very end, a proc which draws the deduced circles/shapes on an image Array. This should be able to run in a few seconds. And one of the expensive bits -- the accumulator population -- can likely be parallelized by Task splitting across all the deteced edge points.

I'm excited to try this approach. But not for a few days at the very least...

acer

Maybe you can just scale the image down, and then do the 3D matrixplot with a few modifications?

restart;
with(ImageTools):
with(plots):

a:=Read(cat(kernelopts(homedir),"/lighthouse1.jpg")):

c:=Scale(ToGrayscale(a),1..300):
rtable_options(c,'subtype'=Matrix); # no need for double copying

matrixplot(map[evalhf](`*`,c,200),style=point,shading=zhue,orientation=[0,0],
           symbolsize=5,scaling=constrained);

The image is simply scaled down, to get better GUI responsiveness. The scaling=constrained option better respects the width/height ratio. And by muliplying the z-values (above, by 200) you can get more depth visible when rotated in 3D. And by adjusting the symbolsize you may gain some effects (eg. on the bleedthrough). So you can vary and experiment with those three adjustments.

I just tried it in Maple 12 as well. Such amazing performance for the 3d plot rotation! (I'm using 64bit Linux and an Nvidia card, with hardware accel. purportedly enabled. But it is much slower in Maple 16/17.)

The color intensity is much nicer too, on the 3D plot's zhue shading. But that can be obtained in 16/17 with the lightmodel=none option.

acer

The Standard GUI is relatively slow to render and rotate 3D density-style plots, if the number of grid points is moderately large.

I can't quite tell whether making a rotatable 3D plot is your actual goal, or not...  If it is, then you'll have to reduce the image somehow, sure.

Another possiblity for a 3D plot might be to make use `surfdata` and subsop the image Array into into COLOR substructure. But you'd likely still need to reduce the image somehow. This would give a smoother surface than would `matrixplot`, but maybe you want the granularity of the latter?

BTW, the values of the grayscale conversion are just one way amongst several possible for getting the "intensity". Another way is to grab the 3rd ("V"=intensity) layer of the HSV conversion. And since you seem to want zhue shading, then one way to get that is to replace the 1st ("H"=hue) layer with the 3rd layer after doing a RGBtoHSV conversion.

This attachment reads an image file, does the replacement of "H" layer by the "V" layer (force-spread to 0..1), and writes out the result after max'ing out both the "S"=saturation and "V"=intensity layers. Then it sticks both on a pair of Labels. Sure, you can't rotate it in 3D, but it works pretty fast and the GUI still behaves well afterwards. This approach is more of a replacement for 2D `densityplot` or `listdensityplot` (for which the Standard GUI responds quite a bit worse than it does for even the 3D plot). You may, or may not, want to force-spread the hue to match 0..1 end-points.

[edit: You could get fancy with the Labels and use SetProperty to adjust the Label componet's pixelHeight and pixelWidth to be in the same propertion as the image Arrays first two dimensions, and even scale down the image Array to match the number of pixels displayed on the Label, to minimize file i/o). I didn't do all that.]

VasH.mw

acer

I would have expected to see something within 0.6 ulps of 7.100000001e8 and 7.0999999820e8 seems too far off for the default working precision setting Digits=10.

This is already better,

restart: 
Digits:=11:
2^29.403243784;

                                       8
                        7.1000000014 10 

After all, is this not an "atomic" operation?

Here's something fun, for all the lovers of automatic simplification. Compare the results of these various computations (the restarts are necessary). The middle one is the one to note.

restart:
a:=29.403243784:
for i from 10 to 50 do
  Digits:=i:
  2^a;
end do;

restart:
for i from 10 to 50 do
  Digits:=i:
  2^29.403243784;
end do;

restart:
p:=proc() option trace; local i;
for i from 10 to 50 do
  Digits:=i:
  2^29.403243784;
end do;
NULL;
end proc;
p();

And if you really love automatic simplification then you might like these too:

restart:

4^(1/2);

                              (1/2)
                             4     

'(4^(1/2))^29.403243784';

                                      8
                        7.099999982 10 

2^(1/2), type(2^(1/2),numeric), type(Pi,numeric);

                       (1/2)              
                      2     , false, false

'(2^(1/2))^29.403243784', 'Pi^29.403243784';

                                 29.403243784
                  26645.82515, Pi            

Since exact 2^(1/2) is not rational it might seem a bit weird for that example to auto-simplify.

acer

First 252 253 254 255 256 257 258 Last Page 254 of 337