Ve

Vetores em Julia

1 exercício

Sobre Vetores

Um dos objetivos centrais de Julia é conseguir fazer cálculos com dados numéricos de forma rápida e eficiente. Muitos dados numéricos.

Normalmente, os dados ficam armazenados em arrays (ou em algum tipo relacionado), então dá para dizer que os arrays estão no coração da linguagem Julia.

Arrays podem ter tamanho arbitrário (limitados apenas pela memória disponível no seu hardware) e podem ter quantas dimensões você quiser.

Alguns tipos de array têm nomes especiais (copiados da Álgebra Linear). Um array unidimensional é chamado de Vector e um array bidimensional é chamado de Matrix. Os dois são subtipos de Array em Julia.

Este Conceito introdutório concentra-se no básico dos vetores. Arrays de dimensões maiores serão abordados mais adiante no programa de estudos.

Criando vetores

Em Julia, um vetor é uma sequência ordenada de valores que podem ser acessados por um número de índice.

A forma mais simples de criar um vetor é listar os valores entre colchetes:

julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
 1
 4
 9

julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
 "arrays"
 "are"
 "important"

O tipo do vetor corresponde ao tipo de cada elemento.

Tecnicamente, é um vetor coluna, mas ignore isso por enquanto se você não conhece Álgebra Linear. Isso vai fazer mais sentido depois do conceito de Arrays Multidimensionais.

Então vetores precisam ser homogêneos (todos os elementos do mesmo tipo)?

De certo modo, sim, e é recomendável buscar isso se você quiser o melhor desempenho. No entanto, Julia consegue contornar essa limitação (quando necessário) usando o tipo Any:

julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
 1
  "str"
  'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)

Ao criar um vetor vazio, Julia usa o tipo de elemento Any por padrão, mas dá para definir algo mais específico anotando o array vazio com o tipo de elemento desejado.

julia> empty_vec = []
Any[]

julia> empty_int_vec = Int64[]
Int64[]

Vetores pré-preenchidos

É muito comum começar com vetores só de 0 ou só de 1. Para isso, existem funções chamadas (sem surpresa) zeros() e ones(), que recebem o tamanho do vetor como parâmetro. O tipo padrão é Float64, mas dá para especificar outros tipos numéricos, se quiser.

De forma parecida, a função fill() recebe tanto um valor a repetir quanto o tamanho desejado do vetor.

julia> zeros(3)
3-element Vector{Float64}:
 0.0
 0.0
 0.0

julia> ones(3)
3-element Vector{Float64}:
 1.0
 1.0
 1.0

julia> ones(Int64, 3)
3-element Vector{Int64}:
 1
 1
 1

julia> fill(42, 3)
3-element Vector{Int64}:
 42
 42
 42

Existem muitas outras opções: consulte o manual.

Leia e lembre-se desta regra:

  • Por padrão, a indexação em Julia começa em 1, não em 0.

Isso é familiar para quem já usou outras linguagens de ciência de dados (R, Matlab, Fortran...), mas pode parecer chocante para quem vem de linguagens parecidas com C.

Fora isso, os índices funcionam como você imagina: é só colocá-los entre colchetes:

squares = [0, 1, 4, 9, 16]
squares[1]  # 0
squares[3]  # 4
squares[begin]  # 0 ("begin" is synonym for 1)
squares[end]  # 16 ("end" is synonym for length(squares))

Repare na conveniência de indexar com end (que é muito útil) e begin (que provavelmente não é).

Quem programa em Python pode estar se perguntando sobre índices negativos. Pode esquecer: eles não fazem parte de Julia e vão gerar um BoundsError, assim como qualquer índice menor que 1 ou maior que length(squares).

Operações com vetores

Os vetores em Julia são mutáveis: dá para mudar o conteúdo de posições individuais.

julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
 1
 3
 5
 7

julia> vals[2] = 4  # reassign the value of this element
4

# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
 1
 4
 5
 7

Existem muitas funções disponíveis para manipular vetores, embora a documentação de Julia as generalize para "coleções" em vez de vetores.

Repare que, por convenção, funções que modificam sua entrada têm um ! no nome. O compilador não vai exigir isso, mas é uma convenção muito forte no mundo Julia.

Estas são algumas das funções úteis:

  • Para adicionar valores ao final do vetor, use push!().
  • Para remover o último valor, use pop!().
  • Para operar no início do vetor, as funções correspondentes são pushfirst!() e popfirst!().
  • Para inserir ou remover um elemento em qualquer posição, existem insert!() e deleteat!().
julia> vals = [1, 3]
2-element Vector{Int64}:
 1
 3

julia> push!(vals, 5, 6)  # can add multiple values
4-element Vector{Int64}:
 1
 3
 5
 6

julia> pop!(vals)  # mutates vals, return popped value
6

julia> vals
3-element Vector{Int64}:
 1
 3
 5

Concatenação

A concatenação é bem simples no caso dos vetores, mas uma olhada no manual já avisa das complexidades que vêm pela frente quando consideramos arrays multidimensionais.

A função append!() pode receber como entrada uma mistura de vários vetores e elementos isolados.

julia> append!([1, 2], [3, 4], [-1, -2], 15)
7-element Vector{Int64}:
  1
  2
  3
  4
 -1
 -2
 15
Editar via GitHub O link abre em uma nova janela ou aba

Aprenda Vetores