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

Reply via email to