# Change a vector CartesianIndex

**URL:** https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506
**Category:** General Usage
**Tags:** cartesianindices
**Created:** [February 12, 2023, 10:48am UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506 "2023-02-12T10:48:11Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Zerosum](https://avatars.discourse-cdn.com/v4/letter/z/b2d939/32.png) [@Zerosum](https://discourse.julialang.org/u/Zerosum)
#### Post date: [February 12, 2023, 10:48am UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/1 "2023-02-12T10:48:11Z")

</div>

I was wondering if I could get help with this problem.  
I have a matrix and find every index where its value is negative.

```julia
mat = [1 2 3 ; -1 -2 3]

ind = findall(<(0),mat)

2-element Vector{CartesianIndex{2}}:
 CartesianIndex(2, 1)
 CartesianIndex(2, 2)

```

Something I want to do is to change the row before each CartesianIndex; CartesianIndex(1,1), CartesianIndex(1,2). I tried to following

```julia
function ind_ready(;ind = ind)
        
    A = hcat(getindex.(ind,1),getindex.(ind,2))
    A[:,1] = A[:,1] .- 1   
    B = Any[]
    C = CartesianIndex[] 

    for i in 1:length(ind) 
        B = push!(B,(A[i,1],A[i,2]))
    end

    for i in 1:length(B) 
        C = push!(C,CartesianIndex(B[i]))
    end

    return C

end

```

Then I get the following

```julia
2-element Vector{CartesianIndex}:
 CartesianIndex(1, 1)
 CartesianIndex(1, 2)

```

However, with this

```julia
mat[ind_ready()]

```

returns the following error

```julia
ArgumentError: unable to check bounds for indices of type CartesianIndex{2}

```

How can I fix this problem?

Any suggestion would be greatly helpful.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 12, 2023, 12:58pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/2 "2023-02-12T12:58:31Z")

</div>

> [@Zerosum](#):
>
> Something I want to do is to change the row before each CartesianIndex; CartesianIndex(1,1), CartesianIndex(1,2). I tried to following

```julia
ind .= CartesianIndex.(getindex.(ind, 1) .- 1, getindex.(ind, 2))

```

or equivalently

```julia
@. ind = CartesianIndex(getindex(ind, 1) - 1, getindex(ind, 2))

```

which gives

```julia
julia> mat[ind]
2-element Vector{Int64}:
 1
 2

```

> [@Zerosum](#):
>
> However, with this `mat[ind_ready()]` returns the following error `ArgumentError: unable to check bounds`

Two problems: your `ind_ready()` function actually decrements the second index (with `A[:,2] = A[:,2] .- 1 `), not the first, resulting in invalid `0` indices:

```julia
julia> i2 = ind_ready()
2-element Vector{CartesianIndex}:
 CartesianIndex(2, 0)
 CartesianIndex(2, 1)

```

Second, Julia doesn’t like that your `ind_ready` returns an abstractly typed `CartesianIndex[]` vector and not a concretely typed `CartesianIndex{2}[]` vector:

```julia
julia> mat[CartesianIndex[CartesianIndex(1,1)]]
ERROR: ArgumentError: unable to check bounds for indices of type CartesianIndex{2}

julia> mat[CartesianIndex{2}[CartesianIndex(1,1)]]
1-element Vector{Int64}:
 1

```

But this error message is confusing and should be fixed: [confusing error for array[CartesianIndex[...]] indexing · Issue #48655 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/48655)

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [February 12, 2023, 1:10pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/3 "2023-02-12T13:10:05Z")

</div>

You could simply do:

```julia
ind .-= Ref(CartesianIndex(1,0))
mat[ind]

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 12, 2023, 1:12pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/4 "2023-02-12T13:12:52Z")

</div>

> [@rafael.guerra](#):
>
> `ci = ind .- Ref(CartesianIndex(1,0))`

Oh, right, I forgot that `CartesianIndex` supports vector operations (± and multiplication by scalars).

---

<div class="post-metadata">

### Author: ![Zerosum](https://avatars.discourse-cdn.com/v4/letter/z/b2d939/32.png) [@Zerosum](https://discourse.julialang.org/u/Zerosum)
#### Post date: [February 13, 2023, 9:21am UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/5 "2023-02-13T09:21:05Z")

</div>

Thank you very much!

I figured out that my example has the problem you mentioned, so I changed the example to a row. I’ll edit the code in the question accordingly.

I was just wondering one more thing. Is there a way that I can put conditions? I want to reduce by one if the cartesian index is bigger than one?

---

<div class="post-metadata">

### Author: ![Zerosum](https://avatars.discourse-cdn.com/v4/letter/z/b2d939/32.png) [@Zerosum](https://discourse.julialang.org/u/Zerosum)
#### Post date: [February 13, 2023, 9:22am UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/6 "2023-02-13T09:22:03Z")

</div>

Thank you so much. Now I can cut my messy codes into half 🙂

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 13, 2023, 1:30pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/7 "2023-02-13T13:30:02Z")

</div>

> [@Zerosum](#):
>
> I was just wondering one more thing. Is there a way that I can put conditions? I want to reduce by one if the cartesian index is bigger than one?

Yes, of course. One solution would be to include a call to `max` (or `ifelse` or similar):

```julia
ind .= CartesianIndex.(max.(1, getindex.(ind, 1) .- 1), getindex.(ind, 2))

```

but when things become sufficiently complicated at some point it becomes clearer to write an “scalar” expression that does what you want, and either broadcast it or use a comprehension or `map`. For example, one of:

```julia
newind = map!(ind) do c
    CartesianIndex(max(1, c[1]), c[2])
end

map!(ind, ind) do c
    CartesianIndex(max(1, c[1]), c[2])
end

newind = [CartesianIndex(max(1, c[1]), c[2]) for c in ind]

f(c) = CartesianIndex(max(1, c[1]), c[2])
ind .= f.(c)

ind .= (c -> CartesianIndex(max(1, c[1]), c[2])).(ind)

```

and of course once you write it like this you can use `if` statements or whatever you want to transform `c`.

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [February 13, 2023, 2:00pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/8 "2023-02-13T14:00:16Z")

</div>

If your need is to handle cases where some negative value is in the first row, you could make use of a variant of @rafael.guerra solution

```julia

mat3 = [-2 -3 4; 1 2 3 ; -1 -2 3]

ind3 = findall(<(0),mat3)

ind3 .-= Ref(CartesianIndex(1,0))

nind=[i - CartesianIndex(1,0) for i in ind3 if i.I[1] > 1]

```

---

<div class="post-metadata">

### Author: ![Zerosum](https://avatars.discourse-cdn.com/v4/letter/z/b2d939/32.png) [@Zerosum](https://discourse.julialang.org/u/Zerosum)
#### Post date: [February 13, 2023, 6:53pm UTC](https://discourse.julialang.org/t/change-a-vector-cartesianindex/94506/9 "2023-02-13T18:53:07Z")

</div>

I thank all of you so much !
