[ << ] | [ < ] | [ Acima ] | [ > ] | [ >> ] | [Topo] | [Conteúdo] | [Índice] | [ ? ] |
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.
8.1 Tipos de dados | ||
8.2 Blocos | ||
8.3 Vetores | ||
8.4 Matrizes | ||
8.5 Referências e Leituras Adicionais |
[ << ] | [ < ] | [ Acima ] | [ > ] | [ >> ] | [Topo] | [Conteúdo] | [Índice] | [ ? ] |
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] | [ ? ] |
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’
8.2.1 Bloco - alocação | ||
8.2.2 Blocos - Lendo e Escrevendo | ||
8.2.3 Blocos - exemplos |
[ << ] | [ < ] | [ Acima ] | [ > ] | [ >> ] | [Topo] | [Conteúdo] | [Índice] | [ ? ] |
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
.
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.
Essa função aloca memória para um blco e inicializa todos os elementos do bloco com o valor zero.
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] | [ ? ] |
A biblioteca fornece funções para leitura e escrita de blocos para um arquivo como dados binários ou como texto formatado.
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.
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.
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.
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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
.
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.
Essa função aloca memória para um vetor de n componentes e inicializa todos os elementos do vetor com o valor zero.
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] | [ ? ] |
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.
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.
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.
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] | [ ? ] |
Essa função ajusta todos os elementos de um vetor v para o valor x.
Essa função ajusta todos os elementos de um vetor v para zero.
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] | [ ? ] |
A biblioteca fornece funções para ler e escrever vetores para um arquivo como dados binários ou texto formatado.
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.
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.
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.
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] | [ ? ] |
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.
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
.
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
.
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
.
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
.
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
.
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] | [ ? ] |
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.
Essa função copia os elementos do vetor src para o vetor dest. Os dois vetores devem ter o mesmo número de componentes.
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] | [ ? ] |
A seguinte função pode ser usada para intercambiar, ou permutar, os elementos de um vetor.
Essa função intercambia o i-ésimo e o j-ésimo elementos do vetor v trocando-os de lugar.
Essa função inverte a ordem dos elementos do vetor v.
[ << ] | [ < ] | [ Acima ] | [ > ] | [ >> ] | [Topo] | [Conteúdo] | [Índice] | [ ? ] |
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.
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.
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.
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.
Essa função multiplica os elementos do vetor a pelo escalar x. O resultado a_i \leftarrow x a_i é armazenado em a.
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] | [ ? ] |
As seguintes operações são somente definidas para vetores reais.
Essa função retorna a maior componente do vetor v.
Essa função retorna a menor componente do vetor v.
Essa função retorna a menor componente e a maior componente do vetor v, armazenando-as em min_out e max_out.
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.
Essa função retorna o índice da menor componente do vetor v. Quando houverem muito elementos menores repetidos então o menor índice é retornado.
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] | [ ? ] |
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.
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.
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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
.
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.
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.
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] | [ ? ] |
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.
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.
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.
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] | [ ? ] |
Essa função ajusta todos os elementos da matriz m para o valor x.
Essa função ajusta todos os elementos da matriz m para zero.
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] | [ ? ] |
A biblioteca fornece funções para leitura e escrita de matrizes para um arquivo como dados binários ou texto formatado.
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.
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.
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.
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] | [ ? ] |
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.
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
.
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
.
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
.
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
.
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] | [ ? ] |
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.
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
.
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
.
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
.
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
.
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
.
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
.
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] | [ ? ] |
Essa função copia os elementos da matriz src para a matriz dest. As duas matrizes devem ter o mesmo tamanho.
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] | [ ? ] |
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.
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.
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.
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.
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] | [ ? ] |
As seguintes funções podem ser usadas para intercambiar as linhas e as colunas de uma matriz.
Essa função troca de lugar a i-ésima e a j-ésima linha da matriz m.
Essa função troca de lugar a i-ésima e a j-ésima coluna da matriz m.
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.
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.
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] | [ ? ] |
As seguintes operações são definidas para matrizes reais e complexas.
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.
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.
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.
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.
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.
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] | [ ? ] |
As seguintes operações são somente definidas para matrizes reais.
Essa função retorna o maior valor na matriz m.
Essa função retorna o menor valor na matriz m.
Essa função retorna o menor valor e o maior valor na matriz m, armazenando-os em min_out e max_out.
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.
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.
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] | [ ? ] |
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.
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).
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] | [ ? ] |
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.outmatrix 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] | [ ? ] |
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.