home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d199
/
asimplex.lha
/
ASimplex
/
matrix.c
< prev
next >
Wrap
Text File
|
1989-03-31
|
7KB
|
192 lines
/*****************************************************************************
* Modul : matrix.c *
* Zweck : Funktionen für Matrixinversion, Matrizenmultipli- *
* kation und Matrizenzugriff *
* Autor : Stefan Förster *
* *
* Datum | Version | Bemerkung *
* -----------|---------|--------------------------------------------------- *
* 21.12.1988 | | M() *
* | | SetM() *
* | | Mult() *
* 05.01.1989 | | Invers() *
* 18.01.1989 | | Mult() ohne M() und SetM() *
* 30.01.1989 | | Invers() ohne Verwendung von LRSubst(),LRPart()) *
* | | Bug in M(): Typumwandlung (LONG) wegen Overflow *
* | | Bug in SetM(): Typumwandlung (LONG) wegen Overflow *
* 06.02.1989 | 0.0 | Invers() ohne M() u. SetM(); Anpassung an ASimplex *
* | | Mult() angepaßt an ASimplex *
* | | M() angepaßt an ASimplex *
* | | SetM() angepaßt an ASimplex *
* 02.03.1989 | 0.1 | Bug in M(): if(flag==PHASE_I) statt if(PHASE_I) *
* 07.03.1989 | 1.0 | Bug in Invers(): fabs() statt ABS() (Typ SHORT !!) *
*****************************************************************************/
/*****************************************************************************
* USHORT Invers(inv,n,p) *
* Zweck : Berechnung der inversen Matrix mit Hilfe des Gauß-Algorithmus *
* Input : inv - Matrix, von der die inverse Matrix berechnet werden *
* soll *
* n - Größe der (n,n)-Matrix *
* Output : inv - inverse Matrix *
* p - n-Permutationsvektor *
* Ergebnis : INVERTABLE/NOT_INVERTABLE *
*****************************************************************************/
USHORT Invers(inv,n,p)
DOUBLE *inv;
SHORT n,*p;
{
REGISTER DOUBLE *ptr1, *ptr2, *ptr3, s;
REGISTER SHORT i,j,k;
REGISTER DOUBLE max;
for(k=1; k<=n; ++k) {
max = 0.0;
ptr2 = inv + ((LONG)(k-1)*(LONG)(n+1));
for(i=k; i<=n; ++i) {
s = 0;
ptr1 = inv + ((LONG)(i-1)*(LONG)n+(LONG)(k-1));
for(j=k; j<=n; ++j) {
s += fabs(*ptr1);
++ptr1;
}
if(s==0.0) return(NOT_INVERTABLE);
s = fabs(*ptr2)/s;
ptr2 += n;
if(s>max) {
max = s;
p[k-1] = i;
}
}
if(max<EPS_INV) return(NOT_INVERTABLE);
if((i=p[k-1]) != k) {
ptr1 = inv+(i-1)*n;
ptr2 = inv+(k-1)*n;
for(j=0; j<n; ++j) {
s = *ptr1;
*ptr1++ = *ptr2;
*ptr2++ = s;
}
}
s = *(inv + ((LONG)(k-1)*(LONG)(n+1)));
ptr1 = inv + ((LONG)(k-1)*(LONG)n);
for(j=1; j<=n; ++j) {
if(j!=k) {
*ptr1 = -(*ptr1)/s;
ptr2 = inv + (j-1);
ptr3 = inv + (k-1);
for(i=1; i<=n; ++i) {
if(i!=k) *ptr2 += (*ptr3)*(*ptr1);
ptr2 += n;
ptr3 += n;
}
}
++ptr1;
}
ptr1 = inv + (k-1);
for(i=1; i<=n; ++i) {
if(i!=k) *ptr1 /= s;
else *ptr1 = 1.0/s;
ptr1 += n;
}
}
for(k=n-1; k>0; --k) {
if((j=p[k-1]) != k) {
ptr1 = inv + (k-1);
ptr2 = inv + (j-1);
for(i=1; i<=n; ++i) {
s = *ptr1;
*ptr1 = *ptr2;
*ptr2 = s;
ptr1 += n;
ptr2 += n;
}
}
}
return(INVERTABLE);
}
/*****************************************************************************
* VOID Mult(A,B,erg,n,m,k) *
* Zweck : Matrizenmultiplikation erg = A*B *
* Input : A - (n,m)-Matrix *
* B - (m,k)-Matrix *
* n,m,k - Zeilen- und Spaltenanzahlen *
* Output : erg - (n,k)-Matrix A*B *
*****************************************************************************/
VOID Mult(A,B,erg,n,m,k)
DOUBLE *A,*B,*erg;
SHORT n,m,k;
{
REGISTER DOUBLE *Aptr,*Bptr,s;
REGISTER SHORT h,j,i;
for(i=0; i<n; ++i) { /* Zeilen von erg */
for(j=0; j<k; ++j) { /* Spalten von erg */
Aptr = A;
Bptr = B;
for(s=0.0,h=0; h<m; ++h) {
s += (*Aptr++)*(*Bptr);
Bptr += k;
}
*erg++ = s;
++B;
}
A += m;
B -= k;
}
}
/*****************************************************************************
* DOUBLE M(matrix,n,i,j,flag) *
* Zweck : M() liest die Komponente a[i,j] einer Matrix *
* Input : matrix - Zeiger auf die Matrix *
* n - Anzahl Spalten *
* i - Zeilenindex *
* j - Spaltenindex *
* flag - PHASE_I/PHASE_II *
* Bemerkung : Falls j>n und flag==PHASE_I, gibt M() Werte der angehängten *
* Einheitsmatrix aus (0 oder 1) *
*****************************************************************************/
DOUBLE M(matrix,n,i,j,flag)
DOUBLE *matrix;
SHORT n,i,j;
USHORT flag;
{
if(flag==PHASE_I && j>n) return(i==j-n ? 1.0 : 0.0);
else return(*(matrix+((LONG)(i-1)*(LONG)n+(LONG)(j-1))));
}
/*****************************************************************************
* VOID SetM(matrix,n,i,j,value) *
* Zweck : SetM() setzt die Komponente a[i,j] einer Matrix auf 'value' *
* Input : matrix - Zeiger auf die Matrix *
* n - Anzahl Spalten *
* i - Zeilenindex *
* j - Spaltenindex *
* value - a[i,j] = value *
*****************************************************************************/
VOID SetM(matrix,n,i,j,value)
DOUBLE *matrix;
SHORT n,i,j;
DOUBLE value;
{
*(matrix+((LONG)(i-1)*(LONG)n+(LONG)(j-1))) = value;
}