Your reasoning about performance is a bit off here. You say you want to reduce the number of operations, and that a conditional division procedure would let you do that. Even in assembly, where the penalty for conditionals is much less than in J, this isn't true. Here are the assembly instructions that would be used in a single division in Robert's solution:
z =: y=0 z =: _*z z =: y+z z =: x%z All of these instructions take the same amount of time to execute, one machine cycle. Here's the version you would use for conditional execution: z =: 0 jumpif (y=0) END z =: x%y END: This requires a bit of a trick to avoid jumping when y is not equal to zero: regardless of which branch we want to do, we set z to zero and then exit if y is zero or do the division if it's not. It looks like it's just three instructions, but jump operations take a lot longer than arithmetic operations. This is because instructions in the processor are split into steps in order to run many of them at once (while the first instruction is in its last step, the one after that will be in its second-to-last step and so on). If the processor is processing a jump, however, then it doesn't know which instruction will be processed next, so it can't do this (well, actually it guesses a branch and begins executing it, but if it's wrong it still has to start from scratch so the result is similar). Modern processors tend to have around 10 steps in the pipeline, so a jump operation will usually take about ten times as long as an arithmetic operation. In J, the overhead for conditionals, which usually use @. in tacit code, is even higher. Here's a timing comparison between Robert's solution and a conditional using @. : a =. ?@$~1e7 b =. ?@$~1e7 6!:2 'c1 =. a%b+_*b=0' 0.389194 6!:2 'c2 =. a %`0:@.(0=])"0 b' 6.23016 c1 -: c2 1 The results are the same, but the version based only on arithmetic is much faster. Chris Burke's version in this thread is even better: 6!:2 'c3 =. a (%*0~:]) b' 0.279997 In short, when you see the word "conditional" you should think "bad performance" almost immediately. When they exist, arithmetic solutions are faster by orders of magnitude. Marshall On Fri, May 17, 2013 at 09:13:17PM -0500, P T wrote: > Thanks Devon and Robert. > > Sure, we can replace zeros with infinity and vice versa before and after > division. But, can it be avoided? What I am looking for is conditional > division without writing an explicit loop. My intention is to represent an > electrical transmission network with matrices and they can potentially be > large. I am trying to minimizing the number of operations. > > I am reading on sparse matrices in "Learning J" by Roger Stokes and looks > like it can do what I am looking for. But, I am not sure if it actually > does not perform the unnecessary operations (i.e. division by zeros) or > just a display issue. > > x =: 1 $. 6 6 NB. an empty 6x6 matrix > x =: 4 5 6 7 ( 0 0 ; 1 1; 2 2; 3 3) } x NB. insert some data > x > 0 0 │ 4 > 1 1 │ 5 > 2 2 │ 6 > 3 3 │ 7 > > y =: 1 $. 6 6 > y =: 1 2 3 4 ( 0 0 ; 1 1; 2 2; 3 3) } y > y > 0 0 │ 1 > 1 1 │ 2 > 2 2 │ 3 > 3 3 │ 4 > > x%y > 0 0 │ 4 > 1 1 │ 2.5 > 2 2 │ 2 > 3 3 │ 1.75 > > Thanks, > PT > > > > On Fri, May 17, 2013 at 6:45 PM, Robert Knight > <[email protected]>wrote: > > > *PT-* > > > > To modify the (infinite) "zero-division" result from *infinity* to > > *zero*... > > > > How about adding infinity to the divisor's zero-elements? > > > > *z =: x%y+_*y=0* > > > > > > ]x =. 2 2 $ 2 > > > > 2 2 > > 2 2 > > > > ]y =. 2 2 $ i.4 > > > > 0 1 > > 2 3 > > > > ]z =. x%y+_*y=0 > > > > 0 2 > > 1 0.666667 > > > > *-Robert Knight* > > (Also a J-newbie) > > > > > > On Fri, May 17, 2013 at 6:44 PM, P T <[email protected]> wrote: > > > > > > > I am learning J (J602) and dividing one table with another. When division > > > by zero occurs, I want the the value to be zero instead of infinity. For > > > example, in the results below, I want the first element to be 0.0 instead > > > of _ > > > > > > ]x =. 2 2 $ 2 > > > 2 2 > > > 2 2 > > > > > > ]y=. 2 2 $ i.4 > > > 0 1 > > > 2 3 > > > > > > x%y > > > _ 2 > > > 1 0.666667 > > > > > > > > > May be I can replace all occurrences of _ with 0.0. But, can I avoid this > > > additional step? > > > > > > Thanks, > > > PT > > > ---------------------------------------------------------------------- > > > For information about J forums see http://www.jsoftware.com/forums.htm > > > > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
