OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [demos/] [nxscribble/] [matrix.c] - Diff between revs 27 and 174

Only display areas with differences | Details | Blame | View Log

Rev 27 Rev 174
/***********************************************************************
/***********************************************************************
 
 
matrix.c - simple matrix operations
matrix.c - simple matrix operations
 
 
Copyright (C) 1991 Dean Rubine
Copyright (C) 1991 Dean Rubine
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License. See ../COPYING for
it under the terms of the GNU General Public License. See ../COPYING for
the full agreement.
the full agreement.
 
 
**********************************************************************/
**********************************************************************/
 
 
/*
/*
 Simple matrix operations
 Simple matrix operations
 Why I am writing this stuff over is beyond me
 Why I am writing this stuff over is beyond me
*/
*/
 
 
#undef PIQ_DEBUG
#undef PIQ_DEBUG
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <math.h>
#include <math.h>
#include "util.h"
#include "util.h"
#include "matrix.h"
#include "matrix.h"
 
 
 
 
typedef struct array_header *Array;
typedef struct array_header *Array;
 
 
#define EPSILON         (1.0e-10)       /* zero range */
#define EPSILON         (1.0e-10)       /* zero range */
 
 
/*
/*
 Allocation functions
 Allocation functions
*/
*/
 
 
 
 
Vector
Vector
NewVector(r)
NewVector(r)
int r;
int r;
{
{
        register struct array_header *a;
        register struct array_header *a;
        register Vector v;
        register Vector v;
 
 
        a = (struct array_header *)
        a = (struct array_header *)
            allocate(sizeof(struct array_header) + r * sizeof(double), char);
            allocate(sizeof(struct array_header) + r * sizeof(double), char);
        a->ndims = 1;
        a->ndims = 1;
        a->nrows = r;
        a->nrows = r;
        a->ncols = 1;
        a->ncols = 1;
        v = (Vector) (a + 1);
        v = (Vector) (a + 1);
 
 
#define CHECK
#define CHECK
#ifdef CHECK
#ifdef CHECK
        if(HEADER(v) != (struct array_header *) a ||
        if(HEADER(v) != (struct array_header *) a ||
           NDIMS(v) != 1 || NROWS(v) != r || NCOLS(v) != 1) {
           NDIMS(v) != 1 || NROWS(v) != r || NCOLS(v) != 1) {
                exit_error("NewVector error: v=%x H: %x,%x  D:%d,%d  R:%d,%d  C:%d,%d\n", v,  HEADER(v), a,  NDIMS(v), 1,  NROWS(v), r, NCOLS(v), 1);
                exit_error("NewVector error: v=%x H: %x,%x  D:%d,%d  R:%d,%d  C:%d,%d\n", v,  HEADER(v), a,  NDIMS(v), 1,  NROWS(v), r, NCOLS(v), 1);
            }
            }
#endif
#endif
 
 
        return v;
        return v;
}
}
 
 
Matrix
Matrix
NewMatrix(r, c)
NewMatrix(r, c)
int r, c;
int r, c;
{
{
        register struct array_header *a = (struct array_header *)
        register struct array_header *a = (struct array_header *)
           allocate(sizeof(struct array_header) + r * sizeof(double *), char);
           allocate(sizeof(struct array_header) + r * sizeof(double *), char);
        register int i;
        register int i;
        register Matrix m;
        register Matrix m;
 
 
        m = (Matrix) (a + 1);
        m = (Matrix) (a + 1);
        for(i = 0; i < r; i++)
        for(i = 0; i < r; i++)
                m[i] = allocate(c, double);
                m[i] = allocate(c, double);
        a->ndims = 2;
        a->ndims = 2;
        a->nrows = r;
        a->nrows = r;
        a->ncols = c;
        a->ncols = c;
        return m;
        return m;
}
}
 
 
void
void
FreeVector(v)
FreeVector(v)
Vector v;
Vector v;
{
{
        free(HEADER(v));
        free(HEADER(v));
}
}
 
 
void
void
FreeMatrix(m)
FreeMatrix(m)
Matrix m;
Matrix m;
{
{
        register int i;
        register int i;
 
 
        for(i = 0; i < NROWS(m); i++)
        for(i = 0; i < NROWS(m); i++)
                free(m[i]);
                free(m[i]);
        free(HEADER(m));
        free(HEADER(m));
}
}
 
 
Vector
Vector
VectorCopy(v)
VectorCopy(v)
register Vector v;
register Vector v;
{
{
        register Vector r = NewVector(NROWS(v));
        register Vector r = NewVector(NROWS(v));
        register int i;
        register int i;
 
 
        for(i = 0; i < NROWS(v); i++)
        for(i = 0; i < NROWS(v); i++)
                r[i] = v[i];
                r[i] = v[i];
        return r;
        return r;
}
}
 
 
Matrix
Matrix
MatrixCopy(m)
MatrixCopy(m)
register Matrix m;
register Matrix m;
{
{
        register Matrix r = NewMatrix(NROWS(m), NCOLS(m));
        register Matrix r = NewMatrix(NROWS(m), NCOLS(m));
        register int i, j;
        register int i, j;
 
 
        for(i = 0; i < NROWS(m); i++)
        for(i = 0; i < NROWS(m); i++)
                for(j = 0; j < NROWS(m); j++)
                for(j = 0; j < NROWS(m); j++)
                        r[i][j] = m[i][j];
                        r[i][j] = m[i][j];
        return r;
        return r;
}
}
 
 
/* Null vector and matrixes */
/* Null vector and matrixes */
 
 
 
 
void
void
ZeroVector(v)
ZeroVector(v)
Vector v;
Vector v;
{
{
        register int i;
        register int i;
        for(i = 0; i < NROWS(v); i++) v[i] = 0.0;
        for(i = 0; i < NROWS(v); i++) v[i] = 0.0;
}
}
 
 
 
 
void
void
ZeroMatrix(m)
ZeroMatrix(m)
Matrix m;
Matrix m;
{
{
        register int i, j;
        register int i, j;
        for(i = 0; i < NROWS(m); i++)
        for(i = 0; i < NROWS(m); i++)
                for(j = 0; j < NCOLS(m); j++)
                for(j = 0; j < NCOLS(m); j++)
                        m[i][j] = 0.0;
                        m[i][j] = 0.0;
}
}
 
 
void
void
FillMatrix(m, fill)
FillMatrix(m, fill)
Matrix m;
Matrix m;
double fill;
double fill;
{
{
        register int i, j;
        register int i, j;
        for(i = 0; i < NROWS(m); i++)
        for(i = 0; i < NROWS(m); i++)
                for(j = 0; j < NCOLS(m); j++)
                for(j = 0; j < NCOLS(m); j++)
                        m[i][j] = fill;
                        m[i][j] = fill;
}
}
 
 
double
double
InnerProduct(v1, v2)
InnerProduct(v1, v2)
register Vector v1, v2;
register Vector v1, v2;
{
{
        double result = 0;
        double result = 0;
        register int n = NROWS(v1);
        register int n = NROWS(v1);
        if(n != NROWS(v2)) {
        if(n != NROWS(v2)) {
                exit_error("InnerProduct %d x %d ", n, NROWS(v2));
                exit_error("InnerProduct %d x %d ", n, NROWS(v2));
            }
            }
        while(--n >= 0)
        while(--n >= 0)
                result += *v1++ * *v2++;
                result += *v1++ * *v2++;
        return result;
        return result;
}
}
 
 
void
void
MatrixMultiply(m1, m2, prod)
MatrixMultiply(m1, m2, prod)
register Matrix m1, m2, prod;
register Matrix m1, m2, prod;
{
{
        register int i, j, k;
        register int i, j, k;
        double sum;
        double sum;
 
 
        if(NCOLS(m1) != NROWS(m2)) {
        if(NCOLS(m1) != NROWS(m2)) {
                error("MatrixMultiply: Can't multiply %dx%d and %dx%d matrices",
                error("MatrixMultiply: Can't multiply %dx%d and %dx%d matrices",
                        NROWS(m1), NCOLS(m1), NROWS(m2), NCOLS(m2));
                        NROWS(m1), NCOLS(m1), NROWS(m2), NCOLS(m2));
                return;
                return;
            }
            }
        if(NROWS(prod) != NROWS(m1) || NCOLS(prod) != NCOLS(m2)) {
        if(NROWS(prod) != NROWS(m1) || NCOLS(prod) != NCOLS(m2)) {
                error("MatrixMultiply: %dx%d times %dx%d does not give %dx%d product",
                error("MatrixMultiply: %dx%d times %dx%d does not give %dx%d product",
                        NROWS(m1), NCOLS(m1), NROWS(m2), NCOLS(m2),
                        NROWS(m1), NCOLS(m1), NROWS(m2), NCOLS(m2),
                        NROWS(prod), NCOLS(prod));
                        NROWS(prod), NCOLS(prod));
                return;
                return;
            }
            }
 
 
        for(i = 0; i < NROWS(m1); i++)
        for(i = 0; i < NROWS(m1); i++)
                for(j = 0; j < NCOLS(m2); j++) {
                for(j = 0; j < NCOLS(m2); j++) {
                        sum = 0;
                        sum = 0;
                        for(k = 0; k < NCOLS(m1); k++)
                        for(k = 0; k < NCOLS(m1); k++)
                                sum += m1[i][k] * m2[k][j];
                                sum += m1[i][k] * m2[k][j];
                        prod[i][j] = sum;
                        prod[i][j] = sum;
                }
                }
}
}
 
 
/*
/*
Compute result = v'm where
Compute result = v'm where
        v is a column vector (r x 1)
        v is a column vector (r x 1)
        m is a matrix (r x c)
        m is a matrix (r x c)
        result is a column vector (c x 1)
        result is a column vector (c x 1)
*/
*/
 
 
void
void
VectorTimesMatrix(v, m, prod)
VectorTimesMatrix(v, m, prod)
Vector v;
Vector v;
Matrix m;
Matrix m;
Vector prod;
Vector prod;
{
{
        register int i, j;
        register int i, j;
 
 
        if(NROWS(v) != NROWS(m)) {
        if(NROWS(v) != NROWS(m)) {
                error("VectorTimesMatrix: Can't multiply %d vector by %dx%d",
                error("VectorTimesMatrix: Can't multiply %d vector by %dx%d",
                        NROWS(v), NROWS(m), NCOLS(m));
                        NROWS(v), NROWS(m), NCOLS(m));
                return;
                return;
            }
            }
        if(NROWS(prod) != NCOLS(m)) {
        if(NROWS(prod) != NCOLS(m)) {
                error("VectorTimesMatrix: %d vector times %dx%d mat does not fit in %d product" ,
                error("VectorTimesMatrix: %d vector times %dx%d mat does not fit in %d product" ,
                        NROWS(v), NROWS(m), NCOLS(m), NROWS(prod));
                        NROWS(v), NROWS(m), NCOLS(m), NROWS(prod));
                return;
                return;
            }
            }
 
 
        for(j = 0; j < NCOLS(m); j++) {
        for(j = 0; j < NCOLS(m); j++) {
                prod[j] = 0;
                prod[j] = 0;
                for(i = 0; i < NROWS(m); i++)
                for(i = 0; i < NROWS(m); i++)
                        prod[j] += v[i] * m[i][j];
                        prod[j] += v[i] * m[i][j];
        }
        }
}
}
 
 
void
void
ScalarTimesVector(s, v, product)
ScalarTimesVector(s, v, product)
double s;
double s;
register Vector v, product;
register Vector v, product;
{
{
        register int n = NROWS(v);
        register int n = NROWS(v);
 
 
        if(NROWS(v) != NROWS(product)) {
        if(NROWS(v) != NROWS(product)) {
                error("ScalarTimesVector: result wrong size (%d!=%d)",
                error("ScalarTimesVector: result wrong size (%d!=%d)",
                        NROWS(v), NROWS(product));
                        NROWS(v), NROWS(product));
                return;
                return;
            }
            }
 
 
        while(--n >= 0)
        while(--n >= 0)
                *product++ = s * *v++;
                *product++ = s * *v++;
}
}
 
 
void
void
ScalarTimesMatrix(s, m, product)
ScalarTimesMatrix(s, m, product)
double s;
double s;
register Matrix m, product;
register Matrix m, product;
{
{
        register int i, j;
        register int i, j;
 
 
        if(NROWS(m) != NROWS(product)  ||
        if(NROWS(m) != NROWS(product)  ||
           NCOLS(m) != NCOLS(product)) {
           NCOLS(m) != NCOLS(product)) {
                error("ScalarTimesMatrix: result wrong size (%d!=%d)or(%d!=%d)",
                error("ScalarTimesMatrix: result wrong size (%d!=%d)or(%d!=%d)",
                        NROWS(m), NROWS(product),
                        NROWS(m), NROWS(product),
                        NCOLS(m), NCOLS(product));
                        NCOLS(m), NCOLS(product));
                return;
                return;
            }
            }
 
 
        for(i = 0; i < NROWS(m); i++)
        for(i = 0; i < NROWS(m); i++)
                for(j = 0; j < NCOLS(m); j++)
                for(j = 0; j < NCOLS(m); j++)
                        product[i][j] = s * m[i][j];
                        product[i][j] = s * m[i][j];
}
}
 
 
/*
/*
 Compute v'mv
 Compute v'mv
 */
 */
 
 
double
double
QuadraticForm(v, m)
QuadraticForm(v, m)
register Vector v;
register Vector v;
register Matrix m;
register Matrix m;
{
{
        register int i, j, n;
        register int i, j, n;
        double result = 0;
        double result = 0;
 
 
        n = NROWS(v);
        n = NROWS(v);
 
 
        if(n != NROWS(m) || n != NCOLS(m)) {
        if(n != NROWS(m) || n != NCOLS(m)) {
                exit_error("QuadraticForm: bad matrix size (%dx%d not %dx%d)",
                exit_error("QuadraticForm: bad matrix size (%dx%d not %dx%d)",
                        NROWS(m), NCOLS(m), n, n);
                        NROWS(m), NCOLS(m), n, n);
            }
            }
        for(i = 0; i < n; i++)
        for(i = 0; i < n; i++)
                for(j = 0; j < n; j++) {
                for(j = 0; j < n; j++) {
 
 
#ifdef PIQ_DEBUG
#ifdef PIQ_DEBUG
                        printf("%g*%g*%g [%g] %s ",
                        printf("%g*%g*%g [%g] %s ",
                        m[i][j],v[i],v[j],
                        m[i][j],v[i],v[j],
                        m[i][j] * v[i] * v[j],
                        m[i][j] * v[i] * v[j],
                        i==n-1&&j==n-1? "=" : "+");
                        i==n-1&&j==n-1? "=" : "+");
#endif
#endif
 
 
                        result += m[i][j] * v[i] * v[j];
                        result += m[i][j] * v[i] * v[j];
                }
                }
        return result;
        return result;
}
}
 
 
/* Matrix inversion using full pivoting.
/* Matrix inversion using full pivoting.
 * The standard Gauss-Jordan method is used.
 * The standard Gauss-Jordan method is used.
 * The return value is the determinant.
 * The return value is the determinant.
 * The input matrix may be the same as the result matrix
 * The input matrix may be the same as the result matrix
 *
 *
 *      det = InvertMatrix(inputmatrix, resultmatrix);
 *      det = InvertMatrix(inputmatrix, resultmatrix);
 *
 *
 * HISTORY
 * HISTORY
 * 26-Feb-82  David Smith (drs) at Carnegie-Mellon University
 * 26-Feb-82  David Smith (drs) at Carnegie-Mellon University
 *      Written.
 *      Written.
 * Sun Mar 20 19:36:16 EST 1988 - converted to this form by Dean Rubine
 * Sun Mar 20 19:36:16 EST 1988 - converted to this form by Dean Rubine
 *
 *
 */
 */
 
 
int     DebugInvertMatrix = 0;
int     DebugInvertMatrix = 0;
 
 
#define PERMBUFSIZE 200 /* Max mat size */
#define PERMBUFSIZE 200 /* Max mat size */
 
 
#define _abs(x) ((x)>=0 ? (x) : -(x))
#define _abs(x) ((x)>=0 ? (x) : -(x))
 
 
double
double
InvertMatrix(ym, rm)
InvertMatrix(ym, rm)
Matrix ym, rm;
Matrix ym, rm;
{
{
        register int i, j, k;
        register int i, j, k;
        double det, biga, recip_biga, hold;
        double det, biga, recip_biga, hold;
        int l[PERMBUFSIZE], m[PERMBUFSIZE];
        int l[PERMBUFSIZE], m[PERMBUFSIZE];
        register int n;
        register int n;
 
 
        if(NROWS(ym) != NCOLS(ym)) {
        if(NROWS(ym) != NCOLS(ym)) {
                exit_error("InvertMatrix: not square");
                exit_error("InvertMatrix: not square");
            }
            }
 
 
        n = NROWS(ym);
        n = NROWS(ym);
 
 
        if(n != NROWS(rm) || n != NCOLS(rm)) {
        if(n != NROWS(rm) || n != NCOLS(rm)) {
                exit_error("InvertMatrix: result wrong size");
                exit_error("InvertMatrix: result wrong size");
            }
            }
 
 
        /* Copy ym to rm */
        /* Copy ym to rm */
 
 
        if(ym != rm)
        if(ym != rm)
                for(i = 0; i < n; i++)
                for(i = 0; i < n; i++)
                        for(j = 0; j < n; j++)
                        for(j = 0; j < n; j++)
                                rm[i][j] = ym[i][j];
                                rm[i][j] = ym[i][j];
 
 
        /*if(DebugInvertMatrix) PrintMatrix(rm, "Inverting (det=%g)\n", det);*/
        /*if(DebugInvertMatrix) PrintMatrix(rm, "Inverting (det=%g)\n", det);*/
 
 
    /* Allocate permutation vectors for l and m, with the same origin
    /* Allocate permutation vectors for l and m, with the same origin
       as the matrix. */
       as the matrix. */
 
 
        if (n >= PERMBUFSIZE) {
        if (n >= PERMBUFSIZE) {
                exit_error("InvertMatrix: PERMBUFSIZE");
                exit_error("InvertMatrix: PERMBUFSIZE");
            }
            }
 
 
        det = 1.0;
        det = 1.0;
        for (k = 0; k < n;  k++) {
        for (k = 0; k < n;  k++) {
                l[k] = k;  m[k] = k;
                l[k] = k;  m[k] = k;
                biga = rm[k][k];
                biga = rm[k][k];
 
 
                /* Find the biggest element in the submatrix */
                /* Find the biggest element in the submatrix */
                for (i = k;  i < n;  i++)
                for (i = k;  i < n;  i++)
                        for (j = k; j < n; j++)
                        for (j = k; j < n; j++)
                                if (_abs(rm[i][j]) > _abs(biga)) {
                                if (_abs(rm[i][j]) > _abs(biga)) {
                                        biga = rm[i][j];
                                        biga = rm[i][j];
                                        l[k] = i;
                                        l[k] = i;
                                        m[k] = j;
                                        m[k] = j;
                                }
                                }
 
 
                if(DebugInvertMatrix)
                if(DebugInvertMatrix)
                        if(biga == 0.0)
                        if(biga == 0.0)
                                PrintMatrix(m, "found zero biga = %g\n", biga);
                                PrintMatrix(m, "found zero biga = %g\n", biga);
 
 
                /* Interchange rows */
                /* Interchange rows */
                i = l[k];
                i = l[k];
                if (i > k)
                if (i > k)
                        for (j = 0; j < n; j++) {
                        for (j = 0; j < n; j++) {
                                hold = -rm[k][j];
                                hold = -rm[k][j];
                                rm[k][j] = rm[i][j];
                                rm[k][j] = rm[i][j];
                                rm[i][j] = hold;
                                rm[i][j] = hold;
                        }
                        }
 
 
                /* Interchange columns */
                /* Interchange columns */
                j = m[k];
                j = m[k];
                if (j > k)
                if (j > k)
                        for (i = 0; i < n; i++) {
                        for (i = 0; i < n; i++) {
                                hold = -rm[i][k];
                                hold = -rm[i][k];
                                rm[i][k] = rm[i][j];
                                rm[i][k] = rm[i][j];
                                rm[i][j] = hold;
                                rm[i][j] = hold;
                        }
                        }
 
 
                /* Divide column by minus pivot
                /* Divide column by minus pivot
                    (value of pivot element is contained in biga). */
                    (value of pivot element is contained in biga). */
                if (biga == 0.0) {
                if (biga == 0.0) {
                        return 0.0;
                        return 0.0;
                }
                }
 
 
                if(DebugInvertMatrix) printf("biga = %g\n", biga);
                if(DebugInvertMatrix) printf("biga = %g\n", biga);
                recip_biga = 1/biga;
                recip_biga = 1/biga;
                for (i = 0; i < n; i++)
                for (i = 0; i < n; i++)
                        if (i != k)
                        if (i != k)
                                rm[i][k] *= -recip_biga;
                                rm[i][k] *= -recip_biga;
 
 
                /* Reduce matrix */
                /* Reduce matrix */
                for (i = 0; i < n; i++)
                for (i = 0; i < n; i++)
                        if (i != k) {
                        if (i != k) {
                                hold = rm[i][k];
                                hold = rm[i][k];
                                for (j = 0; j < n; j++)
                                for (j = 0; j < n; j++)
                                        if (j != k)
                                        if (j != k)
                                                rm[i][j] += hold * rm[k][j];
                                                rm[i][j] += hold * rm[k][j];
                        }
                        }
 
 
                /* Divide row by pivot */
                /* Divide row by pivot */
                for (j = 0; j < n; j++)
                for (j = 0; j < n; j++)
                        if (j != k)
                        if (j != k)
                                rm[k][j] *= recip_biga;
                                rm[k][j] *= recip_biga;
 
 
                det *= biga;    /* Product of pivots */
                det *= biga;    /* Product of pivots */
                if(DebugInvertMatrix) printf("det = %g\n", det);
                if(DebugInvertMatrix) printf("det = %g\n", det);
                rm[k][k] = recip_biga;
                rm[k][k] = recip_biga;
 
 
        }       /* K loop */
        }       /* K loop */
 
 
        /* Final row & column interchanges */
        /* Final row & column interchanges */
        for (k = n - 1; k >= 0; k--) {
        for (k = n - 1; k >= 0; k--) {
                i = l[k];
                i = l[k];
                if (i > k)
                if (i > k)
                        for (j = 0; j < n; j++) {
                        for (j = 0; j < n; j++) {
                                hold = rm[j][k];
                                hold = rm[j][k];
                                rm[j][k] = -rm[j][i];
                                rm[j][k] = -rm[j][i];
                                rm[j][i] = hold;
                                rm[j][i] = hold;
                        }
                        }
                j = m[k];
                j = m[k];
                if (j > k)
                if (j > k)
                        for (i = 0; i < n; i++) {
                        for (i = 0; i < n; i++) {
                                hold = rm[k][i];
                                hold = rm[k][i];
                                rm[k][i] = -rm[j][i];
                                rm[k][i] = -rm[j][i];
                                rm[j][i] = hold;
                                rm[j][i] = hold;
                        }
                        }
        }
        }
 
 
        if(DebugInvertMatrix) printf("returning, det = %g\n", det);
        if(DebugInvertMatrix) printf("returning, det = %g\n", det);
 
 
        return det;
        return det;
}
}
 
 
 
 
#include "bitvector.h"
#include "bitvector.h"
 
 
Vector
Vector
SliceVector(v, rowmask)
SliceVector(v, rowmask)
Vector v;
Vector v;
BitVector rowmask;
BitVector rowmask;
{
{
        register int i, ri;
        register int i, ri;
 
 
        Vector r = NewVector(bitcount(NROWS(v), rowmask));
        Vector r = NewVector(bitcount(NROWS(v), rowmask));
        for(i = ri = 0; i < NROWS(v); i++)
        for(i = ri = 0; i < NROWS(v); i++)
                if(IS_SET(i, rowmask) )
                if(IS_SET(i, rowmask) )
                        r[ri++] = v[i];
                        r[ri++] = v[i];
        return r;
        return r;
}
}
 
 
Matrix
Matrix
SliceMatrix(m, rowmask, colmask)
SliceMatrix(m, rowmask, colmask)
Matrix m;
Matrix m;
BitVector rowmask, colmask;
BitVector rowmask, colmask;
{
{
        register int i, ri, j, rj;
        register int i, ri, j, rj;
 
 
        Matrix r;
        Matrix r;
 
 
        r = NewMatrix(bitcount(NROWS(m), rowmask),
        r = NewMatrix(bitcount(NROWS(m), rowmask),
                             bitcount(NCOLS(m), colmask));
                             bitcount(NCOLS(m), colmask));
        for(i = ri = 0; i < NROWS(m); i++)
        for(i = ri = 0; i < NROWS(m); i++)
                if(IS_SET(i, rowmask) ) {
                if(IS_SET(i, rowmask) ) {
                        for(j = rj = 0; j < NCOLS(m); j++)
                        for(j = rj = 0; j < NCOLS(m); j++)
                                if(IS_SET(j, colmask))
                                if(IS_SET(j, colmask))
                                        r[ri][rj++] = m[i][j];
                                        r[ri][rj++] = m[i][j];
                        ri++;
                        ri++;
                }
                }
 
 
        return r;
        return r;
}
}
 
 
Matrix
Matrix
DeSliceMatrix(m, fill, rowmask, colmask, r)
DeSliceMatrix(m, fill, rowmask, colmask, r)
Matrix m;
Matrix m;
double fill;
double fill;
BitVector rowmask, colmask;
BitVector rowmask, colmask;
Matrix r;
Matrix r;
{
{
        register int i, ri, j, rj;
        register int i, ri, j, rj;
 
 
        FillMatrix(r, fill);
        FillMatrix(r, fill);
 
 
        for(i = ri = 0; i < NROWS(r); i++) {
        for(i = ri = 0; i < NROWS(r); i++) {
                if(IS_SET(i, rowmask) )  {
                if(IS_SET(i, rowmask) )  {
                        for(j = rj = 0; j < NCOLS(r); j++)
                        for(j = rj = 0; j < NCOLS(r); j++)
                                if(IS_SET(j, colmask))
                                if(IS_SET(j, colmask))
                                        r[i][j] = m[ri][rj++];
                                        r[i][j] = m[ri][rj++];
                        ri++;
                        ri++;
                }
                }
        }
        }
 
 
        return r;
        return r;
}
}
 
 
void
void
OutputVector(f, v)
OutputVector(f, v)
FILE *f;
FILE *f;
register Vector v;
register Vector v;
{
{
        register int i;
        register int i;
        fprintf(f, " V %d   ", NROWS(v));
        fprintf(f, " V %d   ", NROWS(v));
        for(i = 0; i < NROWS(v); i++)
        for(i = 0; i < NROWS(v); i++)
                fprintf(f, " %g", v[i]);
                fprintf(f, " %g", v[i]);
        fprintf(f, "\n");
        fprintf(f, "\n");
}
}
 
 
Vector
Vector
InputVector(f)
InputVector(f)
FILE *f;
FILE *f;
{
{
        register Vector v;
        register Vector v;
        register int i;
        register int i;
        char check[4];
        char check[4];
        int nrows;
        int nrows;
 
 
        if(fscanf(f, "%1s %d", check, &nrows) != 2) {
        if(fscanf(f, "%1s %d", check, &nrows) != 2) {
                exit_error("InputVector fscanf 1");
                exit_error("InputVector fscanf 1");
            }
            }
        if(check[0] != 'V') {
        if(check[0] != 'V') {
                exit_error("InputVector check");
                exit_error("InputVector check");
            }
            }
        v = NewVector(nrows);
        v = NewVector(nrows);
        for(i = 0; i < nrows; i++) {
        for(i = 0; i < nrows; i++) {
                if(fscanf(f, "%lf", &v[i]) != 1) {
                if(fscanf(f, "%lf", &v[i]) != 1) {
                        exit_error("InputVector fscanf 2");
                        exit_error("InputVector fscanf 2");
                    }
                    }
        }
        }
        return v;
        return v;
}
}
 
 
void
void
OutputMatrix(f, m)
OutputMatrix(f, m)
FILE* f;
FILE* f;
register Matrix m;
register Matrix m;
{
{
        register int i, j;
        register int i, j;
        fprintf(f, " M %d %d\n", NROWS(m), NCOLS(m));
        fprintf(f, " M %d %d\n", NROWS(m), NCOLS(m));
        for(i = 0; i < NROWS(m);  i++) {
        for(i = 0; i < NROWS(m);  i++) {
                for(j = 0; j < NCOLS(m); j++)
                for(j = 0; j < NCOLS(m); j++)
                        fprintf(f, " %g", m[i][j]);
                        fprintf(f, " %g", m[i][j]);
                fprintf(f, "\n");
                fprintf(f, "\n");
        }
        }
}
}
 
 
Matrix
Matrix
InputMatrix(f)
InputMatrix(f)
FILE *f;
FILE *f;
{
{
        register Matrix m;
        register Matrix m;
        register int i, j;
        register int i, j;
        char check[4];
        char check[4];
        int nrows, ncols;
        int nrows, ncols;
 
 
        if(fscanf(f, "%1s %d %d", check, &nrows, &ncols) != 3) {
        if(fscanf(f, "%1s %d %d", check, &nrows, &ncols) != 3) {
                exit_error("InputMatrix fscanf 1");
                exit_error("InputMatrix fscanf 1");
            }
            }
        if(check[0] != 'M') {
        if(check[0] != 'M') {
                exit_error("InputMatrix check");
                exit_error("InputMatrix check");
            }
            }
        m = NewMatrix(nrows, ncols);
        m = NewMatrix(nrows, ncols);
        for(i = 0; i < nrows; i++)
        for(i = 0; i < nrows; i++)
            for(j = 0; j < ncols; j++) {
            for(j = 0; j < ncols; j++) {
                        if(fscanf(f, "%lf", &m[i][j]) != 1) {
                        if(fscanf(f, "%lf", &m[i][j]) != 1) {
                                exit_error("InputMatrix fscanf 2");
                                exit_error("InputMatrix fscanf 2");
                            }
                            }
            }
            }
 
 
        return m;
        return m;
}
}
 
 
double
double
InvertSingularMatrix(m, inv)
InvertSingularMatrix(m, inv)
Matrix m, inv;
Matrix m, inv;
{
{
        register int i, j, k;
        register int i, j, k;
        BitVector mask;
        BitVector mask;
        Matrix sm;
        Matrix sm;
        double det, maxdet;
        double det, maxdet;
        int mi = -1, mj = -1, mk = -1;
        int mi = -1, mj = -1, mk = -1;
 
 
        maxdet = 0.0;
        maxdet = 0.0;
        for(i = 0; i < NROWS(m); i++) {
        for(i = 0; i < NROWS(m); i++) {
                printf("r&c%d, ", i);
                printf("r&c%d, ", i);
                SET_BIT_VECTOR(mask);
                SET_BIT_VECTOR(mask);
                BIT_CLEAR(i, mask);
                BIT_CLEAR(i, mask);
                sm = SliceMatrix(m, mask, mask);
                sm = SliceMatrix(m, mask, mask);
                det = InvertMatrix(sm, sm);
                det = InvertMatrix(sm, sm);
                if(det == 0.0)
                if(det == 0.0)
                        printf("det still 0\n");
                        printf("det still 0\n");
                else {
                else {
                        printf("det = %g\n", det);
                        printf("det = %g\n", det);
                }
                }
                if(_abs(det) > _abs(maxdet))
                if(_abs(det) > _abs(maxdet))
                        maxdet = det, mi = i;
                        maxdet = det, mi = i;
                FreeMatrix(sm);
                FreeMatrix(sm);
        }
        }
        printf("\n");
        printf("\n");
 
 
        printf("maxdet=%g when row %d left out\n", maxdet, mi);
        printf("maxdet=%g when row %d left out\n", maxdet, mi);
        if(fabs(maxdet) > 1.0e-6) {
        if(fabs(maxdet) > 1.0e-6) {
                goto found;
                goto found;
        }
        }
 
 
        maxdet = 0.0;
        maxdet = 0.0;
        for(i = 0; i < NROWS(m); i++) {
        for(i = 0; i < NROWS(m); i++) {
             for(j = i+1; j < NROWS(m); j++) {
             for(j = i+1; j < NROWS(m); j++) {
                /* printf("leaving out row&col %d&%d, ", i, j); */
                /* printf("leaving out row&col %d&%d, ", i, j); */
                SET_BIT_VECTOR(mask);
                SET_BIT_VECTOR(mask);
                BIT_CLEAR(i, mask);
                BIT_CLEAR(i, mask);
                BIT_CLEAR(j, mask);
                BIT_CLEAR(j, mask);
                sm = SliceMatrix(m, mask, mask);
                sm = SliceMatrix(m, mask, mask);
                det = InvertMatrix(sm, sm);
                det = InvertMatrix(sm, sm);
                /*
                /*
                if(det == 0.0)
                if(det == 0.0)
                        printf("det still 0\n");
                        printf("det still 0\n");
                else {
                else {
                        printf("det = %g\n", det);
                        printf("det = %g\n", det);
                }
                }
                */
                */
                if(abs(det) > abs(maxdet))
                if(abs(det) > abs(maxdet))
                        maxdet = det, mi = i, mj = j;
                        maxdet = det, mi = i, mj = j;
                FreeMatrix(sm);
                FreeMatrix(sm);
            }
            }
        }
        }
 
 
        printf("maxdet=%g when rows %d,%d left out\n", maxdet, mi, mj);
        printf("maxdet=%g when rows %d,%d left out\n", maxdet, mi, mj);
        if(_abs(maxdet) > 1.0e-6) {
        if(_abs(maxdet) > 1.0e-6) {
                goto found;
                goto found;
        }
        }
 
 
        maxdet = 0.0;
        maxdet = 0.0;
        for(i = 0; i < NROWS(m); i++) {
        for(i = 0; i < NROWS(m); i++) {
           for(j = i+1; j < NROWS(m); j++) {
           for(j = i+1; j < NROWS(m); j++) {
              for(k = j+1; k < NROWS(m); k++) {
              for(k = j+1; k < NROWS(m); k++) {
                /* printf("leaving out row&col %d,%d&%d, ", i, j, k); */
                /* printf("leaving out row&col %d,%d&%d, ", i, j, k); */
                SET_BIT_VECTOR(mask);
                SET_BIT_VECTOR(mask);
                BIT_CLEAR(i, mask);
                BIT_CLEAR(i, mask);
                BIT_CLEAR(j, mask);
                BIT_CLEAR(j, mask);
                BIT_CLEAR(k, mask);
                BIT_CLEAR(k, mask);
                sm = SliceMatrix(m, mask, mask);
                sm = SliceMatrix(m, mask, mask);
                det = InvertMatrix(sm, sm);
                det = InvertMatrix(sm, sm);
                /*
                /*
                if(det == 0.0)
                if(det == 0.0)
                        printf("det still 0\n");
                        printf("det still 0\n");
                else {
                else {
                        printf("det = %g\n", det);
                        printf("det = %g\n", det);
                }
                }
                */
                */
                if(_abs(det) > _abs(maxdet))
                if(_abs(det) > _abs(maxdet))
                        maxdet = det, mi = i, mj = j, mk = k;
                        maxdet = det, mi = i, mj = j, mk = k;
                FreeMatrix(sm);
                FreeMatrix(sm);
              }
              }
           }
           }
        }
        }
        printf("maxdet=%g when rows %d,%d&%d left out\n", maxdet, mi, mj, mk);
        printf("maxdet=%g when rows %d,%d&%d left out\n", maxdet, mi, mj, mk);
        if(mk == -1)
        if(mk == -1)
                return 0.0;
                return 0.0;
 
 
found:
found:
 
 
        SET_BIT_VECTOR(mask);
        SET_BIT_VECTOR(mask);
        if(mi >= 0) BIT_CLEAR(mi, mask);
        if(mi >= 0) BIT_CLEAR(mi, mask);
        if(mj >= 0) BIT_CLEAR(mj, mask);
        if(mj >= 0) BIT_CLEAR(mj, mask);
        if(mk >= 0) BIT_CLEAR(mk, mask);
        if(mk >= 0) BIT_CLEAR(mk, mask);
        sm = SliceMatrix(m, mask, mask);
        sm = SliceMatrix(m, mask, mask);
        det = InvertMatrix(sm, sm);
        det = InvertMatrix(sm, sm);
        DeSliceMatrix(sm, 0.0, mask, mask, inv);
        DeSliceMatrix(sm, 0.0, mask, mask, inv);
        FreeMatrix(sm);
        FreeMatrix(sm);
        PrintMatrix(inv, "desliced:\n");
        PrintMatrix(inv, "desliced:\n");
        return det;
        return det;
}
}
 
 
/* You can fairly confidently ignore the compiler warnings after here */
/* You can fairly confidently ignore the compiler warnings after here */
 
 
void
void
PrintVector(v, s,a1,a2,a3,a4,a5,a6,a7,a8)
PrintVector(v, s,a1,a2,a3,a4,a5,a6,a7,a8)
register Vector v;
register Vector v;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
{
{
        register int i;
        register int i;
        printf(s,a1,a2,a3,a4,a5,a6,a7,a8);
        printf(s,a1,a2,a3,a4,a5,a6,a7,a8);
 
 
        for(i = 0; i < NROWS(v); i++) printf(" %8.4f", v[i]);
        for(i = 0; i < NROWS(v); i++) printf(" %8.4f", v[i]);
        printf("\n");
        printf("\n");
}
}
 
 
void
void
PrintMatrix(m, s,a1,a2,a3,a4,a5,a6,a7,a8)
PrintMatrix(m, s,a1,a2,a3,a4,a5,a6,a7,a8)
register Matrix m;
register Matrix m;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
{
{
        register int i, j;
        register int i, j;
        printf(s,a1,a2,a3,a4,a5,a6,a7,a8);
        printf(s,a1,a2,a3,a4,a5,a6,a7,a8);
        for(i = 0; i < NROWS(m);  i++) {
        for(i = 0; i < NROWS(m);  i++) {
                for(j = 0; j < NCOLS(m); j++)
                for(j = 0; j < NCOLS(m); j++)
                        printf(" %8.4f", m[i][j]);
                        printf(" %8.4f", m[i][j]);
                printf("\n");
                printf("\n");
        }
        }
}
}
 
 
void
void
PrintArray(a, s,a1,a2,a3,a4,a5,a6,a7,a8)
PrintArray(a, s,a1,a2,a3,a4,a5,a6,a7,a8)
Array a;
Array a;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
char *s; int a1,a2,a3,a4,a5,a6,a7,a8;
{
{
        switch(NDIMS(a)) {
        switch(NDIMS(a)) {
        case 1: PrintVector((Vector) a, s,a1,a2,a3,a4,a5,a6,a7,a8); break;
        case 1: PrintVector((Vector) a, s,a1,a2,a3,a4,a5,a6,a7,a8); break;
        case 2: PrintMatrix((Matrix) a, s,a1,a2,a3,a4,a5,a6,a7,a8); break;
        case 2: PrintMatrix((Matrix) a, s,a1,a2,a3,a4,a5,a6,a7,a8); break;
        default: error("PrintArray");
        default: error("PrintArray");
        }
        }
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.