MaplePrimes Commons General Technical Discussions

The primary forum for technical discussions.

We have just released updates to Maple and MapleSim.

Maple 2019.2 includes corrections and improvements to a variety of areas in the product, including a new “Go to page ____” option in print preview (that am personally quite pleased about), sections are expanded by default when printing or exporting, a fix to a problem using non-executable math with text in document mode that sometimes made it impossible to advance to a new line using Enter, improvements to VectorCalculus, select, abs and other math functions, support for macOS Catalina, and more.  We recommend that all Maple 2019 users install these updates.

This update is available through Tools>Check for Updates in Maple, and is also available from our website on the Maple 2019.2 download page, where you can also find more details.

For MapleSim users, the MapleSim 2019.2 family of products includes enhancements in the areas of model development and toolchain connectivity, including substantial enhancements to the MapleSim CAD toolbox.   For more details and download instructions, visit the MapleSim 2019.2 download page.

Although the graph of a parametrized surface can be viewed and manipulated on the computer screen as a surface in 3D, it is not quite suitable for printing on a 3D printer since such a surface has zero thickness, and thus it does not correspond to physical object.

To produce a 3D printout of a surface, it needs to be endowed with some "thickness".  To do that, we move every point from the surface in the direction of that point's nomral vector by the amount ±T/2, where T is the desired thickness.  The locus of the points thus obtained forms a thin shell of thickness T around the original surface, thus making it into a proper solid. The result then may be saved into a file in the STL format and be sent to a 3D printner for reproduction.

The worksheet attached to this post provides a facility for translating a parametrized surface into an STL file.  It also provides a command for viewing the thickened object on the screen.  The details are documented within that worksheet.

Here are a few samples.  Each sample is shown twice—one as it appears within Maple, and another as viewed by loading the STL file into MeshLab which is a free mesh viewing/manipulation software.


Here is the worksheet that produced these:



I experienced a significant obstacle while trying to generate independent random samples with Statistics:-Sample on different nodes of a Grid multi-processing environment. After many hours of trial-and-error, I discovered an astonishing workaround, and I achieved excellent time and memory performance. Since this seems like a generally useful computation, I thought that it was worthy of a Post.

This Post is also worth reading to learn how to use Grid when you need to initialize a substantial environment on each node before using Grid:-Map or Grid:-Seq.

All remaining details are in the following worksheet.

How to use Statistics:-Sample in the `Grid` environment

Author: Carl Love <> 1 August 2019


I experienced a significant obstacle while trying to generate indenpendent random samples with Statistics:-Sample on the nodes of a multi-processor Grid (on a single computer). After several hours of trial-and-error, I discovered that two things are necessary to do this:


The random number generator needs to be seeded differently in each node. (The reason for this is easy to understand.)


The random variables generated by Statistics:-RandomVariable need to have different names in each node. This one is mind-boggling to me. Afterall, each node has its own kernel and so its own memory It's as if the names of random variables are stored in a disk file which all kernels access. And also the generator has been seeded differently in each node.


Once these things were done, the time and memory performance of the computation were excellent.


Digits:= 15

#Specify the size of the computation:
(n1,n2,n3):= (100, 100, 1000):
# n1 = size of each random sample;
# n2 = number of samples in a batch;
# n3 = number of batches.

#Procedure to initialize needed globals on each node:
Init:= proc(n::posint)
local node:= Grid:-MyNode();
   #This is wrapped in parse so that it'll act globally. Otherwise, an environment
   #variable would be reset when this procedure ends.
   parse("Digits:= 15;", 'statement');

   randomize(randomize()+node); #Initialize independent RNG for this node.
   #If repeatability of results is desired, remove the inner randomize().

   (:-X,:-Y):= Array(1..n, 'datatype'= 'hfloat') $ 2;

   #Perhaps due to some oversight in the design of Statistics, it seems necessary that
   #r.v.s in different nodes **need different names** in order to be independent:
   N||node:= Statistics:-RandomVariable('Normal'(0,1));
   :-TRS:= (X::rtable)-> Statistics:-Sample(N||node, X);
   #To verify that different names are needed, change N||node to N in both lines.
   #Doing so, each node will generate identical samples!

   #Perform some computation. For the pedagogical purpose of this worksheet, all that
   #matters is that it's some numeric computation on some Arrays of random Samples.
   :-GG:= (X::Array, Y::Array)->
         proc(X::Array, Y::Array, n::posint)
         local s, k, S:= 0, p:= 2*Pi;
            for k to n do
               s:= sin(p*X[k]);  
               S:= S + X[k]^2*cos(p*Y[k])/sqrt(2-sin(s)) + Y[k]^2*s
         end proc
         (X, Y, n)
   #Perform a batch of the above computations, and somehow numerically consolidate the
   #results. Once again, pedagogically it doesn't matter how they're consolidated.  
   :-TRX1:= (n::posint)-> add(GG(TRS(X), TRS(Y)), 1..n);
   #It doesn't matter much what's returned. Returning `node` lets us verify that we're
   #actually running this on a grid.
   return node
end proc

The procedure Init above uses the :- syntax to set variables globally for each node. The variables set are X, Y, N||node, TRS, GG, and TRX1. Names constructed by concatenation, such as N||node, are always global, so :- isn't needed for those.

#Time the initialization:
st:= time[real]():
   #Send Init to each node, but don't run it yet:
   #Run Init on each node:
   Nodes:= Grid:-Run(Init, [n1], 'wait');
time__init_Grid:= time[real]() - st;

Array(%id = 18446745861500764518)


The only purpose of array Nodes is that it lets us count the nodes, and it lets us verify that Grid:-MyNode() returned a different value on each node.

num_nodes:= numelems(Nodes);


#Time the actual execution:
st:= time[real]():
   R1:= [Grid:-Seq['tasksize'= iquo(n3, num_nodes)](TRX1(k), k= [n2 $ n3])]:
time__run_Grid:= time[real]() - st


#Just for comparison, run it sequentially:
st:= time[real]():
time__init_noGrid:= time[real]() - st;

st:= time[real]():
   R2:= [seq(TRX1(k), k= [n2 $ n3])]:
time__run_noGrid:= time[real]() - st;



R1 and R2 will be different because different random numbers were used, but they should have similar histograms.

      <R1 | R2>, #side-by-side plots
      'title'=~ <<"With Grid\n"> | <"Without Grid\n">>,
      'gridlines'= false

(Plot output deleted because MaplePrimes cannot handle side-by-side plots!)

They look similar enough to me!


Let's try to quantify the benefit of using Grid:

speedup_factor:= time__run_noGrid / time__run_Grid;


Express that as a fraction of the theoretical maximum speedup:

efficiency:= speedup_factor / num_nodes;


I think that that's really good!


The memory usage of this code is insignificant, which can be verified from an external memory monitor such as Winodws Task Manager. It's just a little bit more than that needed to start a kernel on each node. It's also possible to measure the memory usage programmatically. Doing so for a Grid:-Seq computation is a little bit beyond the scope of this worksheet.




Here are the histograms:

Hare in the forest

The rocket flies




Plotting the function of a complex variable



There are no efficient algorithms for this.
How would you simplify by hand the expression

512*b^9 + (2303*a + 2304)*b^8 + (4616*a^2 + 9216*a + 4608)*b^7 + (5348*a^3 + 16128*a^2 + 16128*a + 5376)*b^6
 + (4088*a^4 + 16128*a^3 + 24192*a^2 + 16128*a + 4032)*b^5 + (1946*a^5 + 10080*a^4 + 20160*a^3 + 20160*a^2 
+ 10080*a + 2016)*b^4 + (728*a^6 + 4032*a^5 + 10080*a^4 + 13440*a^3 + 10080*a^2 + 4032*a + 672)*b^3 
+ (116*a^7 + 1008*a^6 + 3024*a^5 + 5040*a^4 + 5040*a^3 + 3024*a^2 + 1008*a + 144)*b^2 
+ (26*a^8 + 144*a^7 + 504*a^6 + 1008*a^5 + 1260*a^4 + 1008*a^3 + 504*a^2 + 144*a + 18)*b + 9*a^8 
+ 36*a^7 + 84*a^6 + 126*a^5 + 126*a^4 + 84*a^3 + 36*a^2 + 9*a + 1

to  (a+2*b+1)^9 - a*(a-b)^8   ?


We’re excited to announce that we have just released a new version of MapleSim. The MapleSim 2019 family of products helps you get the answers you need from your models, with improved performance, increased modeling scope, and more ways to connect to your existing toolchain. Improvements include:

  • Faster simulation speeds, both within MapleSim and when using exported MapleSim models in other tools

  • More simulation options are now available when running models imported from other systems

  • Additional options for FMI connectivity, including support for variable-step solvers with imported FMUs, and exporting models using variable step solvers using the MapleSim FMI Connector add-on

  • Improved interactive analysis apps for Monte Carlo analysis, Optimization, and Parameter Sweep

  • Expanded modeling scope in hydraulics, electrical, multibody, and more, with new built-in components and support for more external Modelica libraries

  • New add-on library: MapleSim Engine Dynamics Library from Modelon provides specialized tools for modeling, simulating, and analyzing the performance of combustion engines

  • New add-on connector: The B&R MapleSim Connector gives automation projects a powerful, model-based ability to test and visualize control strategies from within B&R Automation Studio

See What’s New in MapleSim 2019 for more information about these and other improvements!

The Joint Mathematics Meetings are taking place next week (January 16 – 19) in Baltimore, Maryland, U.S.A. This will be the 102nd annual winter meeting of the Mathematical Association of America (MAA) and the 125th annual meeting of the American Mathematical Society (AMS).

Maplesoft will be exhibiting at booth #501 as well as in the networking area. Please stop by to chat with me and other members of the Maplesoft team, as well as to pick up some free Maplesoft swag or win some prizes.

This year we will be hosting a hands-on workshop on Maple: A Natural Way to Work with Math

This special event will take place on Thursday, January 17 at 6:00 -8:00 P.M. in the Holiday Ballroom 4 at the Hilton Baltimore.


There are also several other interesting Maple related talks:

MYMathApps Tutorials

MAA General Contributed Paper Session on Mathematics and Technology 

Wednesday January 16, 2019, 1:00 p.m.-1:55 p.m.

Room 323, BCC
Matthew Weihing*, Texas A&M University 
Philip B Yasskin, Texas A&M University 


The Logic Behind the Turing Bombe's Role in Breaking Enigma. 

MAA General Contributed Paper Session on Mathematics and Technology 

Wednesday January 16, 2019, 1:00 p.m.-1:55 p.m.
Room 323, BCC
Neil Sigmon*, Radford University 
Rick Klima, Appalachian State University 


On a software accessible database of faithful representations of Lie algebras. 

MAA General Contributed Paper Session on Algebra, I 

Wednesday January 16, 2019, 2:15 p.m.-6:25 p.m.
Room 348, BCC
Cailin Foster*, Dixie State University 

Discussion of Various Technical Strategies Used in College Math Teaching. 

MAA Contributed Paper Session on Open Educational Resources: Combining Technological Tools and Innovative Practices to Improve Student Learning, IV 

Friday January 18, 2019, 8:00 a.m.-10:55 a.m.
Room 303, BCC
Lina Wu*, Borough of Manhattan Community College-The City University of New York 

An Enticing Simulation in Ordinary Differential Equations that predict tangible results. 

MAA Contributed Paper Session on The Teaching and Learning of Undergraduate Ordinary Differential Equations 

Friday January 18, 2019, 1:00 p.m.-4:55 p.m.
Room 324, BCC
Satyanand Singh*, New York City College of Technology of CUNY 

An Effort to Assess the Impact a Modeling First Approach has in a Traditional Differential Equations Class. 

AMS Special Session on Using Modeling to Motivate the Study of Differential Equations, I 
Saturday January 19, 2019, 8:00 a.m.-11:50 a.m.

Room 336, BCC
Rosemary C Farley*, Manhattan College 
Patrice G Tiffany, Manhattan College 


If you are attending the Joint Math meetings this week and plan on presenting anything on Maple, please feel free to let me know and I'll update this list accordingly.

See you in Baltimore!


Maple Product Manager

We have just released updates to Maple and MapleSim, which provide corrections and improvements to product functionality.

As usual, the Maple update is available through Tools>Check for Updates in Maple, and is also available from our website on the Maple 2018.2.1 download page, where you can also find more details.

For MapleSim users, use Help>Check for Updates or visit the MapleSim 2018.2.1 download page.

We have just released an update to Maple, Maple 2018.2. This release includes improvements in a variety of areas, including code edit regions, Workbooks, and Physics, as well as support for macOS 10.14.

This update is available through Tools>Check for Updates in Maple, and is also available from our website on the Maple 2018.2 download page, where you can also find more details.

For MapleSim users, the update includes optimizations for handling large models, improvements to model import and export, updates to the hydraulics and pneumatics libraries, and more. For more details and download instructions, visit the MapleSim 2018.2 download page.

If one looks in the profile of Rouben Rostamian , then one sees that any search in his Posts, Questions, Answers, and Replies is linked with MaplePrimes only. I informed  MaplePrimes staff about that disturbance without any effect. Using the opportunity, I'd like to pay attention of MaplePrimes users to many clones in the forum. This is a problem for ages: clones vote up themselves and impose one's opinion on  others. Several years ago some clones were deleted. It would be nice to continue that process.

Hi Primes Users,

We’re back with another tech support challenge that we wanted to share with you!

A customer had been having issues launching Maplets using the standard double-clicking method. This is a known issue that rarely occurs, but is being addressed for a future release. In the meantime, we were able to provide this person with a command-prompt-based way of opening the Maplet, and we thought it would be great to share in case you run into the same kind of problem.

After suggesting a few workarounds, our Team Lead was able to offer a command-prompt based way of solving the problem. Since command prompts are the target of batch scripts, which we had already used as a workaround for another issue, we just needed a way of programmatically creating scripts based on the command prompt code for each file.

Using various commands from the FileTools package (including a technique suggested by our Team Lead), we were able to put together code that takes all files in a particular folder (namely, a folder named “Maplets” on the Desktop), and creates a new batch script from a template that is based on the command prompt code (provided that the template is saved in the same Maplets folder under the file name “Maplet script”):

restart; with(FileTools): username := kernelopts(username):

directory := cat("C:\\Users\\", username, "\\Desktop\\Maplets"):

dir := ListDirectory(directory): dir := Basename~(dir):

main := cat(directory, "\\Maplet script.txt"): body := Import(main):

n := numelems(dir):

for i to n do

script := cat(directory, "\\launch ", dir[i], ".txt");

batch := cat(directory, "\\launch ", dir[i], ".bat");

newbody := StringTools:-Substitute(body, "name", dir[i]);

Export(script, newbody);

Rename(script, batch);

end do:

Script template:

if not "%minimized%"=="" goto :minimized

set minimized=true

start /min cmd /C "%~dpnx0"

goto :EOF


"C:\Program Files\Maple 2018\bin.X86_64_WINDOWS\mapletviewer.exe" "C:\Users\%USERNAME%\Desktop\Maplets\name.maplet"

Before using the Maplet script:

After using the Maplet script:

If the appropriate executable is referenced, and the relevant file paths are adjusted accordingly, one should be able to adapt this process to other programs and their corresponding files.  In fact, any batch script that needs to be modified programmatically can be modified using these techniques.  Does anyone have other useful batch scripts that they’ve modified programmatically in Maple using similar techniques?

*(including dragging the files to the executable directly, which only seemed to work when the executable was in its original directory)

Hi MaplePrimes Users!

It’s your friendly, neighborhood tech support team; here to share some tips and tricks from issues we help users with on a daily basis.

A customer contacted us through a Help Page feedback form, asking how to add a row or column in a Matrix. The form came from the Row Operations help page, but the wording of the message suggested that the customer actually wanted to insert a new row or column altogether. Such manipulations can often be accomplished by a command in the ArrayTools package, but the only Insert command currently available is the one for Vectors and 1-D Arrays. Using the Concatenate command from that package, and various commands from the LinearAlgebra package (including the SubMatrix command), we were able to write two custom procedures to perform these manipulations:

InsertRow := proc (A::rtable, n::integer, v::Vector[row])
    local R, C, top, bottom;
    uses LinearAlgebra;
    R := RowDimension(A); C := ColumnDimension(A);
    top := SubMatrix(A, [1 .. n-1], [1 .. C]);
    bottom := SubMatrix(A, [n .. R], [1 .. C]);
    return ArrayTools:-Concatenate(1, top, v, bottom);
end proc:

InsertColumn := proc (A::rtable, n::integer, v::Vector[column])
    local R, C, left, right;
    uses LinearAlgebra;
    R := RowDimension(A); C := ColumnDimension(A);
    left := SubMatrix(A, [1 .. R], [1 .. n-1]);
    right := SubMatrix(A, [1 .. R], [n .. C]);
    return ArrayTools:-Concatenate(2, left, v, right)
end proc:

# test cases:

M := Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]):
v := Vector[row]([2, 2, 2]):
v2 := Vector[column]([2, 2, 2]):
seq(InsertRow(M, i, v), i = 1 .. 4);
seq(InsertColumn(M, i, v2), i = 1 .. 4);

We then reworked this problem using some handy indexing and construction notation that allows our previous procedures to save on the variable constructions and syntax:

InsertRow := proc( A :: rtable, V :: Vector[row], r :: posint )
    return < A[1..r-1,..]; V; A[r..-1,..] >:
end proc:

InsertColumn := proc( A :: rtable, V :: Vector[column], c :: posint )
    return < A[..,1..c-1] | V | A[..,c..-1] >:
end proc:

M := Matrix(3, 3, [seq(i, i = 1 .. 9)]);
A := convert(M, Array);
U := Vector[row]( [ a, b, c ] );
V := convert( U, 'Vector[column]' );
seq(InsertRow( A, U, i ), i=1..4);
seq(InsertColumn( A, V, i ), i=1..4);
seq(InsertRow( M, U, i ), i=1..4);
seq(InsertColumn( M, V, i ), i=1..4);

1 2 3 4 5 6 7 Last Page 1 of 75