X^(1/3)' Behaves Differently for Negative Scalar 'X' and Vector 'X' with Negative Values

`x^(1/3)` behaves differently for negative scalar `x` and vector `x` with negative values

I'm not looking for a workaround e.g. function(x) {sign(x) * (abs(x)) ^ (1/3)}.

I'm interested in an answer that explains what is happening differently to the vector than to the negative value when provided as a numeric scalar.

how does the ^ operator think differently about vectors and scalars?

You seem to believe that c(-0.2, 1)^(1/3) translates to c(-0.2^(1/3), 1^(1/3)). This is incorrect. Operator ^ is actually a function, that is, (a) ^ (b) is as same as "^"(a, b). Therefore, the correct interpretation goes as follows:

   c(-0.2, 1)^(1/3)
=> "^"(c(-0.2, 1), 1/3)
=> c( "^"(-0.2, 1/3), "^"(1, 1/3) )
=> c( (-0.2)^(1/3), (1)^(1/3) )
=> c( NaN, 1 )

Now, why doesn't -0.2^(1/3) give NaN? Because ^ has higher operation precedence than +, -, * and /. So as it is written, it really implies -(0.2^(1/3)) instead of (-0.2)^(1/3).

The lesson is that, to avoid buggy code, write your code as (a) ^ (b) instead of just a ^ b.


Additional Remark:

I often compare ^ and : when teaching R to my students, because they have different behaviors. But they all show the importance of protecting operands with brackets.

(-1):2
#[1] -1 0 1 2

-1:2
#[1] -1 0 1 2

-(1:2)
#[1] -1 -2
2*3:10
#[1] 6 8 10 12 14 16 18 20

(2*3):10
#[1] 6 7 8 9 10

2*(3:10)
#[1] 6 8 10 12 14 16 18 20

See ?Syntax for details of operator precedence.

Operator precedence of unary minus (-) and exponentiation (^) outside vs. inside function

Because of the surprisingly low precedence of the "unary minus" (-) operator, combined with R's convention for raising negative numbers to fractional powers. -27^(1/3) is read as "calculate 27^(1/3) (==3), then invert the sign". If we instead compute (-27)^(1/3), we get NaN, because a negative number can't reliably be raised to a fractional power. Whether the evaluation is inside or outside of a function is a red herring; the issue is whether (-27) is evaluated as an expression first (which it is if you assign it to a function argument or a variable, or put it in parentheses).

The precedence of unary minus is discussed on this mailing list thread from 2009 and R FAQ 7.33, and more generally in this math.stackexchange question. There's a (rather technical) explanation of why a negative value to a fractional power is NaN in ?"^":

Users are sometimes surprised by the value returned, for example
why (-8)^(1/3) is NaN. For double inputs, R makes use of IEC
60559 arithmetic on all platforms, together with the C system
function pow for the ^ operator. The relevant standards
define the result in many corner cases. In particular, the result
in the example above is mandated by the C99 standard. On many
Unix-alike systems the command man pow gives details of the
values in a large number of corner cases.

Is there a difference between a^2 and a^2L?

R uses an integer exponent version R_pow_di internally, but the ^ operator only calls R_pow. That being said, R_pow does special case x^2 as x*x. Therefore, the precision is identical, but the 2L version ought to be slightly slower due to long->double coercion at the C level. This is demonstrated in the following benchmark.

lngs<-rep(2L,1e6)
dbls<-rep(2.0,1e6)
n<-sample(100,1e6,replace=TRUE)
x<-rnorm(1e6)
microbenchmark(x^lngs,x^dbls,n^lngs,n^dbls)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# x^lngs 8.489547 9.804030 12.543227 11.719721 13.98702 19.92170 100 b
# x^dbls 5.622067 6.724312 9.432223 7.949713 10.89252 59.15342 100 a
# n^lngs 10.590587 13.857297 14.920559 14.200080 16.65519 19.55346 100 c
# n^dbls 8.331087 9.699143 12.414267 11.403211 14.20562 19.66389 100 b

This is nothing to lose sleep over.

Links go to the source mirror. Note that R_ADD, R_SUB, R_MUL and R_DIV are defined as C macros to take advantage of type overloading, but R_POW is defined to inline the x^2 = x*x special case then calls R_pow (lower case). The checking for that special case again in R_pow would be duplicative except that R_pow is called internally other places.

Operator precedence of unary minus (-) and exponentiation (^) outside vs. inside function

Because of the surprisingly low precedence of the "unary minus" (-) operator, combined with R's convention for raising negative numbers to fractional powers. -27^(1/3) is read as "calculate 27^(1/3) (==3), then invert the sign". If we instead compute (-27)^(1/3), we get NaN, because a negative number can't reliably be raised to a fractional power. Whether the evaluation is inside or outside of a function is a red herring; the issue is whether (-27) is evaluated as an expression first (which it is if you assign it to a function argument or a variable, or put it in parentheses).

The precedence of unary minus is discussed on this mailing list thread from 2009 and R FAQ 7.33, and more generally in this math.stackexchange question. There's a (rather technical) explanation of why a negative value to a fractional power is NaN in ?"^":

Users are sometimes surprised by the value returned, for example
why (-8)^(1/3) is NaN. For double inputs, R makes use of IEC
60559 arithmetic on all platforms, together with the C system
function pow for the ^ operator. The relevant standards
define the result in many corner cases. In particular, the result
in the example above is mandated by the C99 standard. On many
Unix-alike systems the command man pow gives details of the
values in a large number of corner cases.

Modulo of negative numbers

This solution is branchless, but performs % twice:

function wrapIndex(i, i_max) {
return ((i % i_max) + i_max) % i_max;
}

It should be said the C#/Java behavior of % is assumed, i.e. the result has the same sign as the dividend. Some languages define the remainder calculation to take the sign of the divisor instead (e.g. mod in Clojure). Some languages have both variants (mod/rem pair in Common Lisp, Haskell, etc). Algol-68 has %x which always returns a non-negative number. C++ left it up to implementation until C++11, now the sign of the remainder is (almost) fully specified according to the dividend sign.

See also

  • Wikipedia/Modulo operation

Why can't I raise to a negative power in numpy?

In NumPy, the logic used to choose the output dtype of an operation like a_range ** s is based on dtypes, not values. That means that a_range ** -2 has to have the same output dtype as a_range ** 2.

It's important that something like numpy.array([2]) ** 2 give integer output, so that means that numpy.array([2]) ** -2 has to give integers or nothing. They picked nothing; raising integers to negative integer powers is an error in NumPy.

If you want floating-point output, make floating-point input:

a_range = np.arange(2, n + 1, dtype=float)

or

a_range = np.arange(2, n + 1).astype(float)

There are a few weird aspects of NumPy's type rules you might not expect from the above description. One is that for operations involving both scalars and arrays, the scalar's dtype may actually be "demoted" based on its value before the input dtypes are used to choose the result dtype:

>>> (numpy.array([1], dtype='int8') + numpy.int32(1)).dtype
dtype('int8')
>>> (numpy.array([1], dtype='int8') + numpy.array([1], dtype='int32')).dtype
dtype('int32')

Here, the scalar numpy.int32(1) gets "demoted" to int8, but the arrays don't get demoted. (It's actually a bit more complex than just demoting to int8, particularly for signed/unsigned handling; see the implementation for the full details.)

Second, when uint64s are involved, NumPy may suddenly appear to be okay with negative exponents:

>>> numpy.arange(5, dtype='uint64') ** -2
__main__:1: RuntimeWarning: divide by zero encountered in power
array([ inf, 1. , 0.25 , 0.11111111, 0.0625 ])

This is because NumPy cannot find an integer dtype big enough for both uint64 values and negative values, so it gives up and coerces the inputs to floats. The same can be seen with a positive exponent of signed dtype, as long as you avoid scalar type "demotion":

>>> numpy.arange(5, dtype='uint64') ** numpy.array([2], dtype='int32')
array([ 0., 1., 4., 9., 16.])

redirect to a page if browser not supports javascript in asp.net MVC

Wow at all the -1. Erm, well... it may not be valid, but the meta-in-noscript hack (as everyone's already posted and been voted down for) really is the only way to do what you want. But:

I need to redirect the users to a Notification Page, if the user's browser don't support javascript

I think what you want isn't what you need. No-JS redirection is horrible for usability/accessibility. Please don't do that.

Consider an approach like SO's instead: keep the user on the same page, but just include an on-page notification that scripting is unavailable:

<noscript>
<div id="noscript-warning">Stack Overflow works best with JavaScript enabled</div>
</noscript>

You can use CSS to make this big and red and appear on top of the whole of the rest of the page if you have to.

You can be more specific too. Often you need not only JavaScript, but support for certain scripting features that aren't available everywhere. For example IEMobile (pre-8) does have JavaScript, but has stunted DOM support which stops you running most modern scripts. Or you might be relying on HTML5-related interfaces that aren't everywhere yet. In that case you can sniff client-side and set the notification's visibility manually:

<head>
<style type="text/javascript">
#scriptwarning {
position: absolute; z-index: 9;
top: 25%; left: 25%; width:50%; height: 50%;
color: red; background: white;
border: dashed red 1px;
}
body.jsok #scriptwarning { display: none; }
</style>
</head><body>
<script type="text/javascript">
// Sniff capabilities in whatever way is necessary
//
if ('featureWeWantToUse' in window) {
document.body.className= 'jsok';
}
</script>
<div id="scriptwarning">
JavaScript is disabled, or too rubbish on your browser to do what we want.
See the <a href="browsersupport.html">supported browsers</a> page for more information.
</div>
</body>


Related Topics



Leave a reply



Submit