try=: 3 : 0 c=:12 d=:14 if. c*y<0 do. c elseif. d*y>:0 do. d end. ) try _3 12 try 0 14 try 3 14 c=:12 d=:14 y=:_3 (c*y<0)+(d*y>:0) 12 x=:0 (c*y<0)+(d*y>:0) 12 x=:3 (c*y<0)+(d*y>:0) 12 Roger, Most people seem to go first to the vocabulary to find a starting place to solve their problems.
Wouldn't it be useful to go to "Control Structures" to find a major improvement such as the one you just wrote: if. c*y<0 do. c elseif. d*y>:0 do. d end. or: (c*y<0)+(d*y>:0) There are many places where newer and better ways of doing things could be added to save lots of new users many pitfalls. Linda -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Roger Hui Sent: Saturday, May 18, 2013 12:40 PM To: Programming forum Subject: Re: [Jprogramming] newbie help: how to avoid division by zero > 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. This is literally true. However, since the early days of APL (1960s) when you see "conditional" you can think of a combination of arithmetic and relationals. For example, if you have an array x, and you want the value c if x is negative and d if x is non-negative, that result can be computed: (c*x<0)+(d*x>:0) As you indicated, computing this with @. (on a scalar by scalar basis!) would have been orders of magnitude slower. It's a great thing that 0 times any number is 0, even 0*_ . http://www.jsoftware.com/help/release/iamend.htm (from 2004) is also relevant. On Sat, May 18, 2013 at 4:30 AM, Marshall Lochbaum <[email protected]>wrote: > 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 > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
