/* * matrix.c - misc. routines for manipulating matrices and vectors. * * (C) Copyright 2001 by NetGroup A/S. All rights reserved. * * $Log$ * Revision 1.1 2006/06/20 15:57:22 djburke * Hopefully a saner way to build Basic/MatrixOps * * Revision 1.1 2005/01/08 09:22:57 zowie * Added non-symmetric matrices to eigens; updated version to 2.4.2cvs. * * Revision 1.1.1.1 2001/07/06 13:39:35 kneth * Initial import of code. * * * * The matrices and vectors are indexed in C-style, i.e. from 0 to * N-1. A matrix is assumed to be declared as double **, and it is * allocated by MatrixAlloc. * * * References: * [1] Numerical Recipes in C, 2nd edition, * W.H. Press, S.A. Teukolsky, W.T. Vitterling, and B.P. Flannery, * Cambridge University Press, 1992. * [2] Numerical Analysis, * D. Kincaid and W. Cheney, * Brooks/Cole Publishing Company, 1991. * [3] The C Programming Language, 2nd edition, * B.W. Kernighan and D.M. Ritchie, * Prentice Hall, 1988. * [4] Advanced Engineering Mathematics, 6th edition, * E. Kreyszig, * Wiley and Sons, 1988. * */ #include #include #include #ifndef TINY # define TINY 1.0e-18 #endif #include "sslib.h" #include "matrix.h" /* * MatrixAlloc allocates storage for a square matrix with dimension * n*n. An error message is printed, if it was impossible to allocate * the neccesary space, [3]. * */ double **MatrixAlloc(const int n) { double **matrix; int i; matrix=(double **)calloc(n, sizeof(double *)); if (matrix==NULL) SSLerror("No memory available in routine MatrixAlloc"); else for(i=0; i=k so ... */ not_finished=1; while (not_finished) { j++; temp=fabs(a[p[j]][k]/s[p[j]]); for(i=k; i=(fabs(a[p[i]][k])/s[p[i]])) not_finished=0; /* end loop */ } /* while */ i_swap=p[k]; p[k]=p[j]; p[j]=i_swap; temp=1.0/a[p[k]][k]; for(i=(k+1); i=0; i--) { /* back subst */ sum=b[p[i]]; for(j=(i+1); j=eps)); VectorFree(n, x_old); } /* GaussSeidel */ /* * Jacobi is an iterative equation solver, [2, pp. 185-189]. The algorithm * can be optimised a bit, which is done in this implementation. The method * is suitable for parallel computers. * * The arguments are the same as in GaussSeidel. * */ void Jacobi(const int n, double **a, double *b, double *x, double eps, int max_iter) { double d; /* temporary real */ int i, j, iter; /* counters */ double **a_new; /* a is altered */ double *b_new; /* b is altered */ double *u; /* new solution */ double norm; /* L1-norm */ a_new=MatrixAlloc(3); b_new=VectorAlloc(3); u=VectorAlloc(3); for(i=0; i=eps)); MatrixFree(3, a_new); VectorFree(3, b_new); VectorFree(3, u); } /* Jacobi */ /* * DotProd computes the dot product between two vectors. They are assumed to * be of the same dimension. * */ double DotProd(const int n, double *u, double *v) { int i; /* counter */ double sum=0.0; /* temporary real */ for(i=0; i */ for(i=0; i