⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 old-matlib.cpp

📁 UAV导航及控制,是老外编写的一个源代码开放程序
💻 CPP
字号:
/* -*- indent-tabs-mode:T; c-basic-offset:8; tab-width:8; -*- vi: set ts=8: * $Id: old-matlib.cpp,v 2.0 2002/09/22 02:07:32 tramm Exp $ * *	This is the source file for the matrix and math utiltiy *	library. * *	Author: Aaron Kahn, Suresh Kannan, Eric Johnson *	copyright 2001 *	Portions (c) Trammell Hudson */#include <stdio.h>#include <cmath>#include <string.h>#include "old-matlib.h"#include "old-vect.h"#include <mat/Conversions.h>#include "macros.h"namespace matlib{/* * This will zero out the matrix A * zeros(n,m) = A */voidMinit(	double			A[MAXSIZE][MAXSIZE],	int			n,	int			m){	for( int i=0 ; i<n ; ++i )		for( int j=0 ; j<m ; ++j )			A[i][j] = 0.0;}/* * This will generate an identity matrix I * eye(n) = A(n,n) */voideye(	double			I[MAXSIZE][MAXSIZE],	int			n){	Minit(I,n,n);	for( int i=0 ; i<n ; ++i )		I[i][i] = 1.0;}/* * This will multiply scalar value s will all elements of matrix A(m,n) * placing result into matrix B(m,n) * s.*A(m,n) = B(m,n) * * Ok for A == B. */voidsMmult(	double			s,	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	int			m,	int			n){	for( int i=0 ; i<m ;  ++i )		for( int j=0 ; j<n ; ++j )			B[i][j] = s*A[i][j];}/* * This will multiply matrix A and matrix B return in matrix C * A(m,n)*B(n,p) = C(m,p) */voidMMmult(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	double			C[MAXSIZE][MAXSIZE],	int			m,	int			n,	int			p){	for( int i=0 ; i<m ; ++i )	{		for( int j=0 ; j<p ; ++j )		{			double			s = 0.0;			for( int k=0 ; k<n ; ++k )				s += A[i][k] * B[k][j];			C[i][j] = s;		}	}}/* * This will multiply matrix A and vector b return in vector b * A(m,n)*b(n,1) = c(m,1) */voidMVmult(	double			A[MAXSIZE][MAXSIZE],	const double *		b,	double *		c,	int			m,	int			n){	for( int j=0 ; j<m ; ++j )	{		double			s = 0.0;		for( int i=0 ; i<n ; ++i )			s += A[j][i] * b[i];		c[j] = s;	}}/* * This will multiply vector a and matrix B return in vector c * c(1,n) = a(1,m)*B(m,n) */voidVMmult(	double			a[MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	double			c[MAXSIZE],	int			m,	int			n){	for( int i=0 ;  i<n ;  ++n)	{		double			s = 0.0;		for( int j=0 ; j<m ; ++m )			s += a[j]*B[j][i];		c[i] = s;	}}/* * This will traspose a matrix/vector A return in matrix/vector B * A(m,n) = B(n,m) */voidtranspose(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	int			m,	int			n){	for( int i=0 ; i<m ; ++i )		for( int j=0 ; j<n ; ++j )			B[j][i] = A[i][j];}voidMMcopy(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	int			m,	int			n){	for( int i=0 ; i<m ; i++ )		for( int j=0 ; j<n ; j++ )			B[i][j] = A[i][j];}/* * This will add matrix A and matrix B return in matrix C * C(n,m) = A(n,m) + B(n,m) * * Ok for C == A and C == B */voidMMadd(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	double			C[MAXSIZE][MAXSIZE],	int			m,	int			n){	for( int i=0 ; i<n ; ++i )		for( int j=0 ; j<m ; ++j )			C[i][j] = A[i][j] + B[i][j];}/* * This will subtract matrix A from matrix B placing result in matrix C * C(n,m) = A(n,m) - B(n,m) * * Ok for C == A and C == B. */voidMMsub(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	double			C[MAXSIZE][MAXSIZE],	int			m,	int			n){	for( int i=0 ;  i<n ;  ++i )		for( int j=0 ; j<m ; ++j )			C[i][j] = A[i][j] - B[i][j];}/* * This will perform LU decomp on matrix A return matrix L, matrix U * lu(A(n,n)) => L(n,n) and U(n,n) * * the LU decomp algorithm for no pivoting * for k=1:n-1 *   for i=k+1:n *      A(i,k)=A(i,k)/A(k,k); *      for j=k+1:n *         A(i,j)=A(i,j)-A(i,k)*A(k,j); *      end *   end * end */voidLU(	double			A[MAXSIZE][MAXSIZE],	double			L[MAXSIZE][MAXSIZE],	double			U[MAXSIZE][MAXSIZE],	int			n){	double			Acopy[MAXSIZE][MAXSIZE];	/* copy A matrix */	for( int i=0 ;  i<n ; ++i )		for( int j=0 ; j<n ;  ++j )			Acopy[i][j] = A[i][j];	for( int k=0 ; k<n-1 ; ++k )	{		for( int i=k+1 ; i<n ; ++i )		{			Acopy[i][k] = Acopy[i][k] / Acopy[k][k];			for( int j=k+1 ; j<n ; ++j )			{				Acopy[i][j] -= Acopy[i][k] * Acopy[k][j];			}		}	}		/* make an identity matrix */	eye( L, n );		/* separate the L matrix */	for( int j=0 ; j<n-1 ; ++j )		for( int i=j+1 ; i<n ; ++i )			L[i][j] = Acopy[i][j];	/* separate out the U matrix */	Minit( U, n, n );	for( int i=0 ; i<n ; ++i )		for( int j=i ; j<n ; ++j )			U[i][j] = Acopy[i][j];}/* * This will perform the inverse on matrix A return in matrix B * inv(A(n,n)) = B(n,n) */voidinv(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	int			n){	if( n == 1)	{		B[0][0] = 1.0/A[0][0];		return;	}	if( n == 2 )	{		double detA = A[0][0] * A[1][1] - A[0][1] * A[1][0];		B[0][0] =  A[1][1] / detA;		B[0][1] = -A[0][1] / detA;		B[1][0] = -A[1][0] / detA;		B[1][1] =  A[0][0] / detA;		return;	}	// Should we special case n==3?	/*	 * General case.  Do an LU thingy	 */	double			identCol[MAXSIZE];	double			ident[MAXSIZE][MAXSIZE];	double			L[MAXSIZE][MAXSIZE];	double			U[MAXSIZE][MAXSIZE];	double			invUcol[MAXSIZE];	double			invLcol[MAXSIZE];	double			invU[MAXSIZE][MAXSIZE];	double			invL[MAXSIZE][MAXSIZE];	/* construct an identity matrix */	eye( ident, n );		/* perform LU decomp on A */	LU( A, L, U, n );	for( int i=0 ; i<n ; ++i )	{		/* separates the ith column */		Mcol( ident, identCol, i, n );		solveupper( U, identCol, invUcol, n );		solvelower( L, identCol, invLcol, n );		/* places invUcol in ith column of invU */		Vcol( invUcol, invU, i, n );		/* places invLcol in ith column of invL */		Vcol( invLcol, invL, i, n );	}	/* inv(A) = inv(U)*inv(L) */	MMmult( invU, invL, B, n, n, n );}	/* * This will solve A*x = b, where matrix A is upper triangular * A(n,n)*x(n,1) = b(n,1) */voidsolveupper(	double			A[MAXSIZE][MAXSIZE],	double			b[MAXSIZE],	double			x[MAXSIZE],	const int		n){	const int		p = n + 1;	for( int i=1 ; i<=n ; ++i )	{		x[p-i-1] = b[p-i-1];		for( int j=(p+1-i) ; j<=n ; ++j )			x[p-i-1] -= A[p-i-1][j-1]*x[j-1];		x[p-i-1] = x[p-i-1] / A[p-i-1][p-i-1];	}}/* * This will solve A*x = b, where matrix A is lower triangular * A(n,n)*x(n,1) = b(n,1) */voidsolvelower(	double			A[MAXSIZE][MAXSIZE],	double			b[MAXSIZE],	double			x[MAXSIZE],	int			n){	int i,j;	for(i=1; i<=n; ++i)	{		x[i-1] = b[i-1];		for(j=1; j<=i-1; ++j)		{			x[i-1] = x[i-1] - A[i-1][j-1]*x[j-1];		}		x[i-1] = x[i-1]/A[i-1][i-1];	}	}/* This will take column n from matrix A place in vector aA(:,n) = a(m,1)m = number of rows*/void Mcol(double A[MAXSIZE][MAXSIZE], double a[MAXSIZE], int n, int m){	int i;	for(i=0; i<m; ++i)	{		a[i] = A[i][n];	}}/* This will take vector a and place into column of matrix Aa(:,1) = A(m,n)m = number of rows*/void Vcol(double a[MAXSIZE], double A[MAXSIZE][MAXSIZE], int n, int m){	int i;	for(i=0; i<m; ++i)	{		A[i][n] = a[i];	}}/* This will print matrix A to the screenA(n,m)*/void Mprint(double A[MAXSIZE][MAXSIZE], int n, int m){	int i,j;	for(i=0; i<n; ++i)	{		for(j=0; j<m; ++j)		{			printf("%7.5lf ",A[i][j]);		}		printf("\n");	}	printf("\n");}/* This will take matrix A and insert it as a block into matrix B. A(0,0) will beplaced in B(r,c)A(n,m) -> B(>n, >m)(r,c)r=0, c=0 == B(0,0)*/voidblock2M(	double			A[MAXSIZE][MAXSIZE],	double			B[MAXSIZE][MAXSIZE],	int			n,	int			UNUSED( m ),	int			r,	int			c){	for( int i=0 ; i<n ; ++i)		for( int j=0 ; j<n ; ++j)			B[i+r][j+c] = A[i][j];}/* * This will perform a Kalman filter Gain, state, and coveriance * matrix update. * * What is needed is the linear A matrix, state vector, C matrix, * P coveriance matrix, measurement vector, and the R matrix. * *	A(n,n)		Linear model *	P(n,n)		Coveriance matrix *	X(n,1)		State Vector *	C(m,n)		Measurement matrix; m=# of measurements, n=# of states *	R(m,n)		Measurement weight matrix  *	err(m,1)	err = Xmeasurement(m,1) - Xestimate(m,1) vector *	K(n,m)		Kalman Gain matrix */voidkalmanUpdate(	double			/* A */[MAXSIZE][MAXSIZE],	double			P[MAXSIZE][MAXSIZE],	double			X[MAXSIZE],	double			C[MAXSIZE][MAXSIZE],	double			R[MAXSIZE][MAXSIZE],	double			err[MAXSIZE],	double			K[MAXSIZE][MAXSIZE],	int			n,	int			m){	double			E[MAXSIZE][MAXSIZE];	double			T1[MAXSIZE][MAXSIZE];	// temp matrix 1	double			T2[MAXSIZE][MAXSIZE];	// temp matrix 2	double			TV1[MAXSIZE];		// temp vector 1		// perform E = C*P*C' + R 	MMmult(C,P,T1,m,n,n);	transpose(C,T2,m,n);	MMmult(T1,T2,E,m,n,m);	MMadd(E,R,E,m,m);		// perform K = P*C'*inv(E) 	transpose(C,T2,m,n);	MMmult(P,T2,T1,n,n,m);	inv(E,T2,m);	MMmult(T1,T2,K,n,m,m);		// perform x = x + K*( ys - yp )	MVmult(K,err,TV1,n,m);	VVadd(X,TV1,X,n);			// perform P = P - K*C*P 	MMmult(K,C,T1,n,m,n);	MMmult(T1,P,T2,n,n,n);	MMsub( P, P, T2, n, n );}/* * This will compute an orthoginal set of vectors from a given set * of vectors.  The seed set of column vectors are arranged as columns * of a matrix with full column rank.  The output vectors are arranged * as columns of the output matrix with full column rank. * * A(n,[V1 V2 ... Vm]) --> Q(n,[V1 V2 ... Vm]) */voidmgs(	double			A[MAXSIZE][MAXSIZE],	double			Q[MAXSIZE][MAXSIZE],	int			n,	int			m){	double			Tv1[MAXSIZE];	double			Tv2[MAXSIZE];	/* copy A matrix */	for( int i=0 ; i<n ; ++i )		for( int j=0 ; j<m ; ++j )			Q[i][j] = A[i][j];	for( int i=0 ; i<m ; ++i )	{		Mcol(Q, Tv1, i, n);		double			r = norm( Tv1, n );		for( int k=0 ; k<n ; ++k )			Q[k][i] = Q[k][i]/r;		for( int j=i+1 ; j<n ; ++j )		{			Mcol(Q, Tv1, i, n);			Mcol(Q, Tv2, j, n);			double			r = dot( Tv1, Tv2, n );			for( int k=0 ; k<n ; ++k )				Q[k][j] = Q[k][j] - r*Q[k][i];		}	}}/* * This will compute the dependant value from an independant value * based on a linear function.  The linear function is defined by a * set of independant and dependant points (x and y in cartisian plane). * *	RETURNS	dependant value (y on cartisian plane) *	x	independant value (x on cartisian plane) *	Y1	dependant component of point 1 (y on cartisian plane) *	Y2	dependant component of point 2 (y on cartisian plane) *	X1	independant component of point 1 (x on cartisian plane) *	X2	independant component of point 2 (x on cartisian plane) */doubleline(	double			x,	double			Y1,	double			Y2,	double			X1,	double			X2){	double			m = (Y1 - Y2) / (X1 - X2);	return m * (x - X2) + Y2;}		/* * This will produce a hysterious effect on the given value if given the * previous value and the amount of hysterious play.  The use of this * function is to simulate slop in linkage and gear chains. * *	RETURNS		new value with hysterious *	old_val		previous value *	current_val	current value to modify *	play		the magnitude of play to allow (ie: +/- play) */doublehyst(	double			current_val,	double			old_val,	double			play){	if( current_val >= old_val+play )		return current_val - play;	if( current_val <= old_val-play )		return current_val + play;	return old_val;}/** *  Rotate a vector from one coord system to another. */voidrotate3(	double *		v_out,	const double *		v_in,	const double *		theta){	double			cBE[MAXSIZE][MAXSIZE];	eulerDC(		cBE,		theta[0],		theta[1],		theta[2]	);	MVmult(		cBE,		(double*) v_in,		v_out,		3, 3	);}/* *  Rotate a vector by one angle.  This is not thread safe, but * fast for repeatedly rotating about the same angle. */voidrotate2(	double *		v_out,	const double *		v_in,	const double 		theta){	static double		cos_theta = 1.0;	static double		sin_theta = 0.0;	static double		last_theta = 0.0;		if( last_theta != theta )	{		last_theta	= theta;		cos_theta	= cos(theta);		sin_theta	= sin(theta);	}	v_out[0] = v_in[0] * cos_theta + v_in[1] * sin_theta;	v_out[1] = v_in[1] * cos_theta - v_in[0] * sin_theta;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -