def arctangent(y, x=None, null=<NUM_LIT:0>, broadcast=False, rtol=default_rtol, atol=default_atol):
if sps.issparse(y):<EOL><INDENT>if x is None:<EOL><INDENT>y = y.copy()<EOL>y.data = np.arctan(y.data)<EOL>return y<EOL><DEDENT>elif null is not None and null != <NUM_LIT:0>:<EOL><INDENT>y = y.toarray()<EOL>if sps.issparse(x): x = x.toarray()<EOL><DEDENT>else:<EOL><INDENT>(yr,yc,yv) = sps.find(y)<EOL>xv = np.asarray(x[rr,rc].flat)<EOL>res = y.copy()<EOL>res.data = arctangent(yv, xv, null=null)<EOL>res.eliminate_zeros()<EOL>return res<EOL><DEDENT><DEDENT>elif sps.issparse(x): x = x.toarray()<EOL>if x is None: res = np.arctan(y)<EOL>else:<EOL><INDENT>if not broadcast: (y,x) = unbroadcast(y,x)<EOL>res = np.arctan2(y, x)<EOL>if null is not None:<EOL><INDENT>if rtol is None: rtol = default_rtol<EOL>if atol is None: atol = default_atol<EOL>z = np.isclose(y, <NUM_LIT:0>, rtol=rtol, atol=atol) & np.isclose(x, <NUM_LIT:0>, rtol=rtol, atol=atol)<EOL>res[z] = null<EOL><DEDENT><DEDENT>return res<EOL>
arctangent(x) is equivalent to atan(x) except that it also works on sparse arrays.
arctangent(y,x) is equivalent to atan2(y,x) except that it also works on sparse arrays.

The optional argument null (default: 0) specifies the result found when y and x both equal 0. If
null is None, then an error is raised on this condition. Note that if null is not 0, then it is
more likely that sparse arrays will have to be reified. If null is set to None, then no attempt
is made to detect null values.

The optional argument broadcast (default: False) specifies whether numpy-like (True) or
Mathematica-like (False) broadcasting should be used. Broadcasting resolves ambiguous calls to
arctangent, such as artangent([a,b,c], [[d,e,f],[g,h,i],[j,k,l]]). If broadcasting is True, 
arctangent(y,x) behaves like numpy.arctan2(y,x), so [a,b,c] is interpreted like [[a,b,c],
[a,b,c], [a,b,c]]. If broadcasting is False, [a,b,c] is interpreted like [[a,a,a], [b,b,b],
[c,c,c]].