Carl Love

Carl Love

28015 Reputation

25 Badges

12 years, 298 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Yes, your data can be put into a matrix or array (if it isn't already so), and, like any Maple variable, that array can be saved to a file (with the save command) and retrieved in any other session (i.e., after a restart or even in a completely different worksheet) with the read command. If I do this with an array of the size that you describe, and I use some efficiency options (described below), then the save takes 1.3 seconds and the read takes 1.7 seconds. (I'm using an SSD drive, and those times are CPU-bound. I think that it'll take longer with a mechanical drive.) Here's an illustration:

restart:
#random array simulating your conditions:
A:= rtable(1..434000, 1..28, frandom(0..1), datatype= hfloat):
A[42, 23]; #some random entry for verification
                       0.0293574166199714

#Set a default directory for file I/O. You need to change this to
#something relevant to your computer:
currentdir("/Users/carlj/desktop"):

st:= time[real]():
save A, "mydata.m":
time[real]()-st;
                             1.234

restart:
A[42, 23]; #verify memory is cleared:
                           A[42, 23]

currentdir("/Users/carlj/desktop"):
st:= time[real]():
read "mydata.m":
time[real]()-st;
A[42, 23];
                             1.606
                       0.0293574166199714

The three verification steps are only there for educational purposes, and the four timing steps are only there for experimental purposes. None of those seven steps are actually needed.

Having this array in memory will not have any effect on the efficiency of Maple's GUI display. The array (like other ordinary variables) is not saved with the worksheet.

The two efficiency options mentioned above are

  1. The file's name ends with ".m". This saves the data in Maple's internal format, essentially a character-encoded binary.
  2. The array has a hardware datatype. I used hfloat, equivalent to float[8] or what's commonly called "double precision". Because of this, the array cannot contain the string data. That data can be saved in another array, and the two arrays can be stored in the same file. Or, the timestamp data could be encoded numerically (as its difference from a specific "base" time) and stored in the numeric array. The numeric encoding of timestamps is fairly easy in Maple.

Without these two efficiencies, the times are much longer (a little over a minute), which is still less than reading the CSV.

 

I'll assume that you realize that both results are correct, so I won't discuss that further (unless you ask).

First, the difference has nothing to do with using Interactive rather than Minimize. If the first case is entered as 

Minimize(x + y, {1 <= x + y}, x= 0..1, y= 0..1);

then you get the same result as your Interactive call.

Second, additional information about what's going on in the background can be obtained by setting

infolevel[Optimization]:= 5:

before making the call to InteractiveMinimize, or any other Optimization command. The extra information appears in the worksheet, not in the Maplet window (the dialog box that Interactive uses). One thing revealed by this information is that Maple knows that the solution is not unique; it refers to it as a "weak solution".

Setting a particular infolevel only needs to be done once per session (i.e., per restart).

Third, another interesting case which produces yet another solution is

Minimize(x + y, {x <= 1, y <= 1, 1 <= x+y}, assume= nonnegative);

The reason for these differences is that a simple inequality such as x <= 1 is treated just like a general multivariate linear inequality such as 1 <= x + y. Each such inequality leads to an extra row in the matrix. But there are more-efficient means of handling constraints entered as bounded ranges, such as x= 0..1; those don't lead to extra rows in the matrix. I recommend using this bounded-range form whenever possible, even for nonlinear and integer-linear problems.

The $ is the sequencing operator (see help page ?$). It still works in current Maple. The simple usage shown---a$n, where n is a nonnegative integer---produces a sequence of n copies of a. Thus [a$n] is a list of n copies of a

I'll assume that you're also removing usages of the old linalg package. You certainly should if you're not already. In that case, replace rowdim(A) with upperbound(A)[1] or LinearAlgebra:-RowDimension(A). Either will work; the first is more efficient.

The command plot3d is only for plotting surfaces. To plot curves in 3D, use plots:-spacecurve. I also added a slight transparency to the surface to make the ellipse fully visible.

f:= (x, y)-> x^2 + y^2 - 12*x + 16*y:
plots:-display(
    plot3d(f(x,y), x= -9..9, y= -9..9, transparency= .1),      
    plots:- pointplot3d(
        [[6, -8, f(6, -8)]], color= red, symbol= solidcircle,
        symbolsize = 18
    ), 
    plots:-spacecurve(
       [cos(t), sin(t), 1 - 12*cos(t) + 15*sin(t)], t = 0 .. 2*Pi,
       color= red, thickness= 3
    ),
    orientation= [-15, 68, 5],
    view= [-4.2..8.2, -8.2..4.2, -100 .. 100]
);

 

If you remove the local in the definition local ode_type:= module(), then it works, and you get the error message that you should get.

Now that you've mentioned the large number of warning messages, I think that your excessive times are due to Maple's incredibly slow Standard GUI display. Do the same thing in command-line Maple for comparison. You may also be able to improve the time in the Standard GUI by setting interface(prettyprint= 0) (I'm not sure if that will help).

If you use .mla files, then you could do the code reading and .mla creation in command-line Maple while you kept GUI Maple open. Then you could test the code in the GUI immediately (after using restart).

I agree with Joe: Maple is usually able to process 25,000 lines of code in the blink of an eye.

A parse command cannot reference local variables. So, it'll work if res is global. Change print(res) to print(:-res), or simply remove res from the local declarations.

The option is lightmodel= none.

Hints for the second problem, the equilateral triangle:

  1. The slope of the line tangent to the curve y = f(x) at x = a is f '(a).
  2. The slope of any line in the x-y plane (be it a tangent line or not) equals the (trigonometric) tangent of the angle that it makes with the positive x-axis. (Note that tangent is being used with two different meanings here.) As always, by convention, angles are measured from the positive x-axis counterclockwise to the line. Failure to follow this convention might change the sign of a trigonometric function, but its absolute value will still be correct.

So, what are the required angles in this case?

I assume that your starting matrix contains only nonnegative integers. Here's a procedure for it, not particularly elegant:

A:= <1,1,2,2; 0,1,1,3; 2,0,1,2; 4,1,0,3>:

Tally:= proc(A::Matrix(nonnegint))
local 
    M:= max(A), K:= [$0..M], 
    r:= upperbound(A)[1], c:= upperbound(A)[2],
    R:= Array((1..M+1, 1..c+2, 1..r), fill= ``), i, j, T, n
;
    for i to r do
        T:= map([ListTools:-SearchAll], K, A[i]);
        n:= nops~(T);
        for j in K do R[j+1, ..n[j+1]+2, i]:= <j, n[j+1], T[j+1][]> od
    od;
    seq(R[..,.., i], i= 1..r);
end proc
:   
Tally(A);

 

Efficiency hardly matters for these short examples. But for longer examples, the efficiency of Categorize can be greatly improved (from quadratic to linear) if the two-argument matching function (Cq in your case) can be converted to a one-argument function that produces the canonical representative of the equivalence class (under Cq) of its argument, and then you use Classify instead of Categorize. This is not always possible, but in this case, it is:

Cq:= G-> e-> evalindets(e, specfunc(G), g-> G(sort([op](g))[])):
entries(op~(ListTools:-Classify(Cq(G), L)));

As in my Answer in the other thread, this works for functions G of any number of arguments. Attempting to apply the prior Categorize technique to functions of more than two arguments would be much more complex than it is for two arguments. In that case, it'd be worthwhile to use this Classify technique even for very small cases such as the current L.
 

@maxbanados A symmetric version (i.e., invariant under any permutation of its arguments) of any function can be made like this:

MakeSymm:= f-> subs(_f= f, ()-> _f(sort([args])[])):
f_symm:= MakeSymm(f):
f_symm(y,x);

                           
f(x, y)

This works for any number of arguments and regardless of whether f has any formal definition (as a procedure or anything else).

I thought that I had answered this exact same question from you 2 or so months ago.

Anyway, the solution is simple enough that it's easier for me to rewrite it than to search for an old Answer. All such Questions can be easily answered by starting from the matrix AllPairsDistance. Whether u-v is an edge doesn't change the result.

ShorterDistance:= proc(G::GRAPHLN, u, v)
local 
    D:= GraphTheory:-AllPairsDistance(G),
    V:= GraphTheory:-Vertices(G),
    x
;
    V:= table(V=~ [$1..nops(V)]);
    add(`if`(x<0, 1, 0), x= D[V[v]] - D[V[u]])
end proc
: 
G:= GraphTheory:-RandomGraphs:-RandomGraph(99);
 G := Graph 1: an undirected unweighted graph with 99 vertices 
    and 2716 edge(s)

ShorterDistance(G, 42, 57);
                               24

 

Unless your Maple version is more than few years old, all that you need to do is 

add(A)

Maple has a decent p-adic package, although its documentation is horrendously minimal. All of the elementary functions are implemented. However, 4 is not prime. So what then were you thinking regarding p-adic? And what's great about base-4 in particular?

Maple has numerous ways to proceed such that someone with a good knowledge of arithmetic and logic but only modest knowledge of Maple and programming can quickly make progress with this.

You mentioned convert procedures. Yes, they can be useful. However, note that there's no paradigmic difference between convert procedures and any other procedures: A procedure whose name is of the form `convert/...` can be used with the convert command. That's pretty much all that there is to it.

Maple has tools suited to many of the major programming paradigms. You can write code that looks kinda like Fortran, Algol, Lisp, C++, Python, etc. And the usage of those tools can be blended arbitrarily. Most familiar data structures (such as lists, sets, hash tables, arrays, stacks, queues, records (i.e., containers with labelled fields), etc.) are directly implemented--no need to "load" anything, no need to include any header files. Nearly all infix operators can be overloaded. Nearly all stock commands can be overloaded. (Overloading means changing their behavior for certain types of input while retaining the original behavior for the rest.) You can also define your own infix operators and set their associativity to either left or right (but, alas, not set their precedence). You can easily write code that modifies other code without needing to deconstruct it down to character strings; most code can be deconstructed and examined algebraically. Nearly any command or operator can be easily modified (often it's a one-character modification) so that it "maps" itself over basic containers. (The list of features that I could include in this paragraph goes on and on, but I'll stop there.)

Indeed, in my opinion, even if you were to remove all of Maple's higher-math functionality and all of its GUI, you'd still be left with the finest programming language ever created.

Do you have any familiarity with object-oriented programming (OOP)? I think that that's the way to go for your base-4 numbers. Start reading the Maple Programming Guide by entering ProgrammingGuide into Maple's help search. Let me know if you have any questions. Object-oriented programming begins in Chapter 9.

Once you get the basic ring or field arithmetic set up for any object, Maple can automatically extend it to matrix arithmetic via the LinearAlgebra:-Generic package.

First 63 64 65 66 67 68 69 Last Page 65 of 394