Carl Love

Carl Love

28035 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@Teep Sorry, since I couldn't copy-and-paste the code from your PDF, I didn't realize that your graph had "loops" (corresponding to the positions on the diagonal of the adjacency matrix that are nonzero). The GraphTheory package (as well as a large part of the mathematical theory of graphs) doesn't deal with that case. But here's a workaround for you that I think will suit your purposes: We can highlight the vertices that are supposed to have loops, like this:

restart
:
n:= 12 #number of vertices
:
#The next 3 lines are just me duplicating the Matrix from your PDF. 
#You don't need to do these.
A:= Matrix(n$2):
A[7]:= <1,1,0,0,0,0,1,1,0,1,0,0>:
A[9]:= <0,0,1,1,1,1,0,0,1,0,1,1>:

#Once your dimension n is set and your adjacency Matrix A defined, do this:
Loops:= select(k-> A[k,k] <> 0, [$1..n]);
A[Loops$2]:= 0:
GT:= GraphTheory:
G:= GT:-Graph(A):
GT:-HighlightVertex(G, Loops, "Magenta");
GT:-DrawGraph(G);

Please post the exact command line that you used and what the system's response was.

Also, please give the details surrounding "Maple GUI version hang most of the time." The vast majority of users use Maple's GUI version, and while it may hang occasionally, it's certainly not "most of the time" for most of them.

If you make any sincere attempt to write some code to solve this, we will help you. Indeed, I've already written a complete answer.

@Joe Riel The typespec 'rtable'(..) will select for one-dimensional rtables. There is a type operator, but it's pretty much worthless. It amounts to "procedure declared explicitly or implicitly with option operator." So `<` isn't an operator.

@Joe Riel Here's my version of the bubble sort, allowing for inplace operation if the input is an rtable, and user-specified ordering function. These two features seemed trivial to include, so I did.

BubbleSortRT:= proc(L::{list, rtable}, `&<`:= `<`, {inplace::truefalse:= false})
local 
   R:= `if`(inplace implies L::list, rtable(L), L),
   n:= rtable_num_elems(R, 'All'), k, m
;
   for k to n-1 do
      for m to n-k do
         if R(m+1) &< R(m) then (R(m),R(m+1)):= (R(m+1),R(m)) fi
      od
   od;
   `if`(L::list, [seq(R)], R)
end proc
:

 

@mmcdara Your (sub-)formula

Statistics:-Quantile~(Normal(0,1), Statistics:-Sample(Uniform(1/2, 1), N))^~2

is equivalent to the much faster code

Statistics:-Sample('Normal'(0,1), N)^~2

 

@mmcdara The Iterator:-CartesianProduct can be easily replaced with any of numerous short Cartesian product procedures. I recently posted four completely different such procedures in the thread "Combining lists".

Maple 2018 introduced embedded assignment: Assignment statements can now appear anywhere inside expressions. The statement in question says that the probability of any value of the new r.v. is the sum of the probabilities of all tuples that generate that value, and the probability of any tuple is the product of the probabilities of its elements (due to independence).

Here's code that should work in Maple 2015:

CartProd_NestedSeq:= proc(V::seq({Vector, list}))
local i,k,S;
   eval(subs(S= seq, [foldl(S, [seq(i[k], k= 1..nargs)], seq(i[k]= V[k], k= 1..nargs))]))
end proc
:
CombineDiscrete:= proc(R::list(RandomVariable), f)
uses S= Statistics, It= Iterator;
local 
   r, X, t, P:= table(sparse), nR:= nops(R), fX,
   Pr:= proc(e::(RandomVariable=realcons)) option remember; S:-Probability(e) end proc
;
   for X in 
      CartProd_NestedSeq(
         seq([solve~(op~(indets(S:-PDF(r,t), specfunc(Dirac))), t)[]], r= R)
      )
   do
      fX:= f(X[]);
      P[fX]:= P[fX] + mul(Pr(R[r]=X[r]), r= 1..nR)
   od;
   P:= [entries(P, 'pairs')];
   S:-RandomVariable(EmpiricalDistribution(lhs~(P), 'probabilities'= rhs~(P)))
end proc
:  

 

@erik10 Yes, there is a simple command in Statistics for computing (discrete) sample frequencies: Tally. For samples from continuous distributions, TallyInto is more appropriate.

@Carl Love Here are some more-primitive methods for the Cartesian product of an arbitrary number of lists or vectors. The first uses modular arithmetic and represents each entry of the product as a multi-radix integer with the radices being the number of entries in the lists and the digits being the list entries:

CartProd_MultiRadix:= proc(V::seq({Vector, list}))
local K, i, v, B:= seq(numelems(v), v= V);
   [seq([seq(V[i][1+irem(K, B[i], 'K')], i= 1..nargs)], K= 0..mul([B])-1)]
end  proc:

A slight variation of the above should work in just about any programming language. Note that the 3-argument form of irem (integer remainder) used above returns the quotient in the third-argument, which is why it's in quotes ('K').

My next method corresponds to how I personally do Cartesian products by hand: Lay out all the first entries, then all the second entries, etc.:

CartProd_byRows:= proc(V::seq({Vector, list}))
local 
   i, j, k, v, 
   B:= [seq(numelems(v), v= V)], n:= nops(B), P:= seq(mul(B[1..k]), k= 0..n), N:= P[-1]
;
   convert(
      rtable([seq([seq(seq(V[k][irem(j,B[k])+1], i= 1..P[k]), j= 0..N/P[k]-1)], k= 1..n)])^%T,
      list, nested
   )
end proc:

The ^%T is the transpose operator (switching rows and columns of a matrix). The "-1" entry of an indexed structure (as in P[-1]) means the last entry.

My third method builds the appropriate nested seq command (to an arbritrary nesting depth) and then evaluates it:

CartProd_NestedSeq:= proc(V::seq({Vector, list}))
local i,k,S;
   eval(subs(S= seq, [foldl(S, [seq(i[k], k= 1..nargs)], seq(i[k]= V[k], k= 1..nargs))]))
end proc:

The command foldl (see ?foldl) takes a function (or function symbol, in this case) and builds a nested invocation of that function. A variation of this method should be possible in most languages that support functional programming style. The eval and subs are only needed due to idiosyncracies of Maple (because seq behaves differently from most other functions).

If you're a serious student of computer programming, I recommend that you study these methods.

@vv Sorry. It is not my purpose to befuddle or obfuscate. On the other hand, I'm only interested in solutions that work for an arbitrary number of factors. In this case, that necessitates some complexity, and writing some code for this is an exercise that I recommend for any student of programming. (And I have three more completely different solutions that I'll post as a Reply to my Answer below.)

So, here's a clearer variation of the code above (the method based on Array or rtable indexing):

CartProd1A:= proc(V::seq({Vector, list}))
local v, i;
   [seq(
      rtable(
         seq(1..numelems(v), v= V), (k::seq(posint))-> [seq(V[i][k[i]], i= 1..nargs)]
       )
   )]
end proc:

 

@Matt C Anderson Thanks. Maple has a vast variety of predefined types, several tools for defining your own, and many commands that use types (such as the very important commands indets and subsindets). Types are at the heart of symbolic computation. A type is a boolean predicate that is applied to an expression. 

@acer No offense taken, even if you had meant that I had missed something, because I often do.

Here's some more-elaborate (non-uniform) examples, as requested. But this procedure cannot handle the first Example at ?DiscreteValueMap, because the support in that case is infinite.

I added an internal remember table to the procedure. It's just for efficiency; the functionality is the same.

restart
:
St:= Statistics
:
CombineDiscrete:= proc(R::list(RandomVariable), f)
uses S= Statistics, It= Iterator;
local 
   r, X, t, P:= table(sparse), nR:= nops(R), fX,
   Pr:= proc(e::(RandomVariable=realcons)) option remember; S:-Probability(e) end proc
;
   for X in 
      It:-CartesianProduct(
         seq([solve~(op~(indets(S:-PDF(r,t), specfunc(Dirac))), t)[]], r= R)
      )
   do
      P[(fX:= f(seq(X)))]:= P[fX] + mul(Pr(R[r]=X[r]), r= 1..nR)
   od;
   P:= [entries(P, 'pairs')];
   S:-RandomVariable(EmpiricalDistribution(lhs~(P), 'probabilities'= rhs~(P)))
end proc
:  
Dice:= 'St:-RandomVariable(DiscreteUniform(1,6))' $ 2: #quotes make them independent
Game:= CombineDiscrete([Dice], (x,y)-> piecewise(x=1, -4, y=1, -4, abs(x-y))): 
`2D6`:= CombineDiscrete([Dice], `+`): #sum of two six-sided dice

We add a "double-or-nothing" kicker to the game: If a second roll of a pair
of dice has an even sum, the payoff (either positive or negative) is 
doubled; if odd, the payoff is zero.
`2or0`:= CombineDiscrete([Game, `2D6`], (g, `2d6`)-> piecewise(`2d6`::even, 2*g, 0)):
St:-Mean(`2D6`);
                               7
St:-StandardDeviation(`2D6`, numeric);
                          2.415229458
St:-Mean(`2or0`);
                               -1
                               --
                               9 
St:-Variance(`2or0`);
                              1241
                              ----
                               81 

Now we consider the sum of 4 plays of the double-or-nothing game:
`4G`:= CombineDiscrete(['`2or0`'$4], `+`):
S:= St:-Sample(`4G`, 2^17):
St:-Histogram(S, gridlines= false);

 

@acer I said "with finite support", which is a subset of "from discrete distributions". I'm using support as per its usual mathematical definition rather than as it's used by Statistics. I don't see a way to handle a discrete distribution with infinite support.

@acer Could the OP be thinking about the CUDA package (?CUDA)?

I know that here you're just experimenting with MutableSets, but is any type of set, mutable or not, appropriate for this task? I mention this because in some of your other Questions I'm sure that you've used sets for tasks for which they were they were ill suited, where lists would've been better.

A set is a good choice over a list if the slightly increased time to build it is more than compensated by the substantial savings in element look-up times. A desire to keep numbers in order is not a good reason to use a set, IMO.

 

First 281 282 283 284 285 286 287 Last Page 283 of 708