Joe Riel

9660 Reputation

23 Badges

20 years, 4 days

MaplePrimes Activity


These are replies submitted by Joe Riel

@Carl Love Admittedly I haven't done this in a while (I use Windows rarely) but the actual steps seem few and simple enough. Download, install, and a simple configuration of Maple.  I highly recommend installing a compiler compatible with Maple, particularly if you use the Iterator package (which, by default, sets compile=true to all the constructors).

@Carl Love It wasn't an astute observation, rather I compared the results and wondered why there was a difference. Took me way longer than it should have to figure out the cause.  I guessed the necessary condition (repeated argument) early on, but it still took me a while to realize what was happening.  Using map should be better in that it doesn't construct another set. 

Note that MinVal (different response) does not use add, but rather an explicit loop, to sum the values. The compiler can translate add, but assumes the result is an integer, so gives the wrong result. That is a subtle Maple compiler deficiency that can be a pain to track down at times.

@Carl Love That's because you are using the form that returns sets.  It is far more efficient to supply an integer as the first argument to the Iterator constructor SetPartitions. Each iteration then returns an updated Vector, with the output in restricted growth string format.  It takes slightly more work to use that format, in the call to MinVal, however, the reduction of memory usage [and set construction] more than makes up for it. A related advantage is that in the second form I never construct all the elements of the SetPartitions at once.  One Vector is reused, the call to MinVal does not construct any new elements.  Note that the reported additional memory allocation is 0.

Follow up

I had forgotten that the SetPartitions command has a built-in transformer to convert the output to a permutation rather than the restricted growth strings format.  Using it simplifies the code and is slightly faster.  Here is the code for it.

MinVal := proc(p :: Array(datatype=integer[4])
               , lg :: Array(datatype=float[8])
               , pmin :: Array(datatype=integer[4])
               , m :: float
               , K :: float
               , n :: posint
               , len :: posint
              )
local i,j,v,x;
    v := 0.0;
    for i from 0 to n-1 by len do
        x := 0.0;
        for j to len do
            x := x + lg[p[i+j]];
        end do;
        v := v + abs(x - K);
    end do;

    # test for minimum
    if m <= v then
        v := m;
    else
        # update pmin
        for i to n do
            pmin[i] := p[i];
        end do;
    end if;
    return v;
end proc:


Var := proc(L::list(positive)
            , len :: posint
            , num :: posint
           )
local M, P, i, j, K, lg, n, p, pmin;
    n := numelems(L);
    if len*num <> n then
        error "invalid partition specification";
    end if;

    # allocate arrays used by MinVal
    pmin := Array(1..n, 'datatype'=integer[4]);

    lg := Array(evalf(ln~(L)),'datatype'=float[8]);
    K := add(i, i=lg)/num;
    M := K*len;

    P := Iterator:-SetPartitions(n,[[len,num]],'transformer=permute');

    for p in P do
        M := MinVal(p, lg, pmin, M, K, n, len);
    end do;

    return ListTools:-LengthSplit(convert(pmin,list), len);

end proc:


L := [1829.0, 1644.0, 1594.0, 1576.0, 1520.0, 1477.0, 1477.00, 1404.0
      , 1392.0, 1325.0, 1313.0, 1297.0, 1292.0, 1277.0, 1249.0, 1236.0]:

MinVal := Compiler:-Compile(MinVal):
CodeTools:-Usage((Var)(L, 4, 4));

memory used=2.28GiB, alloc change=0 bytes, cpu time=43.80s, real time=43.91s, gc time=1.86s
         [[1, 9, 13, 15], [2, 4, 14, 16], [3, 6, 10, 11], [5, 7, 8, 12]]

@Carl Love I haven't been paying much attention to this thread, so may have missed a subtlety.  Why is Var assigned the way it is, using `+` with map, rather than add?  Doing so has the weird effect of causing the duplicate value to be used only once.  Is that really the intent?  I would have written

Var := proc(L)
local s,x;
    add(abs(add(Ln(x), x=s)-lnp), s=L);
end proc:

As mentioned that gives a different result than Carl's version, since map(Ln, {1.0, 1.00}) returns a set with one element. 

@Carl Love You can use the * modifier in sprintf to avoid the double call:

 

Round := (x,n) -> parse(sprintf("%.*f",n,x)):

@brian bovril Clicking on the real_lablels.mw link generates a 404 error (resource not available)

@Carl Love For those few not sure how to solve the inequality, here is a somewhat mechanical approach. The key is to use the inequality  x <= ceil(x) < x+1

Given ceil(p/h) = n we get

  p/h <= ceil(p/h) < p/h+1
  p/h <= n < p/h+1
  p <= n*h < p+h
  0 <= n*h-p < h
  -h < p-n*h <= 0
 n*(h-1) < p <= n*h

So for a minimum p, we want p = n*(h-1)+1

@John Fredsted From your comment I suspect that you are a bit confused as to the purpose of with.  There is no choice between using with or using read, they serve completely different purposes.  The with procedure creates shortcuts for some of the exports of a package.  As stated in its help page, it can only be used at top-level (meaning not from within a Maple procedure). 

Here are the two scenarios.  Suppose you have created a source file, MyPackage.mpl, that assigns a module, MyPackage. In Maple, you could do

read "MyPackage.mpl":

You could then access the exports of the module using their fullname, say, MyPackage:-SomeExport(a,b,c).  You could also execute the command

with(MyPackage);

and then could access the exports via the shortname, SomeExports(a,b,c).  You would still have had to use the read command to assign the module.

The alternative route is to create an mla (Maple Library Archive) from the source file, install that where Maple can find it, then you don't need to execute the read command. That is, you could, at any time, use MyPackage:-SomeExport(a,b,c).  If you wanted to access its exports with shortcuts, you would, at top-level, first execute with(MyPackage). 

@John Fredsted include is actually $include, with the $ flush-left.  It is only recognized by the Maple preprocessor (and mint, the syntax checker), that is, you can only use it from tty maple  (command-line maple). One wouldn't normally use read except at run-time. A user might call read to read and evaluate a file of source code, but it generally isn't used by Maple developers creating packages.  Something you will have to decide is how you want to operate.  I'll assume that you will continue to use the Standard GUI to interact with Maple, but will write the code which assigns procedures and/or packages in external text files.  

If the package is entirely self-contained, that is, exists in one file, you can then use the read command, executed from inside the GUI, to read that file and assign whatever it assigns. That is the simplest way to operate, and you might want to start with that.  There are a few limitations.  First, the source for one module/procedure/package must exist in one file. Second, you need to use the read statement, which will be cumbersome if your current directory is different from where the package is located. You would then have to provide the full path to the source file.

The alternative route is to create Maple repositories (*.mla files), copy them to an appropriate location for your setup, then access them as you would any Maple library procedure/package.  This permits using command line Maple to process the file, which in turn permits using $include and other pre-processor directives to split the source into multiple files.  If you go this route, you probably want to create a shell script to automate the common task, which is call cmaple to build the mla and then copy it to the appropriate location.  Getting this setup takes a bit more work, but once setup you should be good to go.  

Note that there are a few differences between reading the source code for a package into Maple and accessing the same package saved into a repository. For example, if you create a module with a ModuleLoad procedure that procedure is automatically executed when the package is loaded from a repository.  It won't, however, be executed if you merely read the source code into Maple. For that case you have to add an explicit call to ModuleLoad in the body of the module, usually near the end.

 

 

The Maple with command should only be used at top-level and really only with interactive use.  Save it for use in a worksheet.  To get a somewhat equivalent effect inside a procedure, use the uses statement.  You can use it in two forms (both these are inside a procedure or module):

uses StringTools;
    StringBuffer();

uses ST = StringTools;
    ST:-StringTools();

I prefer the second form in that it is safer; it doesn't expose all the exports of StringTools but rather serves as a shortcut to accessing them. The one drawback is that mint will nag you about the global variable ST even though it isn't a global variable (it is expanded to StringTools when the body is evaluated).

 

@John Fredsted Neither here nor there, but in Emacs, using the maplev-mode I alluded to, Maple help pages can be opened from the editor. They display as highlighted text, but are the text help (not the 2D math) output of tty maple.

@John Fredsted The danger of explaining more than necessary is that it makes the task appear insurmountable.  Creating Maple packages from text files really is the best way to go and is not difficult.  You can start with a simple approach and then, if desired, refine it. The first thing you need to know how to do is use command line maple.  Okay, that isn't strictly necessary; you can read a source file into Standard Maple using the read command, however, that limits you to putting all the source in one text file.  For many projects that isn't a serious limitation.  When I first learned to write Maple packages that's what I did and it worked well enough to develop some moderately large packages.  For starters, then, if you are happy with a single source file, just create it in an external editor, read it into Maple (with the read command), and then, if you want to create a library, execute the command

LibraryTools:-Save('myPackage', "myPackage.mla");

You then need to copy the generated mla file to the appropriate location.  That is system dependent.  

The reason I migrated to my current method, using scripts and/or Makefiles, etc., is that it makes my life easier, particularly since one rarely creates an mla a single time.  It gets recreated frequently and need to be stored in the proper location. Manually copying files, etc., is tedious.  

There are many advantages to using text files.  They are robust.  They can be edited with your editor of choice. They work with external tools (mint is a very useful Maple syntax checker). They can be put under version control (i.e. they are readily diff'ed). 

Follow up:

The biggest improvement I made was switching from Windows to Linux.  Windows is not friendly for the developer.  It's possible, I used it for years but life is much easier on Linux.  A Mac presumably offers the same advantages in that it is *nix based.  On Windows, Cygwin is practically required, at least if you want to use command-line tools (I have no experience with power-shell).       

@Carl Love Carl, this looks like a GUI bug.  Running the code in tty Maple works fine.  I'll submit an SCR against this. As a work-around, just avoid displaying the results of floats that have attributes.  So you can do

 

attributes(min(map(Var,AllP)));

@Kitonum Nice approach. I wanted to use my Iterator package to do this, but it doesn't currently provide a direct scheme.  Will have to come up with a suitable algorithm.  Note that there are only 9!/(3!)^4 = 280 possible distinct partitions of the set into 3 subsets of 3.

@teh_allchemist What do you mean by simulating over a duration?  It's not clear to me how time is involved, given that these are purely algebraic equations.  Is the issue that you have a set of algebraic equations that you have to repeatedly solve, but some of the parameters (inputs) change with time, though that is incidental.   For example (toy case), you might have x^2+1 = t and you need to solve for x for various values of t. 

 

@Carl Love The read does parse a text file, but the result is the same, a global assignment.  If running tty-maple you could do

$include "test.mpl"; # assumes file was saved as text, to test.mpl

and that would be equivalent to inserting the test.mpl file into the procedure assignment, so z would be interpreted as a local. As noted, $include only works in tty maple.

First 47 48 49 50 51 52 53 Last Page 49 of 195