📄 matrix_double.c
字号:
/* * ============================================================================= * ALADDIN Version 1.0 : * matrix_double.c : Functions for Matrices of data type double * * Copyright (C) 1995 by Mark Austin, Xiaoguang Chen, and Wane-Jang Lin * Institute for Systems Research, * University of Maryland, College Park, MD 20742 * * This software is provided "as is" without express or implied warranty. * Permission is granted to use this software for any on any computer system * and to redistribute it freely, subject to the following restrictions: * * 1. The authors are not responsible for the consequences of use of * this software, even if they arise from defects in the software. * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. * 4. This notice is to remain intact. * * Written by: Mark Austin July 1992 - October 1993 * ============================================================================= */#include <stdio.h>#include <math.h>#include <string.h>#include "units.h"#include "matrix.h"#include "defs.h"/*#define DEBUG *//* ******************************************************** Function: dMatrixPrint Function to print a matrix (nxm) of type double Usage: dMatrixPrint(array_name, array, n, m); where array_name: name of the array. **array: pointer to a pointer to an array. n: number of rows. m: number of columns. NCOL: number of columns printed across page. ******************** ********************************** */#ifdef __STDC__void dMatrixPrint(char *array_name, double **array, int n, int m)#elsevoid dMatrixPrint(array_name, array, n, m)char *array_name;double **array;int n,m;#endif{int i,j,k=0;int index, max_cr;int mcr,l;#define NCOL 4 max_cr = (m%NCOL==0) ? (m/NCOL)-1 : m/NCOL; if (m<=NCOL) { mcr = m; max_cr = 0; } else mcr = NCOL; for (index=0;index<=max_cr;index++) { printf ("\nMatrix \"%s\"\n\n",array_name); printf ("row/col "); for(i=(index*NCOL),l=0;i<=(index*mcr)+NCOL-1;i++,l++) { if (((index*mcr)+l)>=m) break; printf("%3d ",i+1); } printf("\n"); k = 0; for (i=1;i<=n;i++) { printf(" %3d ",++k); for (j=(index*NCOL)+1,l=0;j<=((index*NCOL)+NCOL);j++,l++) { if (((index*NCOL)+l)>=m) break; printf(" %12.5e",array[i-1][j-1]); } printf("\n"); } }}/* * ================= * Matrix Operations * ================= */#ifdef __STDC__double **dMatrixMult(double **m1, int m1_row, int m1_colum, double **m2 ,int m2_row, int m2_colum )#elsedouble **dMatrixMult(m1, m1_row, m1_colum, m2 ,m2_row, m2_colum )double **m1;double **m2;int m1_colum, m1_row;int m2_colum, m2_row;#endif{double **m3;int i,j,k;DIMENSIONS d1, d2;#ifdef DEBUG printf("*** In dMatrixMult()\n");#endif /* [a] : Check for Compatible Matrices */ if(m1_colum != m2_row) { printf("FATAL ERROR >> Execution halted in dMatrixMult()\n"); printf("FATAL ERROR >> Problem : m1_colum = %4d\n", m1_colum); printf(" : m2->row = %4d \n", m2_row); FatalError("In dMatrixMult() : Inconsistent Dimensions",(char *)NULL); } /* [b] : Multiply Matrices */ m3 = MatrixAllocIndirectDouble(m1_row, m2_colum); for(i = 1; i <= m1_row; i++) { for(j = 1; j <= m2_colum; j++) { for(k = 1; k <= m1_colum; k++) { m3[i-1][j-1] += m1[i-1][k-1]*m2[k-1][j-1]; } } }#ifdef DEBUG printf("*** leaving dMatrixMult()\n");#endif return (m3);}#ifdef __STDC__double **dMatrixMultRep(double **m3, double **m1, int m1_row, int m1_colum, double **m2, int m2_row, int m2_colum )#elsedouble **dMatrixMultRep(m3, m1, m1_row, m1_colum, m2, m2_row, m2_colum )double **m3;double **m1;double **m2;int m1_colum, m1_row;int m2_colum, m2_row;#endif{int i,j,k;DIMENSIONS d1, d2;#ifdef DEBUG printf("*** In dMatrixMultRep()\n");#endif /* [0] : Initialize m3 */ for(i = 1; i <= m1_row; i++) { for(j = 1; j <= m2_colum; j++) { m3[i-1][j-1] = 0.0; } } /* [a] : Check for Compatible Matrices */ if(m1_colum != m2_row) { printf("FATAL ERROR >> Execution halted in dMatrixMultRep()\n"); printf("FATAL ERROR >> Problem : m1_colum = %4d\n", m1_colum); printf(" : m2->row = %4d \n", m2_row); FatalError("In dMatrixMult() : Inconsistent Dimensions",(char *)NULL); } /* [b] : Multiply Matrices */ for(i = 1; i <= m1_row; i++) { for(j = 1; j <= m2_colum; j++) { for(k = 1; k <= m1_colum; k++) { m3[i-1][j-1] += m1[i-1][k-1]*m2[k-1][j-1]; } } }#ifdef DEBUG printf("*** leaving dMatrixMultRep()\n");#endif return (m3);}#ifdef __STDC__double **dMatrixTranspose(double **m1, int iNoRows, int iNoColumns)#elsedouble **dMatrixTranspose(m1, iNoRows, iNoColumns)double **m1;int iNoRows, iNoColumns;#endif{double **m2;int i,j,k;#ifdef DEBUG printf("*** In dMatrixTranspose()\n");#endif /* [a] : Transpose Matrix */ m2 = MatrixAllocIndirectDouble(iNoColumns, iNoRows); for(i = 1; i <= iNoRows; i++){ for(j = 1; j <= iNoColumns; j++) { m2[j-1][i-1] = m1[i-1][j-1]; } }#ifdef DEBUG printf("*** Leave dMatrixTranspose()\n");#endif return (m2);}#ifdef __STDC__double **dMatrixCopy(double **m1, int iNoRows, int iNoColumns)#elsedouble **dMatrixCopy(m1, iNoRows, iNoColumns)double **m1;int iNoRows, iNoColumns;#endif{double **m2;int i,j,k;#ifdef DEBUG printf("*** In dMatrixCopy()\n");#endif m2 = MatrixAllocIndirectDouble(iNoRows, iNoColumns); for(i = 1; i <= iNoRows; i++) { for(j = 1; j <= iNoColumns; j++) { m2[i-1][j-1] = m1[i-1][j-1]; } }#ifdef DEBUG printf("*** Leave dMatrixCopy()\n");#endif return (m2);}#ifdef __STDC__double **dMatrixCopyRep(double **m2, double **m1, int iNoRows, int iNoColumns)#elsedouble **dMatrixCopyRep(m2, m1, iNoRows, iNoColumns)double **m2;double **m1;int iNoRows, iNoColumns;#endif{int i,j,k;#ifdef DEBUG printf("*** In dMatrixCopyRep()\n");#endif for(i = 1; i <= iNoRows; i++) { for(j = 1; j <= iNoColumns; j++) { m2[i-1][j-1] = m1[i-1][j-1]; } }#ifdef DEBUG printf("*** Leave dMatrixCopyRep()\n");#endif return (m2);}/* ================================================================ *//* Vector cross product a = b x c; *//* output : a = a[n1][1]; *//* input : b = b[n2][1] or b[1][n2] *//* : c = c[n3][1] or c[1][n3] *//* : n1,n2,n3 = 1, 2, 3 *//* ================================================================ */#ifdef __STDC__double **dVmatrixCrossProduct(double **a, double **b, int b_rows, int b_cols, double **c, int c_rows, int c_cols)#elsedouble **dVmatrixCrossProduct(a, b, b_rows, b_cols, c, c_rows, c_cols)int b_rows, b_cols;int c_rows, c_cols;double **a, **b, **c;#endif{double b1, b2,b3;double c1, c2,c3;#ifdef DEBUG printf(" enter dVmatrixCrossProduct(): \n");#endif /* Check that matrix is either a 3x1 (or 1x3) column (or row) vector */ if((b_rows != 1) && (b_cols != 1) || (b_rows != 3) && (b_cols != 3) ) { FatalError("In dVmatrixCrossProduct() : Matrix b is not a 1x3 row (or 3x1 column) vector",(char *)NULL); } if((c_rows != 1) && (c_cols != 1) || (c_rows != 3) && (c_cols != 3)) { FatalError("In dVmatrixCrossProduct() : Matrix c is not a 1x3 row (or 3x1 column) vector",(char *)NULL); } /* calculate the vector cross product */ if(b_rows == 1) { b1 = b[0][0]; b2 = b[0][1]; b3 = b[0][2]; } else if(b_cols == 1) { b1 = b[0][0]; b2 = b[1][0]; b3 = b[2][0]; } if(c_rows == 1) { c1 = c[0][0]; c2 = c[0][1]; c3 = c[0][2]; } else if(c_cols == 1) { c1 = c[0][0]; c2 = c[1][0]; c3 = c[2][0]; } a[0][0] = b2*c3 - c2*b3; a[1][0] = b3*c1 - c3*b1; a[2][0] = b1*c2 - c1*b2;#ifdef DEBUG printf(" leaving dVmatrixCrossProduct(): \n");#endif return(a);}/* ================================================================ *//* Vector inner (dot) product a = b . c; *//* output : a = a number ; *//* input : b = b[n2][1] or b[1][n2] *//* : c = c[n3][1] or c[1][n3] *//* ================================================================ */#ifdef __STDC__double dVmatrixInnerProduct(double **b, int b_rows, int b_cols, double **c, int c_rows, int c_cols)#elsedouble dVmatrixInnerProduct(b, b_rows, b_cols, c, c_rows, c_cols)int b_rows, b_cols;int c_rows, c_cols;double **b, **c;#endif{double sum = 0.0;double b1, b2,b3;double c1, c2,c3;int i, j, k;#ifdef DEBUG printf(" enter dVmatrixInnerProduct(): \n");#endif /* Check that matrix is either a column (or row) vector */ if((b_rows != 1) && (b_cols != 1) ) { FatalError("In dVmatrixInnerProduct() : Matrix b is not a row (or column) vector",(char *)NULL); } if((c_rows != 1) && (c_cols != 1) ) { FatalError("In dVmatrixInnerProduct() : Matrix c is not a row (or column) vector",(char *)NULL); } /* Check vectors b and c have same dimensions */ if((c_rows == 1) && ((c_cols != b_rows) &&(c_cols != b_cols)) ) { FatalError("In dVmatrixInnerProduct() : Vectors b and c do not have same dimensions",(char *)NULL); } if((c_cols == 1) && ((c_rows != b_rows) &&(c_rows != b_cols)) ) { FatalError("In dVmatrixInnerProduct() : Vectors b and c do not have same dimensions",(char *)NULL); } /* calculate the vector inner (dot) product */ if(b_rows == 1) { if(c_rows == 1) { for (i = 1; i <= b_cols; i++) sum += b[0][i-1]*c[0][i-1]; } else if(c_cols == 1) { for (i = 1; i <= b_cols; i++) sum += b[0][i-1]*c[i-1][0]; } } else if(b_cols == 1) { if(c_rows == 1) { for (i = 1; i <= b_rows; i++) sum += b[i-1][0]*c[0][i-1]; } else if(c_cols == 1) { for (i = 1; i <= b_rows; i++) { sum += b[i-1][0]*c[i-1][0]; } } }#ifdef DEBUG printf(" leaving dVmatrixInnerProduct(): \n");#endif return(sum);}#ifdef __STDC__double dVmatrixL2Norm(double **m, int iNoRows, int iNoCols)#elsedouble dVmatrixL2Norm(m, iNoRows, iNoCols)double **m;int iNoRows, iNoCols;#endif{double sum = 0.0;int i;#ifdef DEBUG printf("*** Enter dVmatrixL2Norm() \n");#endif /* Compute L2 Norm for column/row vector */ if(iNoRows == 1) { for(i = 1; i <= iNoCols; i++) sum = sum + (m[0][i-1]*m[0][i-1]); } else if (iNoCols == 1) { for(i = 1; i <= iNoRows; i++) sum = sum + (m[i-1][0]*m[i-1][0]); } sum = sqrt(sum);#ifdef DEBUG printf("*** Leaving dVmatrixL2Norm() \n");#endif return(sum);}#ifdef __STDC__double dMatrixDet(double **m, int iNoRows, int iNoCols)#elsedouble dMatrixDet(m, iNoRows, iNoCols)double **m;int iNoRows, iNoCols;#endif{double **temp_m;double value;int i,j;int ii,ij,im,in; if( iNoRows!=iNoCols ) FatalError("In dMatrixDet() : matrix is not a square matrix",(char *)NULL); if( iNoRows==1 ) { value = m[0][0]; return( value ); } if( iNoRows==2 ) { value = m[0][0]*m[1][1]-m[0][1]*m[1][0]; return( value ); } if( iNoRows==3 ) { value = m[0][0]*m[1][1]*m[2][2]+m[0][1]*m[1][2]*m[2][0]+m[0][2]*m[2][1]*m[1][0] -m[0][2]*m[1][1]*m[2][0]-m[0][0]*m[2][1]*m[1][2]-m[0][1]*m[1][0]*m[2][2]; return( value ); } value = 0.0; for( i=0 ; i<iNoRows ; i++ ) { temp_m = MatrixAllocIndirectDouble( iNoRows-1, iNoCols-1 ); for( ii=0, im=1 ; ii<(iNoRows-1) ; ii++, im++ ) { for( ij=0, in=0 ; ij<(iNoRows-1) ; ij++, in++ ) { if( in==i ) in++; temp_m[ii][ij] = m[im][in]; } } value += pow(-1.0,i)*m[0][i]*dMatrixDet( temp_m, iNoRows-1, iNoRows-1 ); MatrixFreeIndirectDouble( temp_m, iNoRows-1 ); } return(value);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -