dharr

Dr. David Harrington

5809 Reputation

21 Badges

19 years, 241 days
University of Victoria
Professor or university staff
Victoria, British Columbia, Canada

Social Networks and Content at Maplesoft.com

Maple Application Center
I am a professor of chemistry at the University of Victoria, BC, Canada, where my research areas are electrochemistry and surface science. I have been a user of Maple since about 1990.

MaplePrimes Activity


These are replies submitted by dharr

@ijuptilk Christian's answer is a better one for the roots command. For just finding the maximum amount of information, use solve. For the (very long) general formula for a cubic, use 

solve(a*x^3+b*x^2+c*x+d,x,explicit);

If the  coefficients have (exact) values, use solve also. (But if you only want numerical roots, use fsolve.)

@mmcdara V[2] evaluates to 1. Try addressof(V[2]) and addressof(1) and you see they are the same.

(op(V) shows that there are 3 separate entries in the Vector.)

@acer Thanks. (not sure why the fill value couldn't serve this purpose.)

@mmcdara I agree that the storage is sparse. What I want is that (as for the table example) when I ask for one of the unstored values in the sparse case, say V[5], I get a default value back. It seems that the default value has to be zero, it can't be set to anything else (like {}, for example).

Your f := u -> e^(-theta*u) (and elsewhere) uses "e", which has no special meaning in Maple. Use f := u -> exp(-theta*u) instead. Or in the common symbols palette choose the e next to Pi. Notice in the output that the ordinary e is in italics, but the exp e is not.

@Carl Love Thanks. Just to clarify, although I developed both algorithms, the idea of the labeled adjacency matrix giving the walks is not new, for example it is found here.

@Carl Love Thanks for the comments. The makesets code with the expand is only used for one entry of the matrix (for the vertex of interest), so if you wanted to calculate for all vertices it certainly wouldn't be good. Here's another version that has less explosive storage requirements because it condenses the entries to sums of vertex sets at each stage. The basic idea was to use LinearAlgebra:-Generic for Matrix multiplication with `*` defined as set union, but there was code creep to deal with multiples of sets (2*{1,4,5}), so it has less storage but is probably too inefficient. Could perhaps use something like f(1,2,3)*f(2,3,4)=f(1,2,3,4) instead.

WalkLength:=proc(G::Graph,v)
  uses GraphTheory;
  local x,y,u,vv,A,B,F,n,vertset,i,omega;
  if not member(v,Vertices(G),'vv') then error "vertex not in graph" end if;
  if not IsConnected(G) then return infinity end if;
  F[`0`]:=0:F[`1`]:=1:F[`=`]:=(x,y)->evalb(x=y):F[`/`]:=`/`:
  F[`+`]:=()->map(u->if type(u,`*`) then op(2,u) else u end if,`+`(args));
  F[`*`]:=proc(x,y) local i,j,q,u;
          if x=0 or y=0 then return 0
          elif x::set and y::set then
            return x union y
          elif x::set and type(y,`+`) then
            q:=map(`union`,y,x);
            return map(u->if type(u,`*`) then op(2,u) else u end if,q)
          elif y::set and type(x,`+`) then
            q:=map(`union`,x,y);
            return map(u->if type(u,`*`) then op(2,u) else u end if,q)
          elif type(x,`+`) and type(y,`+`) then
            q:=add(add(i union j,i in x),j in y);
            return map(u->if type(u,`*`) then op(2,u) else u end if,q)
          else error "unexpected error"
          end if
        end proc;
  n:=NumberOfVertices(G);
  vertset:={$(1..n)};
  A:=AdjacencyMatrix(G)*~Matrix(n,n,(i,j)->{i,j});
  B:=copy(A);
  for i from 2 do
    B:=LinearAlgebra:-Generic:-MatrixMatrixMultiply[F](B,A);
  until has(B[vv,vv],[vertset]);
  i;
end proc:

 

@mmcdara I meant only that you find other cycles in this way. It is well known in graph theory that the ringsum of cycles gives other cycles or disjoint unions of cycles, but the disjoint unions can be easily detected. So then you get the algorithm that I think you now have (this is similar to the "cut" case I did earlier in a blog here.) You can also represent the cycles as vectors with addition mod 2, just as in the cuts case.

@vs140580 I already answered your (modified) question about finding the length of the shortest walk that returns to the same vertex. Please look through the answer for the procedure and explanation.

@Carl Love 

restart:

with(GraphTheory):

C1 := {seq({i, i+1}, i=1..6), {7, 1}}:
C2 := {{1, 8}, {8, 3}, {8, 6}}:
G := Graph(C1 union C2):
DrawGraph(G, style=planar);

cb:=CycleBasis(G);

[[1, 2, 3, 8], [1, 2, 3, 4, 5, 6, 7], [1, 7, 6, 8]]

How to find [3, 4, 5, 6, 8]? Considered as sets of edges, the symmetric difference (or "ringsum") operation combines cycles into other cycles  - it kills common edges.

Actually finding cycles or counting all of them is nontrivial. Here combining all three cycles works.

cycles:=map(x->Edges(InducedSubgraph(G,x)),cb);

[{{1, 2}, {1, 8}, {2, 3}, {3, 8}}, {{1, 2}, {1, 7}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}}, {{1, 7}, {1, 8}, {6, 7}, {6, 8}}]

symmdiff(cycles[1],cycles[3],cycles[2]);

{{3, 4}, {3, 8}, {4, 5}, {5, 6}, {6, 8}}

NULL

Download FindCycles.mw

@Carl Love The last one in particular is nice. This operation is one I need to do fairly often and am always frustrated there isn't some simpler (to the average user) way. The help page for solve,details has an example using eval(r, op(indets(r)) = 3) but you have to know it's the third op. My answer has the same problem. Yours allow _Z11 etc, so again you have to know what possibililities might occur. This is compounded by the fact that extra solve commands lead to higher numbers, so the first one isn't always _Z1. To really to do it properly probably some slicing and dicing of the name is necessary.

@Samir Khan Thanks. Most other software I have, the corner handle resizes keeping the aspect ratio the same and handles on the vertical and horizontal edges change one dimension and therefore the aspect ratio.

@Carl Love But this replaces _Z4 as well, which is not what the OP wanted.

@rasmusgs At least for integrals the answer is simple; just add the option numeric, e.g. 

int(sin(x), x = 0 .. Pi, numeric)

gives 2.0000

(But sometimes, as here the exact value is nice, so maybe you want to try without numeric first.)

@vs140580 Here some minimal changes. I made it a row Vector rather than 1x15 Matrix. To see more entries of a Vector or Matrix use for example interface(rtablesize=20) at the beginning of your worksheet.

The last line of the procedure would normally be the return value. (I could have used A rather than return A.) Then you would print outside the procedure; normally print is not used within procedures to provide results.

To convert entries to floats use evalf(A). 

To work with all edges in a single line of code use map or map2. For an example see my other answer here.

Download Try_Degree_based.mw

First 20 21 22 23 24 25 26 Last Page 22 of 59