
	A Kalman filter C++ class, V 1.2

		This class defines a Kalman filter object that is
	designed to use any type of dynamical system, defined as a
	VectorDynamics object.  This information is passed to the filter
	along with the size of the system vector and of the observation
	vector as part of the constructor:

		Kalman filter( n, m, model );

	
	defines a filter, called filter, with n points in the system
	vector, and m points in the observation vector.  "model" is
	an object derived from VectorDynamics, that defines the actual
	physical model or method to be used.


	The public methods are described below:


	  void sys_noise(Matrix& qs);	sets the filter system noise level

	  void obs_noise(Matrix& ro);	sets the filter observation noise level

	  void obs_sys(Matrix& hin);	sets the observation matrix (generally
					called H in the literature).  This can
					be called whenever the observation
					matrix is changed.

	  void initial(Vector& ic);	sets the value of the state vector
					to whatever 'ic' is set too.  This
					is generally for setting the initial
					condition.

	  Matrix& k;			points to the current gain matrix

	  Matrix& p;			points to the current covariance matrix

	  Kalman& operator++();		do a single time step of the system vector
					and the covariance matrix, and recalculate
					the new filter gain.  This is the normal
					way to increment the filter.  Typically
					this will be done repeatedly until there
					is a new observation.

	  friend Vector& operator<<(Vector&, Kalman&);

					This operator tells the filter to return
					the current state of the filter.  This
					is used any time the user wants output
					from the filter.


	  friend Kalman& operator<<(Kalman&, Vector&);

					This operator tells the filter that there
					is a new observation vector.


	The following 5 methods are not for normal use by the user, public
	access is provided only for testing purposes.


	  void step_x(int steps = 1);   do "steps" (default = 1) time increments
					of the system vector with the current data

	  void step_p(int steps = 1);	do "steps" (default = 1) time increments
					of the covariance matrix with the current
					data

          void set_gain();		sets the gain based upon the current
					value of the covariance

	  void update_x();		update the state vector given the
					current data.

	  void update_p();		update the covariance matrix given the
					current data




	Operators can be combined, but note that precedence rules may
	not give what you expect, so use paretheses to be sure, e.g.:


	To give the filter new data, and then output the state:

			filter << z;
			u << filter;

	or,
			u << (filter << z);

	but because of the precedence rules, the following:

			u << filter << z;

	will output the filter state FIRST, and THEN give the filter new
	observations.  This is perfectly legal, but probably not what you
	wanted.

	The same caution applies to the time increment operator (++) as well.



	I have provided a test program, that runs a physical model that
	is the 1-D 1-direction wave (also called the linear convection)
 	equation:


        	du/dt + c du/dx = 0


	The observations consist of data from the analytic solution at
	the grid points defined in the array: oindex
	One can experiment with the effectiveness of the filter by putting
	different values in oindex (any number of points -- up to the
	number of gridpoints in the model -- can be used, their order does
	not matter).  The system and observation noise levels are fixed
	for demonstration purposes, they could have differing values.
	Also for demonstration purposes, the observed values are exactly
	the analytic solution, adding random noise would provide a more
	realistic simulation.

	The test program uses Unix style command line switches which can
	be mixed in any order and can be concatonated into a single command.
	So that,

		kaltest -v -h0.05

	is the same as:
	
		kaltest -h0.05v

	Typing:
		 kaltest --

	will give a summary of the possible switch settings.


	The program output goes to either a file that is named after the
	command line switches, or to standard output:


		kaltest -v outfile		sends output to outfile

		kaltest outfile			does the same

		kaltest > outfile		goes to outfile because of
						redirection of STDOUT

		kaltest -v			goes to STDOUT

		kaltest				also goes to STDOUT




	The test program, with the default settings, runs in about 23 seconds
	on my MIPS 3230 workstation.  The code SHOULD port to MSDOS fairly
	easily although I haven't tried the latest version on my PC yet, on
	my workstation I am using the AT&T V2.1 C++ compiler, and GNU C++ V2.4.2.


	The test problem provided estimates the state of a system that is
	controlled by the 1-D 1 direction wave equation:

        du/dt + c du/dx = 0


	There are 3 observation in the domain.

	The output file contains three columns of numbers,
	
	the filter output	the actual field	the error covariance
							(the diagonal of P)

	the columns are broken with a blank line between each time step.

	With the default values, the final values are:


	0.0166782       9.38749e-06     0.01985
	0.212781        0.1951  	0.0207852
	0.399705        0.382692        0.0217012
	0.570064        0.555578        0.0220925
	0.717358        0.707113        0.0188156
	0.836255        0.831475        0.00972488
	0.926261        0.923883        0.00913587
	0.981879        0.980787        0.0107426
	0.999377        1	        0.0122494
	0.978015        0.980783        0.0136142
	0.919057        0.923876        0.0148826
	0.824603        0.831464        0.0160753
	0.697627        0.7071  	0.0171751
	0.54289 	0.555562        0.0182094
	0.368106        0.382675        0.0189308
	0.181383        0.195081        0.0168032
	-0.00809865     -9.47491e-06    0.0091819
	-0.201093       -0.1951 	0.00892809
	-0.388802       -0.382692       0.0105573
	-0.56184        -0.555578       0.0120252
	-0.712843       -0.707114       0.0132718
	-0.835733       -0.831475       0.0129451
	-0.925932       -0.923883       0.00803602
	-0.981683       -0.980787       0.00843097
	-0.999943       -1      	0.0101222
	-0.979256       -0.980783       0.0116369
	-0.920258       -0.923876       0.0130145
	-0.825418       -0.831464       0.0142952
	-0.698646       -0.7071 	0.015504
	-0.544881       -0.555562       0.0166567
	-0.369901       -0.382675       0.0177629
	-0.180229       -0.195081       0.0188314





	I used my own Matrix/Vector classes for this code but it should be
	easy to substitute another set as long as they provide the usual
	access operators ([][] and []) and the usual linear algebra operations
	(including inverse).  If another Matrix/Vector class is used you can
	eliminate the following in the link step:

	matrix.o vector.o barray.o barray2d.o lumatrix.o invm.o error.o

	and replace them with your own modules.


	This code is provided as is, for general experimentation and comment.



   Everett (Skip) Carter              Phone:  408-656-3318 FAX: 408-656-2712
   Naval Postgraduate School          INTERNET: skip@taygeta.oc.nps.navy.mil
   Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
   Monterey, CA. 93943                TELEMAIL: s.carter/omnet

