Element-wise exponentiation

Hi,

I have this code:

N = 100;
n = 1:N;
2.^(-n)

and the final line returns the error:

ERROR: syntax: invalid syntax "2.^"; add space(s) to clarify

I’ve tried adding a space before ^ and after it, and neither of those efforts to fix this error worked. Naturally, what I want is a vector of [1, 1/2, 1/2^2, 1/2^3, 1/2^4, …, 1/2^N]. I know one round-about way of achieving what I want (namely exp.(-log(2)*n)), but I just wanted to know if there are any other ways (besides using a loop and defining my desired vector element-by-element, of course) of doing this?

Thanks for your time

this works for me (I guess .^ is the operator here and should be ‘separated by spaces’)

julia> 2 .^ (1:10)
10-element Array{Int64,1}:
    2
    4
    8
   16
   32
   64
  128
  256
  512
 1024
2 Likes

Odd, doing that with -n doesn’t work, I just tried it.

The error message tells you what to do:

julia> 2 .^ (-n)
ERROR: DomainError with -1:
Cannot raise an integer x to a negative power -1.
Make x or -1 a float by adding a zero decimal (e.g., 2.0^-1 or 2^-1.0 instead of 2^-1), or write 1/x^1, float(x)^-1, x^float(-1) or (x//1)^-1

Here’s the result:

julia> 2.0 .^ (-n)
100-element Array{Float64,1}:
 0.5
 0.25
 0.125
 0.0625
 0.03125
 0.015625
 0.0078125
 0.00390625
 0.001953125
 0.0009765625
 0.00048828125
 0.000244140625
 0.0001220703125
 ⋮
 1.6155871338926322e-27
 8.077935669463161e-28
 4.0389678347315804e-28
 2.0194839173657902e-28
 1.0097419586828951e-28
 5.048709793414476e-29
 2.524354896707238e-29
 1.262177448353619e-29
 6.310887241768095e-30
 3.1554436208840472e-30
 1.5777218104420236e-30
 7.888609052210118e-31
3 Likes

Yeah. I am sure there is a reason for that (someone can probably elaborate).
Interestingly 2 ^ -1 works just fine.
So I guess Julia CAN raise an integer x to a negative power -1.

EDIT: I realized this does not work with z=-1; 2^z
So I guess its a matter of how/when the minus 1 / inversion is applied

Oops, I just skimmed passed the error message as I was getting used to ones that I couldn’t understand.

“You should get in the habit of reading through all the error messages that you encounter.”
Bla bla bla, and so on and so forth.
We all know the deal: Often times we just want things to work and don’t take enough time to read and understand.
Julia error messages aren’t always helpful but in 50% of the cases they immediately tell me what I need to do, esp. when it comes to little syntax or method problems.

On a sidenote: One of the best error messages I’ve ever encountered are implemented in Elm. They are helpful, explanatory and respectful at the same time. It’s astonishing how error messages can shape programming culture. :slight_smile:

Quick edit to suggest sth to read: https://elm-lang.org/news/compiler-errors-for-humans

Still trying to understand 2^-1
Why does the first expression work, but when I try to evaluate what ‘code_lowered’ returns, I get an error…?

julia> 2 ^ -1
0.5

julia> @code_lowered 2 ^ -1
CodeInfo(
1 ─ %1 = Base.power_by_squaring(x, p)
└──      return %1
)

julia> Base.power_by_squaring(2,-1)
ERROR: DomainError with -1:
Cannot raise an integer x to a negative power -1.
Make x or -1 a float by adding a zero decimal (e.g., 2.0^-1 or 2^-1.0 instead of 2^-1), or write 1/x^1, float(x)^-1, x^float(-1) or (x//1)^-1
Stacktrace:
 [1] throw_domerr_powbysq(::Int64, ::Int64) at .\intfuncs.jl:193
 [2] power_by_squaring(::Int64, ::Int64) at .\intfuncs.jl:214
 [3] top-level scope at REPL[42]:1

julia> Base.power_by_squaring(2,8)
256

This error message is also a bit strange:

julia> Base.power_by_squaring(2.0,-1)
ERROR: DomainError with -1:
Cannot raise an integer x to a negative power -1.
Convert input to float.
Stacktrace:
 [1] throw_domerr_powbysq(::Float64, ::Int64) at .\intfuncs.jl:190
 [2] power_by_squaring(::Float64, ::Int64) at .\intfuncs.jl:214
 [3] top-level scope at REPL[50]:1

This was already discussed here, for example. The TLDR is, that the Julia parser special-cases literal integer exponents to call Base.literal_pow, which makes it possible to return a floating point value for negative powers without any type instabilities. If this were the case for non-literal integer powers as well, you’d either always have to return a floating point result, which is awkward, if you just want to work with integers, or introduce type instabilities, which would make ^ for integers significantly slower as a whole.

5 Likes