Carl Love

Carl Love

28110 Reputation

25 Badges

13 years, 115 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@Carl Love The code in the Answer above has been updated in several significant ways:

  1. It now handles all documented calling sequences of LinearAlgebra:-Eigenvalues, in particular the generalized eigenvalue problem (whose input is two square matrices).
  2. It now preserves all Matrix options, in particular shape and datatype, which Eigenvalues uses for algorithm selection.
  3. All options to Eigenvalues are handled, including options that do not yet exist but may be added in the future, as long as they're of type {name, name= anything}.
  4. The results are now remembered after sorting.

Regarding 2: This done by applying ToInert to the Matrices, which makes them immutable, which in turn makes them suitable as cache/remember table indices.

Regarding 3: On the off chance that an option not of that type is added, or if a completely new calling sequence is added, it'll still be handled correctly; it just won't be sorted.

Regarding 4: The earlier code sorted them after remembering them. While that did produce correct results, the new way is more efficient.

Finally, let me re-emphasive that this process is completely transparent to the end user. Once the overload is defined, you can call LinearAlgebra:-Eigenvalues in exactly the same ways that you've always called it, and it'll produce output in exactly its documented formats. The only thing that my code does is intercept that output, sort it, and remember it. The overload command is an extremely powerful tool for modifying what stock commands do in transparent ways.

@Kitonum Unfortunately, there are subtle, nonstandardized, imprecise, and often overlapping shades of meaning between residuals and errors, even when those words are used in a purely mathematical context. The present context appears to be fitting a real-valued model function to a finite set of data. In such a case the goodness of fit is often empirically checked by "plotting the residuals". One usually wants to check (often simply visually) not just the magnitude of the residuals but also that their mean is 0 (unbiasedness) and that their variance is constant over different subintervals of the independent variable (homoscedasticity). This can't be done if you use absolute values.

Of course, the 1-norm and infinity-norm of the residuals are also useful information wrt goodness of fit, and of course they use absolute value, but they don't require a plot. That a plot was requested suggests that the situation described in the first paragraph applies.

@Scot Gould The set sorting order is used in my Answer below.

@Preben Alsholm 

That's great, and very useful to know in general. Vote up! I didn't know that procedure options could be subsop'd. It's not allowed for some op numbers of a procedure.

There's 5 issues that I'd like to change. All of these are addressed in the following Answer.

  1. I don't think that option system would be desirable, as it makes the remembered data too ephemeral. Option cache can be used to replace the timewise ephemerality of system with spacewise ephermerality. 
  2. There's also the issue of the ephemerality (or, more precisely, the mutability) of Matrices themselves, which make them less-than-ideal candidates as arguments to cache- or remember-table procedures.
  3. A consistent sort of the eigenvalues and eigenvectors can make this more useful across sessions.
  4. The sort can also be used for list-form output (output= list).
  5. This can all be done with no need to change the calling sequence of LinearAlgebra:-Eigenvectors (from the end user's POV) by using overload.

All these issues are solved in the following Answer.

 

@Kitonum Your suggestion is useful; however, it should be noted that the output thus produced is nearly impossible to use programmatically as a mathematical expression---it's only suitable for display.

@lcz In addition to collapsing the multiple loops, the Cartesian product completely eliminates the need for indexing. You don't even need to count the number of pairs.

@Earl A good starting keyword for researching this may be "catenary". See the Wikipedia article with that title. In particular, see its last section "Chain under a general force".

As is well known, a static uniform chain supported by two uprights of equal height assumes the shape of a simple hyperbolic cosine function.

It's not clear from your worksheet what the direction of gravity is. Is it parallel to or perpendicular to the axes of rotation of the gears? The shape of the chain will depend on that.

@lcz I just posted an application of breadth-first search in graphs in the Posts section.

By the way, I don't think that you understand the proper English usage of re in a title. One may use (but is not obligated to use) the title "Re: X" if one is responding to something titled "X". It doesn't make sense to put "Re" on an original title, such as at the beginning of a Question thread.

@Axel Vogt Is it perhaps the case that the reason that int doesn't do this straightaway is that the constant of integration is not just a constant but rather a function that depends on y but not x? If so, then this probably shouldn't be considered a bug.

@Kitonum Yes, it is simpler and easier to understand; however, the following illustrates why I chose to use AllPairsDistance rather than Distance:

G:= GraphTheory:-SpecialGraphs:-HallJankoGraph():
CodeTools:-Usage(AllEdgesDistance(G,1)):
memory used=488.23KiB, alloc change=0 bytes, 
cpu time=0ns, real time=7.00ms, gc time=0ns

CodeTools:-Usage(Dist~(1, convert(GT:-Edges(G), list), G)):
memory used=249.29MiB, alloc change=0 bytes, 
cpu time=1.80s, real time=1.59s, gc time=437.50ms

There is nothing special about the chosen graph; any sufficiently large graph will serve.

If I modify my procedure as follows, then it'll look more like your procedure but still retain its efficiency. Note that I also sort the output wrt [distance, edge] as requested by the OP. Most of the perceived complexity of the last line of my procedure comes from including the edge in the sort criteria.

AllEdgesDistance:= proc(G::GRAPHLN, v)
uses GT= GraphTheory;
local 
    VL:= GT:-Vertices(G), V:= table(VL=~ [$1..nops(VL)]),
    D:= GT:-AllPairsDistance(G), 
    Distance:= (u,v)-> D[V[u],V[v]], 
    Dist:= (v,e)-> min(Distance~(v,e))
;
    sort((E-> `[]`~(Dist~(v,E), E))([GT:-Edges(G)[]]))
end proc
:    

 

@vs140580 Both the error message and the help page ?GraphTheory,Distance are very clear on this point. You need to change Distance(e[1], v) to Distance(g, e[1], v).

If I define DistE(v, {u,w}) to be the distance from vertex v to edge {u,w} and DistV(v, u) to be the ordinary distance between vertices, then isn't it always true that DistE(v, {u,w}) = min(DistV(v,u), DistV(v,w))?

@Carl Love Although the TableInverse procedure that I gave above is quite efficient, inverting tables is an important enough operation that it's worth having a dedicated procedure for it, and some small extra efficiency can be gained that way. Anyway, the new procedure is still quite short:

TableInverse:= proc(t::table)
local x, T:= table();
     for x in indices(t, ':-pairs') do T[rhs(x)][lhs(x)]:= () od;
     {indices}~(T)
end proc
:


Very important: The time required to invert an entire large table by this procedure can be less than the time required to find the inverse of a single entry by the select method (as proposed by Kitonum). Here's an example of that:

#Example and timing comparison:
T:= table():
R:= rand(0..2^5):
#T will have 2^18 (~1/4-million) indices:
for i to 2^9 do for j to 2^9 do T[i,j]:= 'R'()$2 od od:

TI:= CodeTools:-Usage(TableInverse(T)):
memory used=52.03MiB, alloc change=2.00MiB, 
cpu time=547.00ms, real time=537.00ms, gc time=0ns

#Get an arbitrary entry:
j:= (6,7):
x:= T[j];
                             9, 11

#Get its (setwise) inverse from inverse table already constructed:
S1:= TI[x]:
#Verify that that inverse set contains the known index:
member([j], S1);
                              true

#Get one-point setwise inverse with select:
S2:= CodeTools:-Usage(select(i-> T[i[]]= x, {indices(T)})):
memory used=24.00MiB, alloc change=6.01MiB, 
cpu time=703.00ms, real time=716.00ms, gc time=0ns

#Verify that it's the same inverse set:
evalb(S1=S2);
                              true

Efficient use of tables is one of the most important things to learn for writing efficient Maple code.

First 131 132 133 134 135 136 137 Last Page 133 of 710