00001 /* $Id: matinv.c,v 1.1.1.1 2004/12/23 04:05:13 ellson Exp $ $Revision: 1.1.1.1 $ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /********************************************************** 00005 * This software is part of the graphviz package * 00006 * http://www.graphviz.org/ * 00007 * * 00008 * Copyright (c) 1994-2004 AT&T Corp. * 00009 * and is licensed under the * 00010 * Common Public License, Version 1.0 * 00011 * by AT&T Corp. * 00012 * * 00013 * Information and Software Systems Research * 00014 * AT&T Research, Florham Park NJ * 00015 **********************************************************/ 00016 00017 /* 00018 * This code was (mostly) written by Ken Turkowski, who said: 00019 * 00020 * Oh, that. I wrote it in college the first time. It's open source - I think I 00021 * posted it after seeing so many people solve equations by inverting matrices 00022 * by computing minors naïvely. 00023 * -Ken 00024 * 00025 * The views represented here are mine and are not necessarily shared by 00026 * my employer. 00027 Ken Turkowski turk@apple.com 00028 Immersive Media Technologist http://www.worldserver.com/turk/ 00029 Apple Computer, Inc. 00030 1 Infinite Loop, MS 302-3VR 00031 Cupertino, CA 95014 00032 */ 00033 00034 /* Matinv() inverts the matrix A using LU decomposition. Arguments: 00035 * A - the (n x n) matrix to be inverted 00036 * Ainv - the (n x n) inverted matrix 00037 * n - the order of the matrices A and Ainv 00038 */ 00039 00040 #if _PACKAGE_ast 00041 #include <ast.h> 00042 #else 00043 #endif 00044 #include <stdlib.h> 00045 #include <render.h> 00046 extern int lu_decompose(double **a, int n); 00047 extern void lu_solve(double *x, double *b, int n); 00048 00049 int matinv(double **A, double **Ainv, int n) 00050 { 00051 register int i, j; 00052 double *b, temp; 00053 00054 /* Decompose matrix into L and U triangular matrices */ 00055 if (lu_decompose(A, n) == 0) 00056 return (0); /* Singular */ 00057 00058 /* Invert matrix by solving n simultaneous equations n times */ 00059 b = N_NEW(n, double); 00060 for (i = 0; i < n; i++) { 00061 for (j = 0; j < n; j++) 00062 b[j] = 0.0; 00063 b[i] = 1.0; 00064 lu_solve(Ainv[i], b, n); /* Into a row of Ainv: fix later */ 00065 } 00066 free(b); 00067 00068 /* Transpose matrix */ 00069 for (i = 0; i < n; i++) { 00070 for (j = 0; j < i; j++) { 00071 temp = Ainv[i][j]; 00072 Ainv[i][j] = Ainv[j][i]; 00073 Ainv[j][i] = temp; 00074 } 00075 } 00076 00077 return (1); 00078 }