Graphviz  2.29.20120524.0446
lib/neatogen/matinv.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 /*
00015  * This code was (mostly) written by Ken Turkowski, who said:
00016  *
00017  * Oh, that. I wrote it in college the first time. It's open source - I think I
00018  * posted it after seeing so many people solve equations by inverting matrices
00019  * by computing minors naïvely.
00020  * -Ken
00021  *
00022  * The views represented here are mine and are not necessarily shared by
00023  * my employer.
00024         Ken Turkowski                   turk@apple.com
00025         Immersive Media Technologist    http://www.worldserver.com/turk/
00026         Apple Computer, Inc.
00027         1 Infinite Loop, MS 302-3VR
00028         Cupertino, CA 95014
00029  */
00030 
00031 /* Matinv() inverts the matrix A using LU decomposition.  Arguments:
00032  *      A    - the (n x n) matrix to be inverted
00033  *      Ainv - the (n x n) inverted matrix
00034  *      n    - the order of the matrices A and Ainv
00035  */
00036 
00037 #if _PACKAGE_ast
00038 #include <ast.h>
00039 #else
00040 #endif
00041 #include <stdlib.h>
00042 #include "render.h"
00043 extern int lu_decompose(double **a, int n);
00044 extern void lu_solve(double *x, double *b, int n);
00045 
00046 int matinv(double **A, double **Ainv, int n)
00047 {
00048     register int i, j;
00049     double *b, temp;
00050 
00051     /* Decompose matrix into L and U triangular matrices */
00052     if (lu_decompose(A, n) == 0)
00053         return (0);             /* Singular */
00054 
00055     /* Invert matrix by solving n simultaneous equations n times */
00056     b = N_NEW(n, double);
00057     for (i = 0; i < n; i++) {
00058         for (j = 0; j < n; j++)
00059             b[j] = 0.0;
00060         b[i] = 1.0;
00061         lu_solve(Ainv[i], b, n);        /* Into a row of Ainv: fix later */
00062     }
00063     free(b);
00064 
00065     /* Transpose matrix */
00066     for (i = 0; i < n; i++) {
00067         for (j = 0; j < i; j++) {
00068             temp = Ainv[i][j];
00069             Ainv[i][j] = Ainv[j][i];
00070             Ainv[j][i] = temp;
00071         }
00072     }
00073 
00074     return (1);
00075 }