# Does Cartesian Indexing work on single values?

My goal is to create a function to check if my data points are valid, i.e., not an NaN and not equal to -999.

Here is the function I wrote:
`f(A) = [idx for idx in CartesianIndices(A) if @inbounds (!isnan(A[idx]) && A[idx] != -999)];`

Why does it work on vector data like N1 but not on single values like N2?

``````N1 = [3.7, 4.5];
N2 = 3.7;
``````

How do I make it work for single values as well?

Thanks!

There’s no sensible way to assign a Cartesian index to a floating-point value, so Julia doesn’t implement the associated method:

``````julia> CartesianIndices(3.7)
ERROR: MethodError: no method matching CartesianIndices(::Float64)
Closest candidates are:
CartesianIndices(::CartesianIndex) at C:\Users\alexa\.julia\juliaup\julia-1.7.1+0~x64\share\julia\base\multidimensional.jl:276
CartesianIndices(::AbstractArray) at C:\Users\alexa\.julia\juliaup\julia-1.7.1+0~x64\share\julia\base\multidimensional.jl:280
CartesianIndices(::Tuple{}) at C:\Users\alexa\.julia\juliaup\julia-1.7.1+0~x64\share\julia\base\multidimensional.jl:270
...
Stacktrace:
 top-level scope
@ REPL:1
``````

You probably want to use the built-in function `findall` instead:

``````julia> f(A) = findall(A) do Aᵢ
!isnan(Aᵢ) && Aᵢ != -999
end
f (generic function with 1 method)

julia> f([3.7, 4.5])
2-element Vector{Int64}:
1
2

julia> f(3.7)
1-element Vector{Int64}:
1
``````
2 Likes

That’s so bad. Cartesian index is one of the fastest ways to process large amounts of data.

You probably want `eachindex` here anyway instead of `CartesianIndices`?

``````julia> f(A) = [idx for idx in eachindex(A) if @inbounds (!isnan(A[idx]) && A[idx] != -999)]
f (generic function with 1 method)

julia> N1 = [3.7, 4.5];

julia> N2 = 3.7;

julia> f(N1)
2-element Vector{Int64}:
1
2

julia> f(N2)
1-element Vector{Int64}:
1
``````

Or do you require the Cartesian indices in particular?

2 Likes

I just realize that it does not work either. Here is why:

``````YES(A) = [idx for idx in eachindex(A) if @inbounds (!isnan(A[idx]) && A[idx] != -999)];
N2 = 3.7
Ind = YES(N2)
``````

`N2[Ind]` will give me the below error:

``````ERROR: MethodError: no method matching getindex(::Float64, ::Vector{Int64})
Closest candidates are:
getindex(::Number) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/number.jl:95
getindex(::Union{AbstractChar, Number}, ::CartesianIndex{0}) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/multidimensional.jl:831
getindex(::Number, ::Integer) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/number.jl:96
...
Stacktrace:
 top-level scope
``````

This seems to be a Julia bug to me. I mean, no indexing system should fail only because the vector is reduced down to just 1 value.

`N2[Ind...]` to get a scalar index, or encapsulate the scalar in a container: `[N2][Ind]`

1 Like

Do I have to write a loop so that my program will treat a scalar differently from a vector? It seems Julia wants to make something really simple really complex.

This thread is a bit odd, your scalars should probably be 1-element vectors for type stability, and then CartesianIndex would work too.

2 Likes

Thanks! The values are generated out of an external program.

Is there a universal function to convert either a scalar, or a 1-column data, or a vector to a vector?

I tried `vec()`, and it does not work for scalars.

`[x;]` works for both vectors and scalars.

1 Like

Excellent! Many thanks

Sure there is. Julia treats numbers (and characters) as 0-dimensional arrays:

``````julia> x = 3.7
3.7

julia> x[]
3.7

julia> x[CartesianIndex()]
3.7
``````

so it would make sense to have something like:

``````CartesianIndices(::Union{Number,AbstractChar}) = CartesianIndex():CartesianIndex()
``````
3 Likes

This gets a bit unintuitive with Julia’s multidimensional `getindex` behavior:

``````julia> 1[]
1

julia> 1[CartesianIndex()]
1

julia> 1[1, 1]
1

julia> 1[CartesianIndex(1, 1)]
ERROR: MethodError: no method matching getindex(::Int64, ::CartesianIndex{2})
[...]
``````
1 Like

That seems like a separate issue — a missing `getindex` method (for consistency…I’m not sure how useful it is).

Julia has treated numbers as 0-dimensional arrays for years now and we long ago decided to keep it (make numbers non-iterable? · Issue #7903 · JuliaLang/julia · GitHub), so it seems like `CartesianIndices` should be consistent with that…

3 Likes