Carl Love

Carl Love

28050 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@mmcdara The Maple 2022 result of your DoesThisWork.mw is this plot:

@nm X x X means the Cartesian product of with itself.

Although has works for the first part (in this case), it's far from optimal. Use member or in to check direct (or top-level) membership. Use has to check membership at any level.

@DJJerome1976 But note that the numbers returned are indices into the list of vertices rather than the vertices themselves. It's often true that those are the same thing because the vertex list is often [1, 2, 3, ...n(as with your example), but it's not always true.

@Brian Hanley I do understand what you're asking. As you probably know, it's commonly called "garbage collection". The steps mentioned so far (deletion of the pointer M, deletion from the display) are necessary for garbage collection, but (as you guessed) they're not necessarily sufficient. "What happens under the covers" is mysterious, has gotten more mysterious and much more complicated over the years, and, as far as I know, the complete details aren't publicly documented anywhere.

Regarding the kernel memory (not display memory), the few documented tidbits that are available can be found on help page ?kernelopts. See the subsections on bytesalloc, bytesused, cacheclearlimit, datalimit, gcbytesavail, gcbytesreturned, gcmaxthreads, gcthreadmemorysize, gctimes, heaps, and memusage. There is also the command gc(), but it only "garbage collects" items that the kernel has decided are ready to be collected, and the user has little control over that. Nonetheless, the process seems to work automatically most of the time (once the kernel "gets around to it"), provided that you delete the pointers, or use local pointers whose scope expires (e.g., locals inside procedures that aren't returned to the top level). Note that you can have multiple kernels (which run as separate processes) within one Maple session. Typically, each worksheet runs in its own kernel.

Regarding display memory---it's even more mysterious. You might be able to do something with the Java console, which I guess is documented somewhere independent of MapleSoft, but I know nothing about it. I simply recommend that large items not be displayed on screen at all.

@ I think that your Cloud suggestion applies to Maple Calculator. The OP here is using Maple Flow.

@Brian Hanley You say that you can "still click into and see the old M". This implies that is displayed on screen. In that case you should delete it from the screen (with Ctrl-Del) as well as deleting it from the "kernel" memory by one of the methods already mentioned. The simplest is M:= 'M'. The display memory and kernel memory are separate.

@ecterrab I only said that I was skeptical about it; I didn't say that it doesn't work in general. Skeptical means that I saw it as the likely cause of the error. It turns out that my skepticism was correct in this case. This is not the first time that I've encountered an error caused by using assuming real with no variables specified. (I don't remember details of the earlier case.)

Suppose I were to write a command that used keyword parameters. How would I tell assuming about those keywords? Does a mechanism for that exist?

@lcz Yes, clearly the WeightMatrix should be symmetric. I can't see the problem in your code. The first for-loop is redundant; it should be replaced by just AddEdge(gnew0, addedges). However, that is not the cause of the asymmetric matrix.

I was wrong to set any edge weights to 3. Although some edges in the resulting graph come from combining 3 edges in the original, their weight should only be 2. Edges in series through the deleted vertex do not contribute twice to the flow. But when edges originating at the non-deleted vertex are combined, their flows must be added. So change Contract to

Contract:= proc(G::Graph, e::And(set({string, symbol, integer}), 2 &under nops))
description "Remove edge from G by combining end vertices. Output is weighted.";
uses GT= GraphTheory;
local 
    V:= GT:-Vertices(G), n:= nops(V), J:= table(V=~[$n]), 
    W:= GT[`if`(op(2,G)=':-weighted', WeightMatrix, AdjacencyMatrix)](G), 
    u:= J[e[1]], v:= J[e[2]], R:= [1..v-1, v+1..n]
;
    try if W[u,v]=0 then error fi catch: error "edge %1 not found", e end try;
    W[u]+= W[v]; W[u,u]:= 0; 
    GT:-Graph(V[R], rtable(symmetric, W[R,R]))
end proc
:

The only difference is the change of 2*W[v] to just W[v].

@Deeshani Your expression has unbalanced parentheses. You also have numerous unnecessary pairs of parentheses. Although not erroneous, they only make it more confusing and difficult to correct. You can't correct unbalanced parentheses by adding pairs of parentheses.

@Cata I think that your way is better in this case. My way is more general, but is not as clear.

@lcz Here is the revised edge-contraction procedure. Surprisingly, it's simpler than the original.

Contract:= proc(G::Graph, e::And(set({string, symbol, integer}), 2 &under nops))
description "Remove edge from G by combining end vertices. Output is weighted.";
uses GT= GraphTheory;
local 
    V:= GT:-Vertices(G), n:= nops(V), J:= table(V=~[$n]), 
    W:= GT[`if`(op(2,G)=':-weighted', WeightMatrix, AdjacencyMatrix)](G), 
    u:= J[e[1]], v:= J[e[2]], R:= [1..v-1, v+1..n]
;
    try if W[u,v]=0 then error fi catch: error "edge %1 not found", e end try;
    W[u]+= 2*W[v]; W[u,u]:= 0; 
    GT:-Graph(V[R], rtable(symmetric, W[R,R]))
end proc
:
GT:= GraphTheory:
g:= GT:-ConvertGraph("O~tIID@wL~j`PbOqgLJ@p");
g1:= Contract(Contract(g, {1,3}), {5,6});
plots:-display(GT:-DrawGraph~(<g | g1>));
GT:-MaxFlow(g1,1,4)[1];

 

@lcz For our immediate purpose here (computing MaxFlow), we can use weighted edges to simulate multiple edges. Each original pair of edges through a deleted vertex results in a combination of 2 or 3 edges in the final graph, for which we can use weights 2 or 3. To see that it's possibly 3, consider contracting edge {1,3} from the graph 

g:= GraphTheory:-Graph({[{1,2}, 1], [{1,3}, 1], [{2,3}, 1]});

with 3 being the removed vertex. The resulting graph should be

g1:= GraphTheory:-Graph({[{1,2}, 3]});

I will rewrite Contract to do its work by addition of rows and columns of the weight matrix, which I'll construct if needed (using MakeWeighted, of course), followed by deletion of a row and a column. The weight matrix and vertex list are sufficient for the Graph command. I include the vertex list so that the vertices don't get renumbered, which would cause confusion for the user.

It's clear that the following sentence (excerpted from the passage that I quoted above) in the paper is incorrect:

  • Then, each edge is replaced by two oppositely directed arcs, the capacity of each arc is set to unity. 

The "unity" is incorrect. And Maple doesn't require us to use a pair of arcs instead of an edge, although some other software likely does.

@DSP514 The colons and semicolons are statement separators. The colon suppresses the display of the final result of the statement that precedes it; the semicolon does not suppress it. 

@bstuan "Exactly when" is poor phrasing. "If and only if" would be better. So, don't fret about not understanding it at first.

@bstuan The theorem you just posted states "int(f(x), x= a..b) converges exactly when int(g(x), x= a..b) converges." That means that they either both converge or both diverge. For your problem, they both diverge.

First 69 70 71 72 73 74 75 Last Page 71 of 709