[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8 Vetores e Matrizes

As funções descritas nesse capítulo fornecem uma interface simples de vetor e matriz para vetores estáticos comuns da linguagem C. O gerenciamento de memória desses vetores estáticos está implementada usando tipo básico simples, conhecido como um bloco. Escrevendo suas funções em termos de vetores e matrizes você pode informar uma estrutura simples contendo ambos os arguentos dados e dimensões sem precisar parâmetros adicionais de funções. As estruturas são compatíveis com formatos de vetor e matriz usados pelas rotinas BLAS.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.1 Tipos de dados

Todas as funções estão disponíveis para cada um dos tipos de dado disponíveis. As versões para double possuem o prefixo gsl_block, gsl_vector e gsl_matrix. Similarmente as versões para vetores estáticos de precisão simples float possuem o prefixo gsl_block_float, gsl_vector_float e gsl_matrix_float. A lista completa de tipos disponiveis é fornecida abaixo,

gsl_block                       double         
gsl_block_float                 float         
gsl_block_long_double           long double   
gsl_block_int                   int           
gsl_block_uint                  unsigned int  
gsl_block_long                  long          
gsl_block_ulong                 unsigned long 
gsl_block_short                 short         
gsl_block_ushort                unsigned short
gsl_block_char                  char          
gsl_block_uchar                 unsigned char 
gsl_block_complex               complex double        
gsl_block_complex_float         complex float         
gsl_block_complex_long_double   complex long double   

Tipos correspondentes existem para as funções gsl_vector e gsl_matrix.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.2 Blocos

Por consistência toda a memória é alocada através de uma estrutura gsl_block. A estrutura contém dois componentes, o tamanho de uma área de memória e um apontador para a memória. A estrutura gsl_block parece-se com o seguinte,

typedef struct
{
  size_t size;
  double * data;
} gsl_block;

Vetores e matrizes são feitos através do particionameto de um bloco básico. Uma parte é um conjunto de elementos formados a partir de um deslocamento inicial e uma combinação de índices e tamanhos de passo. No caso de uma matriz o tamanho de passo para o índice da coluna representa a quantidade de elementos da linha. O tamanho de passo para um vetor é conhecido como o stride.

As funções para alocação e desalocação de blocos são definidas em ‘gsl_block.h


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.2.1 Bloco - alocação

As funções para alocação de memória para um bloco seguem o estilo de malloc e free. Adicionalmente elas também executam sua própria verificação de erro. Se não existe memória suficiente para alocar um bloco então as funções chamam o controlador de erro da GSL (com um número de erro correspondente a GSL_ENOMEM) além de retornar um apontador nulo. Dessa forma se você usa o controlador de erros da biblioteca para abortar seu programa não é necessário verificar cada alloc.

Function: gsl_block * gsl_block_alloc (size_t n)

Essa função aloca memória para um bloco de n elementos de precisão dupla, retornando um apontador para a estrutura do bloco. O bloco não é inicializado e dessa forma os valores de seus elementos são indefinidos. Use a função gsl_block_calloc se você deseja garantir que todos os elementos sejam inicializados com o valor zero.

Um apontador nulo é retornado se não tiver memória suficiente para criar o bloco.

Function: gsl_block * gsl_block_calloc (size_t n)

Essa função aloca memória para um blco e inicializa todos os elementos do bloco com o valor zero.

Function: void gsl_block_free (gsl_block * b)

Essa função libera a memória usada por um bloco b previamente alocada com gsl_block_alloc ou com gsl_block_calloc.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.2.2 Blocos - Lendo e Escrevendo

A biblioteca fornece funções para leitura e escrita de blocos para um arquivo como dados binários ou como texto formatado.

Function: int gsl_block_fwrite (FILE * stream, const gsl_block * b)

Essa função escreve os elementos do bloco b para o fluxo stream em formato binário. O valor de retorno é 0 para sucesso e GSL_EFAILED se houve um problema de escrita para o arquivo. Uma vez que os dados estejam escritos no formao binário nativo esses mesmos dados podem não serem portáveis entre diferentes arquiteturas.

Function: int gsl_block_fread (FILE * stream, gsl_block * b)

Essa função lê um bloco b a partir de um fluxo aberto stream no formato binário. O bloco b deve ser pré-alocado com o comprimento correto uma vez que a função usa o tamanho de b para determinar quantos bytes ler. O valor de retornado é 0 em caso de sucesso e GSL_EFAILED caso haja um problema ao ler a partir do arquivo. Os dados são assumidos terem sido escritos no formato binários nativo sobre a mesma arquitetura.

Function: int gsl_block_fprintf (FILE * stream, const gsl_block * b, const char * format)

Essa função escreve os elementos do bloco b uma linha de cada vez para o fluxo stream usando o especificados de formato format, o qual deve ser um entre os formatos %g, %e ou %f para números em ponto flutuante e %d para inteiros. A função retorna 0 em caso de sucesso e GSL_EFAILED se ocorrer um problema ao escrever para o arquivo.

Function: int gsl_block_fscanf (FILE * stream, gsl_block * b)

Essa função lê dados formatados a partir do fluxo stream para o bloco b. O bloco b deve ser pré-alocado com o comprimento correto uma vez que a função usa o tamanho de b para determinar quantos números devem ser lidos. A função retorna 0 em caso de sucesso e GSL_EFAILED se existir um problema ao fazer a leitura a partir do arquivo.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.2.3 Blocos - exemplos

O seguinte programa mostra como alocar um bloco,

#include <stdio.h>
#include <gsl/gsl_block.h>

int
main (void)
{
  gsl_block * b = gsl_block_alloc (100);
  
  printf ("length of block = %u\n", b->size);
  printf ("block data address = %#x\n", b->data);

  gsl_block_free (b);
  return 0;
}

Aqui está a saída do programa,

length of block = 100
block data address = 0x804b0d8

[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3 Vetores

Vetores são definidos através de uma estrutura gsl_vector que descreve uma parte de um bloco. Diferentes vetores podem ser criados apontando para o mesmo bloco. Uma parte de vetor é um conjunto de elementos igualmente espaçados de uma área de memória.

A esrutura gsl_vector contém cinco partes, o size, o stride, um apontador para a memória onde os elementos são armazenados, data, um apontador para o bloco possuído pelo vetor, block, se houver algum, e um sinalizador de propriedade, owner. A estrutura é muito simples e parece-se com isso,

typedef struct
{
  size_t size;
  size_t stride;
  double * data;
  gsl_block * block;
  int owner;
} gsl_vector;

O size é simplesmente o número de elementos do vetor. O intervalo de índices válidos vai de 0 a size-1. O stride é o tamanho de passo de um elemento para o seguinte em memória física, medido em unidades de tipos de dado apropriados. O apontador data fornece a localização do primeiro elemento do vetor na memória. O apontador block armazena a localização do bloco de memória no qual os elementos do vetor estão localizados (se houver algum). Se o vetor possui esse bloco então o campo owner é ajustado para um e o bloco irá ser desalocando quando o vetor for liberado. Se o vetor aponta para um bloco possuído por outro objeto então o campo owner é zero e qualquer bloco subordinado não irá ser desalocado com o vetor.

As funções para alocar e acessar vetores estão definidas em ‘gsl_vector.h


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.1 Vetor - Alocação

As funções para alocar memória a um vetor seguem o estilo de malloc e free. Adicionalmente elas também executam sua própria verificação de erro. Se não houver memória suficiente disponível para alocar um vetor então as funções chamam o controlador de erro da GSL (com um número de erro de GSL_ENOMEM) adicionalmente ao retorno de um apontador nulo. Dessa forma se você usa o conrolador de erro da biblioteca para abortar seu programa então não é necessário verificar cada alloc.

Function: gsl_vector * gsl_vector_alloc (size_t n)

Essa função cria um vetor de n componentes, retornando um apontador para uma recentemente inicializada estrutura de vetor. Um novo bloco é alocado para os elementos do vetor, e armazenado na componente block da estrutura do vetor. O bloco é “possuído” pelo vetor, e irá ser desalocado quando o vetor for desalocado.

Function: gsl_vector * gsl_vector_calloc (size_t n)

Essa função aloca memória para um vetor de n componentes e inicializa todos os elementos do vetor com o valor zero.

Function: void gsl_vector_free (gsl_vector * v)

Essa função libera um vetor v previamente alocado. Se o vetor tiver sido criado usando gsl_vector_alloc então o bloco subordinado ao vetor irá também ser desalocado. Se o vetor tiver sido criado a partir de outro objeto então a memória é ainda possuída por aquele objeto e não irá ser desalocada.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.2 Acessando elementos de vetor

Diferente dos compiladores FORTRAN, os compiladores de C não fornece usualmente suporte a verificação de intervalo de vetores e matrizes.(21) As funções gsl_vector_get e gsl_vector_set podem executar verificação de intervalo de uma forma portável para você e informar um erro se você tenta acessar elementos fora do intervalo permitido.

As funçoes para acessar os elementos de um vetor ou matriz são definidas em ‘gsl_vector.h’ e declarados extern inline para eliminar sobrecarga de chamadas a funções. Você deve compilar seu programa com a macro ao pré-processador HAVE_INLINE definida para usar essas funções.

Se necessário você pode desligar a verificação de intervalo completamente sem modificar qualquer arquivo fonte por meio da recompilação de seu programa com a diretiva ao pré-processador GSL_RANGE_CHECK_OFF. Na condição de seu compilador ter suporte a funções inline o efeito de desabilitar a verificação de intervalo é substituir chamadas a gsl_vector_get(v,i) por v->data[i*v->stride] e chamadas a gsl_vector_set(v,i,x) por v->data[i*v->stride]=x. Dessa forma não deve ocorrer perda de performace pelo uso de funções de verifificação de intervalo quando as mesmas estiverem desabilitadas.

Se você usa um compilador C99 que requer que funções inline em arquivos de cabeçalho sejam declaradas inline ao invés de extern inline, defina a macro GSL_C99_INLINE (veja seção Funções Inline). Com o GCC isso é selecionado automaticamente quando compilando no modo C99 (-std=c99).

Se funções inline não forem usadas, chamadas às funções gsl_vector_get e gsl_vector_set irão ser ligadas a versões compiladas dessas funções na biblioteca propriamente dita. A verificação de intervalo nessas funções é controlado através da variável inteira global gsl_check_range. A gsl_check_range é habilitada por padrão—para desabilitá-la, ajuste gsl_check_range para zero. Devido a sobrecarga de chamada-função, existe menos benefício em desabilitar verificação de intervalo aqui que desabilitar funções inline.

Function: double gsl_vector_get (const gsl_vector * v, size_t i)

Essa função retorna o i-ésimo elemento de um vetor v. Se i cair forma do intervalo permitido de 0 a n-1 então o controlador de erro é chamado e 0 é retornado. Uma versão modificada dessa função é usada quando HAVE_INLINE for definida.

Function: void gsl_vector_set (gsl_vector * v, size_t i, double x)

Essa função ajusta o valor do i-ésimo elemento de um vetor v para x. Se i cair forma do intervalo permitido de 0 a n-1 então o controlador de erro é chamado. Uma versão modificada dessa função é usada quando HAVE_INLINE for definida.

Function: double * gsl_vector_ptr (gsl_vector * v, size_t i)
Function: const double * gsl_vector_const_ptr (const gsl_vector * v, size_t i)

Essas funções retornam um apontador para o i-ésimo elemanto de um vetor v. Se i cair fora do intervalo permitido de 0 a n-1 então o controlador de erro é chamado e um apontador nulo é retornado. Versões modificadas dessa função são usada quando HAVE_INLINE for definida.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.3 Elementos de vetor - Inicializando

Function: void gsl_vector_set_all (gsl_vector * v, double x)

Essa função ajusta todos os elementos de um vetor v para o valor x.

Function: void gsl_vector_set_zero (gsl_vector * v)

Essa função ajusta todos os elementos de um vetor v para zero.

Function: int gsl_vector_set_basis (gsl_vector * v, size_t i)

Essa função cria um vetor base através do ajuste de todos os elementos do vetor v para zero exceto para o i-ésimo elemento o qual é ajustado para a unidade.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.4 Vetores - Lendo e Escrevendo

A biblioteca fornece funções para ler e escrever vetores para um arquivo como dados binários ou texto formatado.

Function: int gsl_vector_fwrite (FILE * stream, const gsl_vector * v)

Essa função escreve os elementos do vetor v para o fluxo stream em formato binário. O valor de retorno é 0 em caso de sucesso e GSL_EFAILED se ouver um problema de escrita para o arquivo. Uma vez que os dados são escritos no formato binário nativo esses mesmos dados podem não ser portáveis entre diferentes arquiteturas.

Function: int gsl_vector_fread (FILE * stream, gsl_vector * v)

Essa função lê o vetor v a partir de um fluxo aberto stream em formato binário (22). O vetor v deve ser previamente disponibilizado com o comprimemto correto uma vez que a função utiliza o tamanho de v para determinar quantos bytes devem ser lidos. O valor de retorno é 0 em caso de sucesso e GSL_EFAILED se houver um problema de leitura do arquivo. Os dados são assumidos terem sido escritos no formato binário nativo na arquitetura em que a função gsl_vector_fread está sendo executada.

Function: int gsl_vector_fprintf (FILE * stream, const gsl_vector * v, const char * format)

Essa função escreve os elementos do vetor v uma linha por vez para o fluxo stream usando o especificador de formato format, o qual deve ser um entre os seguintes formatos %g, %e ou %f para números em ponto flutuante e %d para inteiros. A função retorna 0 em caso de sucesso e GSL_EFAILED se houver um problema de escrita para o arquivo.

Function: int gsl_vector_fscanf (FILE * stream, gsl_vector * v)

Essa função lê dados formatados a partir de um fluxo stream para o vetor v. O vetor v deve ser disponibilizado previamente com o número de componentes correto uma vez que a função utiliza o tamanho de v para determinar quantos números devem ser lidos. A função retorna 0 em caso de sucesso e GSL_EFAILED se houver um problema de leitura do arquivo.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.5 Visualizações de vetores

Adicionalmente à criação de vetores a partir pedaços de blocos também é possível fazer fatias de vetores e criar visualizações de vetores. Por exemplo, um subvetor de outro vetor pode ser descrito com uma visualização, ou duas visualizações podem ser feitas que fornecem acesso aos elementos pares e ímpares de um vetor.

Uma visualização de vetor é um objeto temporário, armazenado na pilha, que pode ser usado para operar sobre um subconjunto de elementos de vetor. Visualizações de vetores podem ser definidos para ambos vetores constantes e vetores variáveis, usando tipos separados que preservam constness (23). Uma visualização de vetor tem o tipo gsl_vector_view uma visualização de vetor constante tem o tipo gsl_vector_const_view. Em ambos os casos os elementos da visualização podem ser acessados como um gsl_vector usando a componente de vetor do objeto de visualização. Um apontador para um vetor do tipo gsl_vector * ou const gsl_vector * pode ser obtido pegando o endereço dessa componente com o operador &.

Ao usar esse apontador é importante garantir que a visualização propriamente dita seja abrangida pelo escopo atual—a maneira mais simples para fazer isso é sempre escrever o apontador como &view.vector, e nunca armazenar esse valor em outra variável.

Function: gsl_vector_view gsl_vector_subvector (gsl_vector * v, size_t offset, size_t n)
Function: gsl_vector_const_view gsl_vector_const_subvector (const gsl_vector * v, size_t offset, size_t n)

Essas funções retornam uma visualização de vetor de um subvetor de outro vetor v. O início do novo vetor é deslocado de offset elementos a partir do início do vetor original. O novo vetor tem n elementos. Matematicamente, o i-ésimo elemento do novo vetor v’ é fornecido por,

v'(i) = v->data[(offset + i)*v->stride]

onde o índice i varia de 0 a n-1.

O apontador data da estrutura do vetor retornado é ajustado para null se os parâmetros combinados (offset,n) sobrescreverem o fim do vetor original.

O novo vetor é somente uma visualização do bloco subordinado ao vetor original, v. O bloco contendo os elementos de v não é possuído pelo novo vetor. Quando a visualização sai do escopo do vetor original v e seu bloco vai continuar existindo. A memória original somente pode ser desalocada liberando o vetor original. Certamente, o vetor original não pode ser desalocado enquanto a visualização estiver ainda sendo usada.

A função gsl_vector_const_subvector é equivalente a gsl_vector_subvector mas pode ser usada em vetores que são declarados const.

Function: gsl_vector_view gsl_vector_subvector_with_stride (gsl_vector * v, size_t offset, size_t stride, size_t n)
Function: gsl_vector_const_view gsl_vector_const_subvector_with_stride (const gsl_vector * v, size_t offset, size_t stride, size_t n)

Essas funções retornam uma visualização de vetor de um subvetor de outro vetor v com um argumento adicional stride. O subvetor é formado da mesma forma que gsl_vector_subvector mas o novo vetor tem n elementos com um tamanho de passo de stride de um elemento para seguinte no vetor original. Matematicamente, o i-ésimo elemento do novo vetor v’ é fornecido por,

v'(i) = v->data[(offset + i*stride)*v->stride]

onde o índice i varia de 0 a n-1.

Note que visualizações de subvetor fornecem acesso direto aos respecitivos elementos do vetor original. Por exemplo, o seguinte código irá colocar zero nos elementos de ordem par do vetor v de n componentes, enquanto os elementos de ordem ímpar ficam intocados,

gsl_vector_view v_even 
  = gsl_vector_subvector_with_stride (v, 0, 2, n/2);
gsl_vector_set_zero (&v_even.vector);

Uma visualização de vetor pode ser informada para qualquer subroutina que recebe um vetor como argumento da mesma forma que receberia de um vetor alocado diretamente, usando &view.vector. Por exemplo, o seguinte código calcula a norma dos elementos ímpares de v usando a rotina BLAS DNRM2,

gsl_vector_view v_odd 
  = gsl_vector_subvector_with_stride (v, 1, 2, n/2);
double r = gsl_blas_dnrm2 (&v_odd.vector);

A função gsl_vector_const_subvector_with_stride é equivalente a gsl_vector_subvector_with_stride mas pode ser usada para vetores que são declarados const.

Function: gsl_vector_view gsl_vector_complex_real (gsl_vector_complex * v)
Function: gsl_vector_const_view gsl_vector_complex_const_real (const gsl_vector_complex * v)

Essas funções retornam uma visualização de vetor das partes reais do vetor complexo v.

A função gsl_vector_complex_const_real é equivalente a gsl_vector_complex_real mas pode ser usada para vetores que são declarados const.

Function: gsl_vector_view gsl_vector_complex_imag (gsl_vector_complex * v)
Function: gsl_vector_const_view gsl_vector_complex_const_imag (const gsl_vector_complex * v)

Essas funções retornam uma visualização de vetor das partes imaginárias do vetor complexo v.

A função gsl_vector_complex_const_imag é equivalente a gsl_vector_complex_imag mas pode ser usada para vetores que são declarados const.

Function: gsl_vector_view gsl_vector_view_array (double * base, size_t n)
Function: gsl_vector_const_view gsl_vector_const_view_array (const double * base, size_t n)

Essas funções retornam uma visualização de vetor de um vetor estático. O início do novo vetor é fornecido através de base e tem n elementos. Matematicamente, o i-ésimo elemento do novo vetor v’ é fornecido por,

v'(i) = base[i]

onde o índice i varia de 0 a n-1.

O vetor estático contendo os elementos de v não é possuído pela nova visualização de vetor. Quando a visualização sai do escopo o vetor estático original irá continuar a existir. A memória original pode somente ser desalocada através da liberação do apontador original base. Certamente, o vetor estático original não deve ser desalocado enquanto a visualização estiver ainda em uso.

A função gsl_vector_const_view_array é equivalente a gsl_vector_view_array mas pode ser usada para vetores estáticos que são declarados const.

Function: gsl_vector_view gsl_vector_view_array_with_stride (double * base, size_t stride, size_t n)
Function: gsl_vector_const_view gsl_vector_const_view_array_with_stride (const double * base, size_t stride, size_t n)

Essas funções retornam uma visualização de vetor de um vetor estático base com um argumento adicional stride. O subvetor é formado da mesma forma que para gsl_vector_view_array mas o novo vetor tem n elementos com um tamanho de passo de stride de um elemento para o seguinte no vetor estático original. Matematicamente, o i-ésimo elemento do novo vetor v’ é fornecido por,

v'(i) = base[i*stride]

onde o índice i varia de 0 a n-1.

Note que a visualização fornece acesso direto aos respectivos elementos do vetor estático original. Uma visualização de vetor pode ser informada para qualquer subroutina que recebe como argumento um vetor da mesma forma que receberia um vetor alocado diretamente, usando &view.vector.

A função gsl_vector_const_view_array_with_stride é equivalente a gsl_vector_view_array_with_stride mas pode ser usada para vetores estáticos que são declarados const.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.6 Copiando Vetores

Operações comuns sobre vetores tais como adição e multiplicação estão disponíveis na parte BLAS da biblioteca (veja seção Suporte a BLAS). Todavia, é útil ter um pequeno número de funções utilitárias que não requerem o código BLAS completo. As seguintes funções se encaixam dentro dessa categoria.

Function: int gsl_vector_memcpy (gsl_vector * dest, const gsl_vector * src)

Essa função copia os elementos do vetor src para o vetor dest. Os dois vetores devem ter o mesmo número de componentes.

Function: int gsl_vector_swap (gsl_vector * v, gsl_vector * w)

Essa função permuta os elementos dos vetores v e w copiando-os de um para o outro. Os dois vetores devem ter o mesmo número de componentes.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.7 Trocando elementos

A seguinte função pode ser usada para intercambiar, ou permutar, os elementos de um vetor.

Function: int gsl_vector_swap_elements (gsl_vector * v, size_t i, size_t j)

Essa função intercambia o i-ésimo e o j-ésimo elementos do vetor v trocando-os de lugar.

Function: int gsl_vector_reverse (gsl_vector * v)

Essa função inverte a ordem dos elementos do vetor v.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.8 Vetor - Operações

Function: int gsl_vector_add (gsl_vector * a, const gsl_vector * b)

Essa função adiciona os elementos do vetor b aos elementos do vetor a. O resultado a_i \leftarrow a_i + b_i é armazenado em a e b permanece inalterado. Os dois vetores devem ter o mesmo número de componentes.

Function: int gsl_vector_sub (gsl_vector * a, const gsl_vector * b)

Essa função subtrai os elementos do vetor b dos elementos do vetor a. O resultado a_i \leftarrow a_i - b_i é armazenado em a e b permanece inalterado. Os dois vetores devem ter o mesmo número de componentes.

Function: int gsl_vector_mul (gsl_vector * a, const gsl_vector * b)

Essa função multiplica os elementos do vetor a pelos elementos do vetor b. O resultado a_i \leftarrow a_i * b_i é armazenado em a e b permanece inalterado. Os dois vetores devem ter o mesmo número de componentes.

Function: int gsl_vector_div (gsl_vector * a, const gsl_vector * b)

Essa função divide os elementos do vetor a pelos elementos do vetor b. O resultado a_i \leftarrow a_i / b_i is stored in a e b permanece inalterado. Os dois vetores devem ter o mesmo número de componentes.

Function: int gsl_vector_scale (gsl_vector * a, const double x)

Essa função multiplica os elementos do vetor a pelo escalar x. O resultado a_i \leftarrow x a_i é armazenado em a.

Function: int gsl_vector_add_constant (gsl_vector * a, const double x)

Essa função adiciona o escalar x a todos os elementos do vetor a. O resultado a_i \leftarrow a_i + x é armazenado em a.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.9 Encontrando o maior e o menor elemento de um vetor

As seguintes operações são somente definidas para vetores reais.

Function: double gsl_vector_max (const gsl_vector * v)

Essa função retorna a maior componente do vetor v.

Function: double gsl_vector_min (const gsl_vector * v)

Essa função retorna a menor componente do vetor v.

Function: void gsl_vector_minmax (const gsl_vector * v, double * min_out, double * max_out)

Essa função retorna a menor componente e a maior componente do vetor v, armazenando-as em min_out e max_out.

Function: size_t gsl_vector_max_index (const gsl_vector * v)

Essa função retorna o índice da maior componente no vetor v. Quando houverem muitos elementos de maior valor repetidos então o menor índice é retornado.

Function: size_t gsl_vector_min_index (const gsl_vector * v)

Essa função retorna o índice da menor componente do vetor v. Quando houverem muito elementos menores repetidos então o menor índice é retornado.

Function: void gsl_vector_minmax_index (const gsl_vector * v, size_t * imin, size_t * imax)

Essa função retorna os índices do menor valor e do maior valor de componente do vetor v, armazenando-os em imin e em imax. Quando houverem muito elementos menores e maiores repetidos então os índices menores são retornados.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.10 Vetor - Propriedades

As seguintes funções são definidas para vetores reais e complexos. Para vetores complexos ambas as partes real e imaginária devem satisfazer as condições.

Function: int gsl_vector_isnull (const gsl_vector * v)
Function: int gsl_vector_ispos (const gsl_vector * v)
Function: int gsl_vector_isneg (const gsl_vector * v)
Function: int gsl_vector_isnonneg (const gsl_vector * v)

Essas funções retornam 1 se todos os elementos do vetor v forem zero, estritamente positivos, estritamente negativo, ou não negativos respectivamente, e 0 de outra forma.

Function: int gsl_vector_equal (const gsl_vector * u, const gsl_vector * v)

Essa função retorna 1 se os vetores u e v forem iguais (comparando os valores elemento a elemento) e 0 de outra forma.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.3.11 Vetores - exemplos

O programa adiante mosta como alocar, inicializar e ler a partir de um vetor usando as funções gsl_vector_alloc, gsl_vector_set e gsl_vector_get.

#include <stdio.h>
#include <gsl/gsl_vector.h>

int
main (void)
{
  int i;
  gsl_vector * v = gsl_vector_alloc (3);
  
  for (i = 0; i < 3; i++)
    {
      gsl_vector_set (v, i, 1.23 + i);
    }
  
  for (i = 0; i < 100; i++) /* OUT OF RANGE ERROR */
    {
      printf ("v_%d = %g\n", i, gsl_vector_get (v, i));
    }

  gsl_vector_free (v);
  return 0;
}

Aqui está a saída do programa. O ciclo final tenta ler fora do intervalo do vetor v, e o erro é capturado pelo código de verificação de intervalo em gsl_vector_get.

$ ./a.out
v_0 = 1.23
v_1 = 2.23
v_2 = 3.23
gsl: vector_source.c:12: ERROR: index out of range
Default GSL error handler invoked.
Aborted (core dumped)

O programa adiante mostra como gravar um vetor em um arquivo.

#include <stdio.h>
#include <gsl/gsl_vector.h>

int
main (void)
{
  int i; 
  gsl_vector * v = gsl_vector_alloc (100);
  
  for (i = 0; i < 100; i++)
    {
      gsl_vector_set (v, i, 1.23 + i);
    }

  {  
     FILE * f = fopen ("test.dat", "w");
     gsl_vector_fprintf (f, v, "%.5g");
     fclose (f);
  }

  gsl_vector_free (v);
  return 0;
}

Após executar esse programa o arquivo ‘test.dat’ deve conter os elementos de v, escritos usando o especificador de formato %.5g. O vetor pode então ser lido de volta usando a função gsl_vector_fscanf (f, v) como segue:

#include <stdio.h>
#include <gsl/gsl_vector.h>

int
main (void)
{
  int i; 
  gsl_vector * v = gsl_vector_alloc (10);

  {  
     FILE * f = fopen ("test.dat", "r");
     gsl_vector_fscanf (f, v);
     fclose (f);
  }

  for (i = 0; i < 10; i++)
    {
      printf ("%g\n", gsl_vector_get(v, i));
    }

  gsl_vector_free (v);
  return 0;
}

[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4 Matrizes

Matrizes são definidas pela estrutura gsl_matrix a qual descreve um pedaço de bloco generalizado. Da mesma forma que um vetor a matriz representa um conjunto de elementos em uma área de memória, mas usa dois índices ao invés de um.

A estrutura gsl_matrix contém seis componentes, as duas dimensões da matriz, uma dimensão física, um apontador para a memória onde os elementos da matriz estão armazenados, data, um apontador para o bloco possuído pela matriz block, se houver algum, e um sinalizador de propriedade, owner. A dimensão física determina a organização da memória e pode diferir da dimensão da matriz para permitir o uso de submatrizes. A estrutura gsl_matrix é muito simples e assemelha-se ao seguinte,

typedef struct
{
  size_t size1;
  size_t size2;
  size_t tda;
  double * data;
  gsl_block * block;
  int owner;
} gsl_matrix;

Matrizes são armazenadas na ordem por linha, significando que cada linha de elementos forma um bloco não fragmentado na memória. Essa é a “ordenação padrão da linguagem C” de vetores estáticos bidimensionais. Note que FORTRAN armazena vetores estáticos em ordem por coluna. O número de linhas é size1. O intervalo de índices válidos de linha varia de 0 a size1-1. Similarmente size2 é o número de colunas. O intervalo de índices de coluna varia de 0 a size2-1. A dimensão física de linha tda, ou dimensão à direita, especifica o tamanho de uma linha da matriz como estabelecido na memória.

Por exemplo, na seguinte matriz size1 é 3, size2 é 4, e tda é 8. A organização da memória física da matriz inicia-se no canto superior esquerdo e continua da esquerda para a direita ao longo de cada linha por sua vez.

00 01 02 03 XX XX XX XX
10 11 12 13 XX XX XX XX
20 21 22 23 XX XX XX XX

Cada localização de memória não usada é representada por “XX”. O apontador data fornece a localização do primeiro elementos da matriz na memória. O apontador block armazena a localização do bloco de memória no qual os elementos da matriz estão localizados (se houver algum). Se a matriz possui esse bloco então o campo owner é ajustado para um e o bloco irá ser desalocado quando a matriz for liberada. Se a matriz for somente um pedaço de um bloco possuído por outro objeto então o campo owner é zero e qualquer bloco subordinado não irá ser liberado.

As funções de alocação e acesso a matrizes são definidas em ‘gsl_matrix.h


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.1 Matrizes - alocação

As funções para alocação de memória para uma matriz seguem o estilo de malloc e free. Elas também executam sua própria verificação de erro. Se não houver memória suficiente disponível para alocar uma matriz então as funções chamam o controlador de erro da GSL (com um número de erro GSL_ENOMEM) em adição ao retorno de um apontador nulo. Dessa forma se você usa o controlador de erro da biblioteca para abotar seu programa então não é necessário verificar cada alloc.

Function: gsl_matrix * gsl_matrix_alloc (size_t n1, size_t n2)

Essa função cria uma matriz de tamanho n1 linhas por n2 colunas, retornando um apontador para uma recentemente inicializada estrutura de matriz. Um novo bloco é alocado para os elementos da matriz, e armazenado na componente block da estrutura da matriz. O bloco é “possuido” pela matriz, e irá ser desalocado quando a matriz for desalocada.

Function: gsl_matrix * gsl_matrix_calloc (size_t n1, size_t n2)

Essa função aloca memória para uma matriz de tamanho n1 linhas por n2 colunas e inicializa todos os elementos da matriz para zero.

Function: void gsl_matrix_free (gsl_matrix * m)

Essa função libera uma matriz m alocada anteriormente. Se a matriz tiver sido criada usando gsl_matrix_alloc então o bloco respectivo da matriz irá também ser desalocado. Se a matriz tiver sido criada a partir de outro objeto então a memória está ainda possuída por aquele objeto e não irá ser desalocada.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.2 Acessando elementos de matriz

As funções para acessar os elementos de uma matriz usam o mesmo sistema de verificação de intervalo usado para vetores. Você pode desabilitar a verificação de intervalo recompilando seu programa com a diretiva ao pré-processador GSL_RANGE_CHECK_OFF.

Os elementos da matriz estão armazenados na “ordem da linguagem C”, onde o segundo índice move-se continuamente através da memória. Mais precisamente, o elemento acessado pela função gsl_matrix_get(m,i,j) e gsl_matrix_set(m,i,j,x) é

m->data[i * m->tda + j]

onde tda é o comprimento físico de linha da matriz.

Function: double gsl_matrix_get (const gsl_matrix * m, size_t i, size_t j)

Essa função retorna o (i,j)-ésimo elemento de uma matriz m. Se i ou j cair fora do intervalo permitido de 0 a n1-1 e de 0 a n2-1 então o controlador de erro é chamado e 0 é retornado. Uma versão modificada dessa função é usada quando HAVE_INLINE for definida.

Function: void gsl_matrix_set (gsl_matrix * m, size_t i, size_t j, double x)

Essa função ajusta o valor do (i,j)-ésimo elemento de uma matriz m para o valor x. Se i ou j cai fora do intervalo permitido de 0 a n1-1 e de 0 a n2-1 então o controlador de erro é chamado. Uma versão modificada dessa função é usada quando HAVE_INLINE for definida.

Function: double * gsl_matrix_ptr (gsl_matrix * m, size_t i, size_t j)
Function: const double * gsl_matrix_const_ptr (const gsl_matrix * m, size_t i, size_t j)

Essas funções retornam um apontador para o (i,j)-ésimo elemento de uma matriz m. Se i ou j cai fora do intervalo permitido de 0 a n1-1 e de 0 a n2-1 então o controlador de erro é chamado e um apontador nulo é retornado. Versões modificadas dessa função são usada quando HAVE_INLINE for definida.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.3 Elementos de matriz - Inicializando

Function: void gsl_matrix_set_all (gsl_matrix * m, double x)

Essa função ajusta todos os elementos da matriz m para o valor x.

Function: void gsl_matrix_set_zero (gsl_matrix * m)

Essa função ajusta todos os elementos da matriz m para zero.

Function: void gsl_matrix_set_identity (gsl_matrix * m)

Essa função ajusta os elementos da matriz m para os correspondentes elementos da matriz identidade, m(i,j) = \delta(i,j), i.e. uma diagonal unitária e todos os elementos fora da diagonal com o valor zero. Isso aplica-se a ambas as metrizes retagular e quadrada.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.4 Matrizes - Lendo e Escrevendo

A biblioteca fornece funções para leitura e escrita de matrizes para um arquivo como dados binários ou texto formatado.

Function: int gsl_matrix_fwrite (FILE * stream, const gsl_matrix * m)

Essa função escreve os elementos da matriz m para o fluxo stream em formato binário. O valor de retorno é 0 em caso de sucesso e GSL_EFAILED se houver um problema de escrita para o arquivo. Uma vez que os dados são escritos no formato binário nativo isso pode não ser portável entre diferentes arquiteturas.

Function: int gsl_matrix_fread (FILE * stream, gsl_matrix * m)

Essa função lê para dentro de uma matriz m a partir de um fluxo aberto stream em formato binário. A matriz m deve ser pré-alocada com as dimensões corretas uma vez que a função usa o tamanho de m para determinar quantos bytes devem ser lidos. O valor de retorno é 0 em caso de sucesso e GSL_EFAILED se houver um problema de leitura do arquivo. Os dados são assumidos terem sido escritos no formato binário nativo na mesma arquitetura.

Function: int gsl_matrix_fprintf (FILE * stream, const gsl_matrix * m, const char * format)

Essa função escreve os elementos da matriz m uma linha de cada vez para o fluxo stream usando o especificador de formato format, o qual deve ser um dos seguintes formatos %g, %e ou %f para números em ponto flutuante e %d para inteiros. A função retorna 0 em caso de sucesso e GSL_EFAILED se houver um problema de escrita para o arquivo.

Function: int gsl_matrix_fscanf (FILE * stream, gsl_matrix * m)

Essa função lê dados formatados a partir do fluxo stream para dentro da matriz m. A matriz m deve ser pré-alocada com a correta dimensão uma vez que a função usa o tamanho de m para determinar quantos números ler. A função retorna 0 em caso de sucesso e GSL_EFAILED se houver um problema de leitura do arquivo.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.5 Visualizações de Matrizes

Uma visualização de matriz é um objeto temporário, armazenado na pilha, a qual pode ser usada para operar um subconjunto de elementos de matriz. Visualizaṍes de matriz podem ser definidas para ambos os tipos de matrizes contantes e não constantes usando tipos separados que preservam constness (24). Uma visualização de matriz tem o tipo gsl_matrix_view e uma visualização de matriz contante tem o tipo gsl_matrix_const_view. Em ambos os casos os elementos da visulização podem ser acessados usando a componente matrix do objeto de visualização. Um apontador gsl_matrix * ou const gsl_matrix * pode sr obtido tomando o endereço da componente matrix com o operador &. Adicionalmente a visualizações de matriz também é possível criar visualizações de vetor a partir de uma matriz, tais como visualizações de linhas ou de colunas.

Function: gsl_matrix_view gsl_matrix_submatrix (gsl_matrix * m, size_t k1, size_t k2, size_t n1, size_t n2)
Function: gsl_matrix_const_view gsl_matrix_const_submatrix (const gsl_matrix * m, size_t k1, size_t k2, size_t n1, size_t n2)

Essas funções retornam uma visualização de matriz de uma submatriz da matriz m. O elemento superior esquerdo da submatriz é o elementos (k1,k2) da matriz original. A submatriz tem n1 linhas e n2 colunas. O número físico de colunas na memória fornecido por tda permanece inalterado. Matematicamente, o (i,j)-ésimo elemento da nova matriz é fornecido por,

m'(i,j) = m->data[(k1*m->tda + k2) + i*m->tda + j]

onde o índice i varia de 0 a n1-1 e o índice j varia de 0 a n2-1.

O apontador data da estrutura de matriz retornada é ajustado para null se os parâmetros combinados (i,j,n1,n2,tda) extrapolam o fim da matriz original.

A nova visualização de matriz é somente uma visualização do bloco subjacente da já existente matriz, m. O bloco contendo os elementos de m não é possuído pela nova visualização de matriz. Quando a visualização sai do escopo a matriz original m e seu bloco irão continuar existindo. A memória original pode ser desalocada por meio da liberação da matriz original. Certamente, a matriz original não deve ser desalocada enquanto a visualização estiver ainda em uso.

A função gsl_matrix_const_submatrix é equivalente a gsl_matrix_submatrix mas pode ser usada para matrizes que são declaradas const.

Function: gsl_matrix_view gsl_matrix_view_array (double * base, size_t n1, size_t n2)
Function: gsl_matrix_const_view gsl_matrix_const_view_array (const double * base, size_t n1, size_t n2)

Essas funções retornam uma visualização de matriz do vetor estático base. A matriz tem n1 linhas e n2 colunas. O número físico de colunas na memória é também fornecido por n2. Matematicamente, o (i,j)-ésimo elemento da nova matriz é fornecido por,

m'(i,j) = base[i*n2 + j]

onde o índice i varia de 0 a n1-1 e o índice j varia de 0 a n2-1.

A nova matriz é somente uma visualização do vetor estático base. Quando a visualização sai do escopo o vetor original base irá continuar a existir. A memória original pode somente ser desalocada por meio da liberação do vetor estático original. Certamente, o vetor estático original não deve ser desalocado enquanto a visualização estiver ainda em uso.

A função gsl_matrix_const_view_array é equivalente a gsl_matrix_view_array mas pode ser usada para matrizes que são declaradas const.

Function: gsl_matrix_view gsl_matrix_view_array_with_tda (double * base, size_t n1, size_t n2, size_t tda)
Function: gsl_matrix_const_view gsl_matrix_const_view_array_with_tda (const double * base, size_t n1, size_t n2, size_t tda)

Essas funções retornam uma visualização de matriz da matriz estática base com um número físico de colunas tda que pode diferir da correspondente dimensão da matriz. Uma matriz de n1 linhas e n2 colunas, e o número físico de colunas na memória é fornecido através de tda. Matematicamente, o (i,j)-ésimo elemento da nova matriz é fornecido por,

m'(i,j) = base[i*tda + j]

onde o índice i varia de 0 a n1-1 e o índice j varia de 0 a n2-1.

A nova matriz é somente uma visualização do vetor estático base. Quando a visualização sai do escopo o vetor estático original base irá continuar a existir. A memória original pode somente ser desalocada através da liberação do vetor estático original. Certamente, o vetor estático original não deve ser desalocado enquanto a visualização estiver ainda em uso.

A função gsl_matrix_const_view_array_with_tda é equivalente a gsl_matrix_view_array_with_tda mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_matrix_view gsl_matrix_view_vector (gsl_vector * v, size_t n1, size_t n2)
Function: gsl_matrix_const_view gsl_matrix_const_view_vector (const gsl_vector * v, size_t n1, size_t n2)

Essas funções retornam uma visualização de matriz do vetor v. A matriz tem n1 linhas e n2 colunas. O vetor deve ter salto unitário. O número físico de colunas na memória é também fornecido por n2. Matematicamente, o (i,j)-ésimo elemento da nova matriz é fornecido por,

m'(i,j) = v->data[i*n2 + j]

onde o índice i varia de 0 a n1-1 e o índice j varia de 0 a n2-1.

A nova matriz é somente uma visualização do vetor v. Quando a visualização sai fora do escopo o vetor original v irá continuar a existir. A memória original pode somente ser desalocado através da liberação do vetor original. Certamente, o vetor original não deve ser desalocado enquanto a visualização estiver ainda em uso.

A função gsl_matrix_const_view_vector é equivalente a gsl_matrix_view_vector mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_matrix_view gsl_matrix_view_vector_with_tda (gsl_vector * v, size_t n1, size_t n2, size_t tda)
Function: gsl_matrix_const_view gsl_matrix_const_view_vector_with_tda (const gsl_vector * v, size_t n1, size_t n2, size_t tda)

Essas funções retornam uma visualização de matriz do vetor v com um número físico de colunas tda que pode diferir a partir da correspondente dimensão da matriz. O vetor deve ter salto unitário. A matriz tem n1 linhas e n2 colunas, e o número físico de colunas em memória é fornecido por tda. Matematicamente, o (i,j)-ésimo elemento da nova matriz é fornecido,

m'(i,j) = v->data[i*tda + j]

onde o índice i varia de 0 a n1-1 e o índice j varia de 0 a n2-1.

A nova matriz é somente um visualizador do vetor v. Quando a visualização sai do escopo o vetor original v irá continuar a existir. A memória original pode somente ser desalocada através da liberação do vetor original. Certamente, o vetor original não deve ser desalocado enquanto a visualização estiver ainda em uso.

A função gsl_matrix_const_view_vector_with_tda é equivalente a gsl_matrix_view_vector_with_tda mas pode ser usada para matrizes que forem declaradas const.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.6 Criando visualizações de linhas e colunas

Em geral exitem duas maneiras de acessar um objeto, por referência ou por cópia. As funções descritas nessa seção criam visualizações de vetores que permitem acessar uma linha ou uma coluna de uma matriz por referência. Modificando elementos da visualização é equivalente a modificar a matriz, uma vez que ambos a visualização de vetor e a matriz apontam para o mesmo bloco de memória.

Function: gsl_vector_view gsl_matrix_row (gsl_matrix * m, size_t i)
Function: gsl_vector_const_view gsl_matrix_const_row (const gsl_matrix * m, size_t i)

Essas funções retornam uma visualização de vetor da i-ésima linha da matriz m. O apontador data do novo vetor é ajustado para null se i estiver fora do intervalo.

A função gsl_vector_const_row é equivalente a gsl_matrix_row mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_vector_view gsl_matrix_column (gsl_matrix * m, size_t j)
Function: gsl_vector_const_view gsl_matrix_const_column (const gsl_matrix * m, size_t j)

Essas funções retornam uma visualização de vetor da j-ésima coluna da matriz m. O apontador data do novo vetor é ajustado para null se j estiver fora do intervalo.

A função gsl_vector_const_column é equivalente a gsl_matrix_column mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_vector_view gsl_matrix_subrow (gsl_matrix * m, size_t i, size_t offset, size_t n)
Function: gsl_vector_const_view gsl_matrix_const_subrow (const gsl_matrix * m, size_t i, size_t offset, size_t n)

Essas funções retornam uma visualização de vetor da i-ésima linha da matriz m começando em offset elementos adiante da primeira coluna e contendo n elementos. O apontador data do novo vetor é ajustado para null se i, offset, ou n estiverem fora do intervalo.

A função gsl_vector_const_subrow é equivalente a gsl_matrix_subrow mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_vector_view gsl_matrix_subcolumn (gsl_matrix * m, size_t j, size_t offset, size_t n)
Function: gsl_vector_const_view gsl_matrix_const_subcolumn (const gsl_matrix * m, size_t j, size_t offset, size_t n)

Essas funções retornam uma visualização de vetor da j-ésima coluna da matriz m iniciando-se em offset elementos adiante da primeira linha e contendo n elementos. O apontador data do novo vetor é ajustado para null se j, offset, ou n estiverem fora do intervalo.

A função gsl_vector_const_subcolumn é equivalente a gsl_matrix_subcolumn mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_vector_view gsl_matrix_diagonal (gsl_matrix * m)
Function: gsl_vector_const_view gsl_matrix_const_diagonal (const gsl_matrix * m)

Essas funções retornam uma visualização de vetor da diagonal da matriz m. Uma matriz m não precisa ser quadrada. Para uma matriz retangular o comprimento da diagonal é o mesmo da menor dimensão da matriz.

A função gsl_matrix_const_diagonal é equivalente a gsl_matrix_diagonal mas pode ser usada para matrizes que forem declaradas const.

Function: gsl_vector_view gsl_matrix_subdiagonal (gsl_matrix * m, size_t k)
Function: gsl_vector_const_view gsl_matrix_const_subdiagonal (const gsl_matrix * m, size_t k)

Essas funções retornam uma visualização de vetor da k-ésima subdiagonal (25) of the matriz m. Uma matriz m is not required to be square. The diagonal da matriz corresponds to k = 0.

A função gsl_matrix_const_subdiagonal é equivalente a gsl_matrix_subdiagonal mas pode ser usada para matrizes que forem declared const.

Function: gsl_vector_view gsl_matrix_superdiagonal (gsl_matrix * m, size_t k)
Function: gsl_vector_const_view gsl_matrix_const_superdiagonal (const gsl_matrix * m, size_t k)

Essas funções retornam uma visualização de vetor da k-ésimo superdiagonal (26)da matriz m. A matriz m não precisa ser quadrada. A diagonal da matriz corresponde a k = 0.

A função gsl_matrix_const_superdiagonal é equivalente a gsl_matrix_superdiagonal mas pode ser usada para matrizes que forem declaradas const.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.7 Calculando Matrizes

Function: int gsl_matrix_memcpy (gsl_matrix * dest, const gsl_matrix * src)

Essa função copia os elementos da matriz src para a matriz dest. As duas matrizes devem ter o mesmo tamanho.

Function: int gsl_matrix_swap (gsl_matrix * m1, gsl_matrix * m2)

Essa função intercambia os elementos das matrizes m1 e m2 por meio de cópia. As duas matrizes devem ter o mesmo tamanho.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.8 Copiando linhas e colunas

As funções descritas nessa seção copiam uma linha ou uma coluna de uma matriz para um vetor. Isso permite que os elementos do vetor e a matriz sejam modificados independentemente. Note que se a matriz e o vetor apontam para sobregravar regiões de memória então o resultado irá ser indefinido. O mesmo efeito pode ser alcançado com mais generalidade usando gsl_vector_memcpy com visualizações de vetor de linhas e colunas.

Function: int gsl_matrix_get_row (gsl_vector * v, const gsl_matrix * m, size_t i)

Essa função copia os elementos da i-ésima linha da matriz m para o vetor v. O número de elementos do vetor deve ser o mesmo número de elementos da linha.

Function: int gsl_matrix_get_col (gsl_vector * v, const gsl_matrix * m, size_t j)

Essa função copia os elementos da j-ésima coluna da matriz m para o vetor v. O número de elementos do vetor deve ser o mesmo número de elementos da coluna.

Function: int gsl_matrix_set_row (gsl_matrix * m, size_t i, const gsl_vector * v)

Essa função copia os elementos do vetor v para a i-ésima linha da matriz m. O número de elementos do vetor deve ser o mesmo número de elementos da linha.

Function: int gsl_matrix_set_col (gsl_matrix * m, size_t j, const gsl_vector * v)

Essa função copia os elementos do vetor v para a j-ésima coluna da matriz m. O número de elementos do vetor deve ser o mesmo número de elementos da coluna.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.9 Trocando linhas por colunas

As seguintes funções podem ser usadas para intercambiar as linhas e as colunas de uma matriz.

Function: int gsl_matrix_swap_rows (gsl_matrix * m, size_t i, size_t j)

Essa função troca de lugar a i-ésima e a j-ésima linha da matriz m.

Function: int gsl_matrix_swap_columns (gsl_matrix * m, size_t i, size_t j)

Essa função troca de lugar a i-ésima e a j-ésima coluna da matriz m.

Function: int gsl_matrix_swap_rowcol (gsl_matrix * m, size_t i, size_t j)

Essa função troca de lugar a i-ésimo linha e a j-ésima coluna da matriz m. A matriz deve ser quadrada para que essa operação seja possível.

Function: int gsl_matrix_transpose_memcpy (gsl_matrix * dest, const gsl_matrix * src)

Essa função faz a matriz dest a transposta da matriz src copiando os elementos de src para dest. Essa função trabalha para todas as matrizes desde que as dimensões da matriz dest coincidam com as dimensões da matriz transposta da matriz src.

Function: int gsl_matrix_transpose (gsl_matrix * m)

Essa função substitui a matriz m por sua transposta copiando os elementos da matriz da transposta de volta para m. A matriz deve ser quadrada para que essa operação seja possível.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.10 Matriz - operações

As seguintes operações são definidas para matrizes reais e complexas.

Function: int gsl_matrix_add (gsl_matrix * a, const gsl_matrix * b)

Essa função adiciona os elementos da matriz b aos elementos da matriz a. O resultado a(i,j) \leftarrow a(i,j) + b(i,j) é armazenado em a e b permanece inalterada. As duas matrizes devem ter as mesmas dimensões.

Function: int gsl_matrix_sub (gsl_matrix * a, const gsl_matrix * b)

Essa função subtrai os elementos da matriz b dos elementos da matriz a. O resultado a(i,j) \leftarrow a(i,j) - b(i,j) é armazenado em a e b permanece inalterada. As duas matrizes devem ter as mesmas dimensões.

Function: int gsl_matrix_mul_elements (gsl_matrix * a, const gsl_matrix * b)

Essa função multiplica os elementos da matriz a pelos elementos da matriz b. O resultado a(i,j) \leftarrow a(i,j) * b(i,j) é armazenado em a e b permanece inalterada. As duas matrizes devem ter as mesmas dimensões.

Function: int gsl_matrix_div_elements (gsl_matrix * a, const gsl_matrix * b)

Essa função divide os elementos da matriz a pelos elementos da matriz b. O resultado a(i,j) \leftarrow a(i,j) / b(i,j) é armazenado em a e b permanece inalterada. As duas matrizes devem ter as mesmas dimensões.

Function: int gsl_matrix_scale (gsl_matrix * a, const double x)

Essa função multiplica os elementos da matriz a pelo escalar x. O resultado a(i,j) \leftarrow x a(i,j) é armazenado em a.

Function: int gsl_matrix_add_constant (gsl_matrix * a, const double x)

Essa função adiciona o escalar x aos elementos da matriz a. O resultado a(i,j) \leftarrow a(i,j) + x é armazenado em a.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.11 Encontrando o maior e o menor elemento de uma matriz

As seguintes operações são somente definidas para matrizes reais.

Function: double gsl_matrix_max (const gsl_matrix * m)

Essa função retorna o maior valor na matriz m.

Function: double gsl_matrix_min (const gsl_matrix * m)

Essa função retorna o menor valor na matriz m.

Function: void gsl_matrix_minmax (const gsl_matrix * m, double * min_out, double * max_out)

Essa função retorna o menor valor e o maior valor na matriz m, armazenando-os em min_out e max_out.

Function: void gsl_matrix_max_index (const gsl_matrix * m, size_t * imax, size_t * jmax)

Essa função retorna os índices do maior valor na matriz m, armazenando-os em imax e jmax. Quando houverem muito elementos repetidos maximos então o primeiro elemento encontrado é retornado, na busca seguindo a ordem por linha.

Function: void gsl_matrix_min_index (const gsl_matrix * m, size_t * imin, size_t * jmin)

Essa função retorna os índices do menor valor na matriz m, armazenando-os em imin e jmin. Quando houverem muito elementos repetidos mínimos então o primeiro elemento encontrado é retornado, na busca seguindo a ordem por linha.

Function: void gsl_matrix_minmax_index (const gsl_matrix * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax)

Essa função retorna os índices do menor e do maior valores na matriz m, armazenando-os em (imin,jmin) e em (imax,jmax). Quando houverem muito elementos repetidos menores ou maiores então os primeiros elementos encontrados são retornados, na busca seguindo a ordem por linha.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.12 Matriz - propriedades

As seguintes funções são definidas para matrizes reais e complexas. Para matrizes complexas ambas as partes real e imaginária devem satisfazer as condições.

Function: int gsl_matrix_isnull (const gsl_matrix * m)
Function: int gsl_matrix_ispos (const gsl_matrix * m)
Function: int gsl_matrix_isneg (const gsl_matrix * m)
Function: int gsl_matrix_isnonneg (const gsl_matrix * m)

Essas funções retornam 1 se todos os elementos da matriz m forem zero, estritamente positivos, estritamente negativos, ou não negativos respectivamente, e 0 de outra forma. Para testar se uma matriz é positiva definida, use a decomposição de Cholesky (veja seção Decomposição de Cholesky).

Function: int gsl_matrix_equal (const gsl_matrix * a, const gsl_matrix * b)

Essa função retorna 1 se as matrizes a e b forem iguais (comparando os elementos um a um) e 0 em caso contrário.


[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.4.13 Matrizes - exemplos

O programa abaixo mostra como alocar, inicializar e ler uma matriz usando as funções gsl_matrix_alloc, gsl_matrix_set e gsl_matrix_get.

#include <stdio.h>
#include <gsl/gsl_matrix.h>

int
main (void)
{
  int i, j; 
  gsl_matrix * m = gsl_matrix_alloc (10, 3);
  
  for (i = 0; i < 10; i++)
    for (j = 0; j < 3; j++)
      gsl_matrix_set (m, i, j, 0.23 + 100*i + j);
  
  for (i = 0; i < 100; i++)  /* OUT OF RANGE ERROR */
    for (j = 0; j < 3; j++)
      printf ("m(%d,%d) = %g\n", i, j, 
              gsl_matrix_get (m, i, j));

  gsl_matrix_free (m);

  return 0;
}

Aqui está a saída do programa. O ciclo final tenta ler fora do intervalo da matriz m, e o erro é detectado pelo código de verificação de intervalo em gsl_matrix_get.

$ ./a.out
m(0,0) = 0.23
m(0,1) = 1.23
m(0,2) = 2.23
m(1,0) = 100.23
m(1,1) = 101.23
m(1,2) = 102.23
...
m(9,2) = 902.23
gsl: matrix_source.c:13: ERROR: first index out of range
Default GSL error handler invoked.
Aborted (core dumped)

O programa adiante mostra como escrever uma matriz em um arquivo.

#include <stdio.h>
#include <gsl/gsl_matrix.h>

int
main (void)
{
  int i, j, k = 0; 
  gsl_matrix * m = gsl_matrix_alloc (100, 100);
  gsl_matrix * a = gsl_matrix_alloc (100, 100);
  
  for (i = 0; i < 100; i++)
    for (j = 0; j < 100; j++)
      gsl_matrix_set (m, i, j, 0.23 + i + j);

  {  
     FILE * f = fopen ("test.dat", "wb");
     gsl_matrix_fwrite (f, m);
     fclose (f);
  }

  {  
     FILE * f = fopen ("test.dat", "rb");
     gsl_matrix_fread (f, a);
     fclose (f);
  }

  for (i = 0; i < 100; i++)
    for (j = 0; j < 100; j++)
      {
        double mij = gsl_matrix_get (m, i, j);
        double aij = gsl_matrix_get (a, i, j);
        if (mij != aij) k++;
      }

  gsl_matrix_free (m);
  gsl_matrix_free (a);

  printf ("differences = %d (should be zero)\n", k);
  return (k > 0);
}

Após executar esse programa o arquivo ‘test.dat’ deve conter os elementos de m, escritos em formato binário. Uma matriz que é lida de volta usando a função gsl_matrix_fread deve ser exatamente igual à matriz original.

O programa seguinte demonstra o uso de vizualizações de vetor. O programa calcula as normas de coluna de uma matriz.

#include <math.h>
#include <stdio.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>

int
main (void)
{
  size_t i,j;

  gsl_matrix *m = gsl_matrix_alloc (10, 10);

  for (i = 0; i < 10; i++)
    for (j = 0; j < 10; j++)
      gsl_matrix_set (m, i, j, sin (i) + cos (j));

  for (j = 0; j < 10; j++)
    {
      gsl_vector_view column = gsl_matrix_column (m, j);
      double d;

      d = gsl_blas_dnrm2 (&column.vector);

      printf ("matrix column %d, norm = %g\n", j, d);
    }

  gsl_matrix_free (m);

  return 0;
}

Aqui está a saída do programa,

$ ./a.out
matrix column 0, norm = 4.31461
matrix column 1, norm = 3.1205
matrix column 2, norm = 2.19316
matrix column 3, norm = 3.26114
matrix column 4, norm = 2.53416
matrix column 5, norm = 2.57281
matrix column 6, norm = 4.20469
matrix column 7, norm = 3.65202
matrix column 8, norm = 2.08524
matrix column 9, norm = 3.07313

Os resultados podem ser confirmados usando GNU OCTAVE,

$ octave
GNU Octave, version 2.0.16.92
octave> m = sin(0:9)' * ones(1,10) 
               + ones(10,1) * cos(0:9); 
octave> sqrt(sum(m.^2))
ans =
  4.3146  3.1205  2.1932  3.2611  2.5342  2.5728
  4.2047  3.6520  2.0852  3.0731

[ << ] [ < ] [ Acima ] [ > ] [ >> ]         [Topo] [Conteúdo] [Índice] [ ? ]

8.5 Referências e Leituras Adicionais

Os objetos bloco, vetor e matriz na GSL seguem o modelo valarray do C++. Uma descrição desse modelo pode ser encontrada na seguinte referencia, (27)


[ << ] [ >> ]           [Topo] [Conteúdo] [Índice] [ ? ]

Esse documento foi gerado em 23 de Julho de 2013 usando texi2html 5.0.