Alternatively, you can declare the function as:
function toeplitz(x::AbstractVector{T}) where T
Note that by using AbstractVector
you accept any type of 1d array, not just the built-in Vector{T} = Array{T,1}
.
(You could also just declare it as function toeplitz(x)
and use eltype
. There is no performance advantage to declaring the argument type here, but AbstractVector
is probably useful to communicate the intent and to give clearer errors.)
However, you also have another problem: A[i,:] = x[1:n - i + 1]
will give an error because the right-hand side has only n-i+1
elements whereas the left-hand side expects n
elements. Probably the simplest thing here is to just write out the loop:
for i = 1:n, j = 1:n-i+1
A[i,j] = x[j]
end
which has the added benefit of eliminating the x[1:n - i + 1]
temporary array (or view object if you added a @views
decorator).
However, this is still not a Toeplitz matrix according to the usual definition. The usual definition would correspond to
for i = 1:n
for j = 1:n-i+1
A[i,i+j-1] = x[j]
end
# delete this second loop if you want zeros under the diagonal
# rather than a circulant matrix:
for j = n-i+2:n
A[i, j-(n-i+1)] = x[j]
end
end
Finally, you need return A
at the end in order to return the array. You then get e.g.
julia> function toeplitz(x::AbstractVector{T}) where T
n = length(x)
A = zeros(T, n, n)
for i = 1:n
for j = 1:n-i+1
A[i,i+j-1] = x[j]
end
for j = n-i+2:n
A[i, j-(n-i+1)] = x[j]
end
end
return A
end
julia> toeplitz(1:10)
10×10 Array{Int64,2}:
1 2 3 4 5 6 7 8 9 10
10 1 2 3 4 5 6 7 8 9
9 10 1 2 3 4 5 6 7 8
8 9 10 1 2 3 4 5 6 7
7 8 9 10 1 2 3 4 5 6
6 7 8 9 10 1 2 3 4 5
5 6 7 8 9 10 1 2 3 4
4 5 6 7 8 9 10 1 2 3
3 4 5 6 7 8 9 10 1 2
2 3 4 5 6 7 8 9 10 1
which I think is what you want?