Error while indexing an array

I’m trying to code the next equation:

Here,

  1. S is an array of size (n,n)
  2. A is an array of size n
  3. H is an array of size (n,n)
  4. T is an array of size n
  5. Ť is an array of size n with the cumulative sum of T (Tc in the code)

So far my code is:

for i in 1:n
    for i_ in 1:n
        if H[i, i_] <= Tc[1]
            S[i, i_] = A[1] * cos(2π * H[i, i_] / T[1]) - A[1]

        elseif Tc[i_-1] < H[i, i_] <= Tc[i_]
            S[i, i_] = A[i_] * cos(2π * H[i, i_] / T[i_]) - A[i_]
            
        elseif H[i, i_] > Tc[i_-1]
            S[i, i_] = A[n] * cos(2π * H[i, i_] / T[n]) - A[n]
        end
    end
end

The code gives the next error:

BoundsError: attempt to access n-element Vector{Float64} at index [0]

I tried it in Python but I guess it worked there because you can index with negative integers, which leads me to think that the problem is my approach.

This should be Tc[n-1] according to your definition.

Also, this throws an error (due to Tc[i-1]) whn i=1:

1 Like

Stylistic considerations unrelated to the error:

  1. Avoid code duplication by putting the assignment outside the if, like S[i, i_] = ifH[i, i_] <= Tc[1]
  2. Use cospi(2*x) instead of cos(2π), especially if the element type is not necessarily Float64.
  3. Maybe assign H[i, i_] to a variable, and use it to avoid code duplication
  4. Maybe do for i in 1:n, j in 1:n instead of the two nested fors
2 Likes

Yes, you are right, it should be Tc[n-1].

And yes, that’s why I asked the question, because each value of H has to be evaluated in an interval of Tc[i-1] - Tc[i]. But when i=1 the index will be 0 resulting in an error.

Thank you very much! I appreciate the stylistic suggestions, I have already implemented them :smile:

1 Like

Note that Julia identifiers are Unicode strings, so you could just use Ť instead of Tc, if you think that suits you better.

As far as I understand, your problem is that you want zero-based indexing, instead of the one-based indexing that’s used by default? While Julia’s Arrays (including Matrix and Vector) use one-based indexing, there’s a few approaches to changing the indexing base:

While the i in arr[i] is one-based when arr isa Array, the i in arr[begin + i] effectively shifts the indexing base to zero, because the begin evaluates firstindex(arr) (when used in an indexing expression). If writing begin + ... many times is too unwieldy, just create a helper function. For example:

get = (v, i) -> v[begin + i]
set! = (v, i, n) -> v[begin + i] = n
a = [10, 20]
set!(a, 0, get(a, 1))

It’s even possible to overload binary operators for this purpose, if you fancy that.

Alternatively, you could use another AbstractArray type, such as those provided by the OffsetArrays package, enabling you to explicitly choose an indexing base when constructing the array.

I do not think OP is interested in zero-based indexing.

This is not a coding question though. Based on the definition you provided in the first post, \hat{T}_i seems to exist for i=1, \ldots, n. Hence, the (second) condition \hat{T}_{i-1} < H \leq \hat{T}_i needs to be adjusted for i=1 because there is no \hat{T}_0. So you need to decide how the condition reads for i=1.

For example, one option would be to only check H \leq \hat{T}_i when i=1. We can turn that easily into code:

elseif (i_ == 1 || Tc[i_-1] < H[i, i_]) && (H[i, i_] <= Tc[i_])