Haha, hello Mike D! I figured you were talking about "a". I think I followed the 2-column matrix of node-pairs conversation for the most part, except for RE Boss's contribution which I didn't appreciate until just now. The -: initially threw me off so I thought the whole expression was replaced and not just the generate node-pairs part. It's quite clever but also very specialized to J, it would be nice to use more primitive operations. Why the dislike for "a"? I'm guessing it's a stab at removing some of the code?
Yes, the idea is that 0{C is the empty box corresponding to the 0 indices in A. Also "(<: #C) = (>./ ,A)" - that is the number of entries in C minus 1 corresponds to the maximum index in A. So you could imagine A with 3s, 4s, etc. Cheers, Mike On Sun, Nov 4, 2012 at 4:21 PM, Mike Day <mike_liz....@tiscali.co.uk> wrote: > Hello, Michal D - Mike Day here! > > Sorry, I meant your lower case "a", the boxed array of to-nodes, derived > from upper case "A" which IS the adjacency matrix, which is of course > essential. "revise" need not be provided with a as well as A, and can > make do with the 2-column matrix of node-pairs instead. RE Boss > demonstrates a nice side-effect of sparse arrays "(4 $. $.)" . > > OK - I'd never used {:: so didn't appreciate the subtlety of the ones and > twos in A! So would you need 3s & 4s etc in A to cater for constraints on > pairs of variables other than the first two? > > the other Mike D > > > > On 04/11/2012 8:54 PM, Michal D. wrote: > >> The adjacency matrix A is important because it tells us which constraint >> to >> look up in C. This also explains why the lower diagonal is doubled. >> >> For example, take the less than constraint: >> >> c =: |: (i.n) </ (i.n) >> 2 2 $ '' ; 'Dx' ; 'Dy' ; c >> +--+-------+ >> | |Dx | >> +--+-------+ >> |Dy|0 0 0 0| >> | |1 0 0 0| >> | |1 1 0 0| >> | |1 1 1 0| >> +--+-------+ >> >> This constraint is useful for filtering Dx given Dy. Let's look at how >> revDom works (revDom is the heart of the algorithm). Let's generate a >> domain for x and y. >> >> Dx=: 1 1 1 1 NB. {0,1,2,3} >> Dy=: 1 1 1 0 NB. {0,1,2} >> >> To visualize, stick Dy on the left, and Dx on top: >> >> 2 2 $ '' ; Dx ; (|:,:Dy) ; c >> +-+-------+ >> | |1 1 1 1| >> +-+-------+ >> |1|0 0 0 0| >> |1|1 0 0 0| >> |1|1 1 0 0| >> |0|1 1 1 0| >> +-+-------+ >> >> Now we use Dy to select the relevant rows of c (each row represents the >> set >> of values compatible with that value of Dy). >> >> Dy # c >> 0 0 0 0 >> 1 0 0 0 >> 1 1 0 0 >> >> Take the logical-or of these rows to compute the set of values of Dx that >> have some compatible value in Dy. >> >> +./ Dy # c >> 1 1 0 0 >> >> Finally, take the logical-and with Dx so we don't add values that weren't >> there in the first place. >> >> Dx *. +./ Dy # c >> 1 1 0 0 >> >> Now, with all this done, what if we want to filter Dy on Dx? We need to >> take the transpose of c. To prevent constant transposing, A and C store >> these for us. >> >> Mike >> >> On Sun, Nov 4, 2012 at 9:53 AM, Mike Day <mike_liz....@tiscali.co.uk> >> wrote: >> >> As far as I can understand the "revise" verb, you don't need the >>> adjacency matrix a, although it does help to have a 2-column matrix of >>> index pairs. >>> >>> I think Raul has overlooked your use of the right argument ys within that >>> verb, though he's right about selecting with it. Here's a derivation of >>> arcs without explicit recourse to the adjacency matrix (I've just >>> noticed >>> that Raul presents a similar idiom): >>> >>> arcs=. ys (]#~ (e.~ {."1)) ($#: I.@,) *|:A >>> >>> I. returns a vector of indices to the ravelled boolean; $ #: turns them >>> into a matrix of pairs of indices to an array of the shape of |:A. >>> >>> (]#~ (e.~ {."1)) selects those arcs with an element of ys as the >>> from-node >>> (or perhaps they're the to-nodes?) >>> >>> This form renders the arcs array already sorted, but note that if you do >>> need to sort the elements of an array, it's sufficient to use the idiom >>> /: ~ (rather than ({~ /:) . Presumably sorting "arcs" is >>> merely a >>> matter of taste. >>> >>> It's quite nice to be able to input several components of an argument by >>> (local) name with >>> 'A a C'=.x >>> 'ys D'=. y >>> rather than >>> A=. > 0{x >>> a=. > 1{x >>> ys=. > 0{y >>> D=. > 1{y >>> >>> As A is invariant in "ac", you could of course preset the array of >>> indices for all arcs in A, aix =: ($#: I.@,) *|:A and use aix as an >>> input to "revise" instead of a . >>> >>> I used *|:A or (0<|:A) here and wonder why you need to double its lower >>> diagonal elements. >>> >>> I also wonder whether your example will still work if there are binary >>> constraints involving variables (say z and t) indexed with 2 or 3. And >>> what happens if there are more than one binary constraints on a pair of >>> variables? eg, X+Y=4 AND X>Y ? >>> >>> I'd have been very pleased with myself if I'd come up with code as good >>> as >>> this when I started J - would be pretty pleased if I managed it now! >>> >>> Mike >>> >>> >>> >>> On 04/11/2012 2:40 PM, Raul Miller wrote: >>> >>> In >>>> A=. 0= ? (2$n)$2 NB. generate random matrix of [0,1] >>>> >>>> The 0= is unnecessary, and probably reflects a habit based on the >>>> false idea that boolean algebra is does not have an integer domain. >>>> Boolean rings have (subset of) integer domains, and [even after >>>> redefinition] boolean algebra is a boolean ring. >>>> >>>> If you ever want to treat Heyting Algebras or Bayesian Probability you >>>> might also want to consider what happens when you replace the $2 with >>>> $0. >>>> >>>> I think I would also be more comfortable with >>>> 2 2 $ ''; 'y'; 'x'; A >>>> for the displayed table, but that's a minor quibble. >>>> >>>> An alternative definition for adj might be >>>> adj=: <@I.@:* >>>> >>>> But somewhere around here, I get lost. Your use pattern for arcsX is: >>>> >>>> (i.n) arcsX A >>>> >>>> where A has the shape n,n >>>> >>>> What is the domain of the left argument of arcsX? I am guessing that >>>> it's either i.n or a single element choosen from i.n but if that is >>>> the case, I think I'd define arcsX to only work for the i.n case -- >>>> the name says "arcs" after all. Also, if I wanted to extract the >>>> values from the result of arcsX which correspond to a single value >>>> from i. n, that's simple enough -- I can select on the first column of >>>> the result. >>>> >>>> In other words, perhaps something like this: >>>> >>>> arcs=: $ #: I.@, >>>> arcs *A >>>> >>>> Also, I have not taken the time yet, to read "revise", so I will stop >>>> here. >>>> >>>> >>>> ------------------------------****----------------------------** >>> --**---------- >>> For information about J forums see http://www.jsoftware.com/**** >>> forums.htm <http://www.jsoftware.com/**forums.htm><http://www.** >>> jsoftware.com/forums.htm <http://www.jsoftware.com/forums.htm>> >>> >>> ------------------------------**------------------------------** >> ---------- >> For information about J forums see >> http://www.jsoftware.com/**forums.htm<http://www.jsoftware.com/forums.htm> >> >> > ------------------------------**------------------------------**---------- > For information about J forums see > http://www.jsoftware.com/**forums.htm<http://www.jsoftware.com/forums.htm> > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm