Skip to content
Snippets Groups Projects
Commit eb2bc323 authored by Armando Luiz Nicolini Delgado's avatar Armando Luiz Nicolini Delgado :nerd:
Browse files

/* Criado módulo 'sislin' com funções para geração de sistemas lineares de vários tipos.

  * A estrutura para matrizes é definida na função 'alocaSislin()'
*/
parent f0e180cc
Branches
No related tags found
No related merge requests found
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "utils.h"
#include "sislin.h"
// Alocaçao de memória. Matriz como vetor de ponteiros para vetores
// alocados independentemente
SistLinear_t* alocaSisLin (unsigned int n, tipoAloc_t tipo)
{
SistLinear_t *SL = (SistLinear_t *) malloc(sizeof(SistLinear_t));
if ( SL ) {
SL->n = n;
SL->tipoAloc_A = tipo;
SL->A = (real_t **) malloc(n * sizeof(real_t *));
SL->b = (real_t *) malloc(n * sizeof(real_t));
if (!(SL->A) || !(SL->b)) {
liberaSisLin(SL);
return NULL;
}
if (tipo == pontVet) {
SL->A[0] = (real_t *) malloc(n * n * sizeof(real_t));
if (!(SL->A[0])) {
liberaSisLin(SL);
return NULL;
}
for (int i=1; i < n; ++i) {
SL->A[i] = SL->A[i-1]+n;
}
}
else if (tipo == pontPont) {
for (int i=0; i < n; ++i)
SL->A[i] = (real_t *) malloc(n * sizeof(real_t));
}
}
return (SL);
}
// Liberacao de memória
void liberaSisLin (SistLinear_t *SL)
{
if (SL) {
if (SL->A) {
if (SL->tipoAloc_A == pontVet) {
if (SL->A[0]) free (SL->A[0]);
}
else if (SL->tipoAloc_A == pontPont) {
for (int i=0; i < SL->n; ++i)
free (SL->A[i]);
}
free(SL->A);
}
if (SL->b) free(SL->b);
free(SL);
}
}
/*!
\brief Cria coeficientes e termos independentes do SL
*
\param SL Ponteiro para o sistema linear
\param tipo Tipo de sistema linear a ser criado. Pode ser:
comSolucao, eqNula, eqProporcional, eqCombLinear, hilbert
\param coef_max Maior valor para coeficientes e termos independentes
*/
void iniSisLin (SistLinear_t *SL, tipoSistLinear_t tipo, real_t coef_max)
{
unsigned int n = SL->n;
// para gerar valores no intervalo [0,coef_max]
real_t invRandMax = ((real_t)coef_max / (real_t)RAND_MAX);
// inicializa vetor b
for (unsigned int i=0; i<n; ++i) {
SL->b[i] = (real_t)rand() * invRandMax;
}
if (tipo == hilbert) {
for (unsigned int i=0; i<n; ++i) {
for (unsigned int j=0; j<n; ++j) {
SL->A[i][j] = 1.0 / (real_t)(i+j+1);
}
}
}
else { // inicializa sistema normal e depois altera
// inicializa a matriz A
for (unsigned int i=0; i<n; ++i) {
for (unsigned int j=0; j<n; ++j) {
SL->A[i][j] = (real_t)rand() * invRandMax;
}
}
if (tipo == eqNula) {
// sorteia eq a ser "nula"
unsigned int nula = rand() % n;
for (unsigned int j=0; j<n; ++j) {
SL->A[nula][j] = 0.0;
}
SL->b[nula] = 0.0;
}
else if (tipo == eqProporcional) {
// sorteia eq a ser "proporcional" e valor
unsigned int propDst = rand() % n;
unsigned int propSrc = (propDst + 1) % n;
real_t mult = (real_t)rand() * invRandMax;
for (unsigned int j=0; j<n; ++j) {
SL->A[propDst][j] = SL->A[propSrc][j] * mult;
}
SL->b[propDst] = SL->b[propSrc] * mult;
}
else if (tipo == eqCombLinear) {
// sorteia eq a ser "combLinear"
unsigned int combDst = rand() % n;
unsigned int combSrc1 = (combDst + 1) % n;
unsigned int combSrc2 = (combDst + 2) % n;
for (unsigned int j=0; j<n; ++j) {
SL->A[combDst][j] = SL->A[combSrc1][j] + SL->A[combSrc2][j];
}
SL->b[combDst] = SL->b[combSrc1] + SL->b[combSrc2];
}
else if (tipo == diagDominante) {
// aumenta o expoente dos termos da diagonal principal
for (unsigned int i=0; i<n; ++i) {
SL->A[i][i] *= (real_t)n;
}
}
}
}
SistLinear_t *lerSisLin (tipoAloc_t tipo)
{
unsigned int n;
SistLinear_t *SL;
scanf("%d",&n);
SL = alocaSisLin (n, tipo);
for(int i=0; i < n; ++i)
for(int j=0; j < n; ++j)
scanf ("%lg", &SL->A[i][j]);
for(int i=0; i < n; ++i)
scanf ("%lg", &SL->b[i]);
return SL;
}
void prnSisLin (SistLinear_t *SL)
{
int n=SL->n;
for(int i=0; i < n; ++i) {
printf("\n ");
for(int j=0; j < n; ++j)
printf ("%10g", SL->A[i][j]);
printf (" | %g", SL->b[i]);
}
printf("\n\n");
}
void prnVetor (real_t *v, unsigned int n)
{
int i;
printf ("\n");
for(i=0; i < n; ++i)
printf ("%10g ", v[i]);
printf ("\n\n");
}
#ifndef __SISLIN_H__
#define __SISLIN_H__
#define COEF_MAX 32.0 // Valor máximo usado para gerar valores aleatórios de
// coeficientes nos sistemas lineares.
#define ABS(num) ((num) < 0.0 ? -(num) : (num)) // Valor absoluto de um número
// tipo usado para representar valores em ponto flutuante
typedef double real_t;
// Tipo de alocação para matrizes
typedef enum {
pontPont=0, // Matriz como vetor de N ponteiros para vetores de tamanho N
pontVet // Matriz como vetor de N ponteiros para um único vetor de tamanho N*N
} tipoAloc_t;
// Estrutura para definiçao de um sistema linear qualquer
typedef struct {
real_t **A; // coeficientes
real_t *b; // termos independentes
unsigned int n; // tamanho do SL
tipoAloc_t tipoAloc_A; // tipo de alocação usada na matriz de coeficientes
} SistLinear_t;
// Tipos de matrizes de coeficientes usados pela função 'inicializaSistLinear()'
typedef enum {
generico = 0,
eqNula,
eqProporcional,
eqCombLinear,
hilbert,
diagDominante
} tipoSistLinear_t;
// Alocaçao e desalocação de matrizes
SistLinear_t* alocaSisLin (unsigned int n, tipoAloc_t tipo);
void liberaSisLin (SistLinear_t *SL);
void iniSisLin (SistLinear_t *SL, tipoSistLinear_t tipo, real_t coef_max);
// Leitura e impressão de sistemas lineares
SistLinear_t *lerSisLin ();
void prnSisLin (SistLinear_t *SL);
void prnVetor (real_t *vet, unsigned int n);
#endif // __SISLIN_H__
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment