matrix.h

Go to the documentation of this file.
00001 /* matrixlib/matrix.h.  Generated by configure.  */
00002 /*
00003  * matrix.h
00004  *
00005  * Programmer(s): Chris Harvey, Michael Paluszek, David Wilson, Lavanya Swetharanyan, Wil Turner
00006  *
00007  * Copyright 1996-2005, Princeton Satellite Systems. All rights reserved.
00008  *
00009  * MatrixLib is a complete solution for implementing one and two dimensional matrices, to solve embedded control
00010  * and simulation problems in the C++ environment. Virtually any engineering application will require the use of
00011  * matrices - this library implements all of the matrix operations supported by MATLAB in an easy to use and highly
00012  * efficient C++ API. It greatly reduces the time and money needed to port algorithms developed in MATLAB to C++.
00013  *
00014  */
00015 
00026 #ifndef __MATRIX__
00027 #define __MATRIX__
00028 
00029 #include <stdio.h>
00030 #include "int_array.h"
00031 #include <string.h>
00032 #include <stdlib.h>
00033 #include <math.h>
00034 
00035 extern "C++"
00036 {
00037 
00039 typedef enum {
00040     ml_no_error = 0,                
00041     ml_bad_index = 1,               
00042     ml_size_mismatch = 2,           
00043     ml_non_invertible_matrix = 3,   
00044     ml_bad_file_pointer = 4,        
00045     ml_bad_range = 5,               
00046     ml_bad_operand = 6,             
00047     ml_bad_string_format = 7,       
00048     ml_invalid_buffer = 8,          
00049     ml_lapack_error = 9             
00050 } ml_error_codes;
00051 
00053 #define ML_FP_TOL 1e-08
00054 #define ML_ARR_INCR 4
00055 
00056 /* FUNCTIONS USING BLAS
00057  *
00058  * ml_matrix::operator*=
00059  * ml_matrix::dot()
00060  * ml_matrix::vmag()
00061  */
00062 
00063 /* FUNCTIONS USING LAPACK
00064  *
00065  * ml_matrix::inv()
00066  * solve_ax_eq_b()
00067  * svd()
00068  */
00069 
00070 /* Use the BLAS if detected. */
00071 /* #undef ML_USE_BLAS */
00072 
00073 /* Use the LAPACK if detected. */
00074 /* #undef ML_USE_LAPACK */
00075 
00076 /* Linux OS */
00077 /* #undef PSS_OS_LINUX */
00078 
00079 /* Mac OS X */
00080 #define PSS_OS_MACOSX 
00081 
00082 /* UNIX OS */
00083 #define PSS_OS_UNIX 
00084 
00086 #define ML_COLUMN_MAJOR 
00087 
00088 #ifdef ML_COLUMN_MAJOR
00089     #define ml_matloc(mat, x, y, rrows, rcols) (mat + (y) * (rrows) + (x))
00090     #define ml_incr_row(ptr, rrows, rcols) (ptr++)
00091     #define ml_incr_col(ptr, rrows, rcols) (ptr+=rrows)
00092     #define ml_major_stride(rrows,rcols) (rrows)
00093     #define ml_minor_stride(rrows,rcols) (rcols)
00094     #define ml_major_length(nrows,ncols) (nrows)
00095     #define ml_minor_length(nrows,ncols) (ncols)
00096 #else
00097     #define ml_matloc(mat, x, y, rrows, rcols) (mat + (x) * (rcols) + (y))
00098     #define ml_incr_row(ptr, rrows, rcols) (ptr+=rcols)
00099     #define ml_incr_col(ptr, rrows, rcols) (ptr++)
00100     #define ml_major_stride(rrows,rcols) (rcols)
00101     #define ml_minor_stride(rrows,rcols) (rrows)
00102     #define ml_major_length(nrows,ncols) (ncols)
00103     #define ml_minor_length(nrows,ncols) (nrows)
00104 #endif
00105 
00107 class ml_matrix
00108 {
00109     public:
00110         #if 0
00111         #pragma mark Construction and I/O
00112         #endif
00113 
00123 
00124         ml_matrix();
00126 
00130         inline ml_matrix(const ml_matrix &m)
00131         {
00132             // straight memcpy of parameter m into the contents of "this"
00133             memcpy(this, &m, sizeof(ml_matrix));
00134             double *t = mat;
00135             if (using_base)
00136             {
00137                 mat = base_mat;
00138             }
00139             else
00140             {
00141                 // need a new mat, since memcpy doesn't copy pointers
00142                 mat = new double[real_cols * real_rows];
00143                 // memcpy the contents of m.mat to this.mat
00144                 memcpy(mat, t, len*sizeof(double));
00145             }
00146             buff = NULL;
00147             buffsize = 0;
00148             seed = 0;
00149         }
00151 
00156         inline ml_matrix(int rows, int cols = 1)
00157         {
00158             // if parameters are less than 0, set them to 1, otherwise use what was passed in
00159             num_rows = (rows < 0) ? 1 : rows;
00160             num_cols = (cols < 0) ? 1 : cols;
00161             int copysize;
00162             if ((num_rows <= ML_ARR_INCR) && (num_cols <= ML_ARR_INCR))
00163             {
00164                 real_cols = real_rows = ML_ARR_INCR;
00165                 len = ML_ARR_INCR*ML_ARR_INCR;
00166                 copysize = sizeof(double) * len;
00167                 mat = base_mat;
00168                 using_base = 1;
00169             }
00170             else
00171             {
00172                 // real_rows and real_cols will always be the nearest multiple of 4 above the requested
00173                 // number of rows and cols. this is to allow extra room to prevent reallocation on small resizes
00174                 // of the matrix.
00175                 real_rows = ((num_rows>>2)+1) << 2;
00176                 real_cols = ((num_cols>>2)+1) << 2;
00177                 // len is the entire buffersize of mat, including the padding for potential resizes
00178                 len = real_rows * real_cols;
00179                 copysize = sizeof(double) * len;
00180                 // allocate a new double array for mat, the size of len
00181                 mat = new double[len];
00182                 using_base = 0;
00183             }
00184             // set all elements of mat to 0
00185             memset(mat, 0, copysize);
00186             buff = NULL;
00187             buffsize = 0;
00188             seed = 0;
00189             error = 0;
00190         }
00192         ml_matrix(int rows, int cols, double value);
00194         ml_matrix(int rows, int cols, double *v);
00196         ml_matrix(const char *s);
00198         ml_matrix(void *bf);
00200         ml_matrix(FILE *f, int *linenum = NULL);
00202         inline ~ml_matrix()
00203         {
00204             if (mat && !using_base)
00205             {
00206                 delete [] mat;
00207             }
00208             if (buff)
00209             {
00210                 free(buff);
00211             }
00212         }
00214         char *to_string(int human_readable = 0);
00216         void display(char *s = NULL);
00218         void *to_binary(unsigned int *size = NULL) const;
00220 
00221         #if 0
00222         #pragma mark Matrix Manipulation
00223         #endif
00224 
00233 
00234         double &operator()(int row, int col);
00236 
00242         inline double get(int row, int col) const
00243         {
00244             if (row < 1 || col < 1)
00245             {
00246                 return mat[0];
00247             }
00248             if((row > num_rows) || (col > num_cols))
00249             {
00250                 return mat[0];
00251             }
00252             //printf("getting %d, %d; rrows is %d, rcols is %d\n",row,col,real_rows,real_cols);
00253             return *ml_matloc(mat,row-1,col-1,real_rows,real_cols);
00254         }
00256         void resize(int rows, int cols);
00258         ml_matrix &append_identity();
00260         ml_matrix sub_matrix(int from_row, int to_row, int from_col, int to_col) const;
00262         ml_matrix sub_matrix(int n_rows, int *rows, int n_cols, int *cols) const;
00264         ml_matrix sub_matrix(const ml_int_array &rows, const ml_int_array &cols) const;
00266         ml_matrix get_row(int row) const;
00268         ml_matrix get_col(int col) const;
00270         ml_matrix get_row_set(int n_rows, int *rows) const;
00272         ml_matrix get_row_set(const ml_int_array &rows) const;
00274         ml_matrix get_col_set(int n_cols, int *cols) const;
00276         ml_matrix get_col_set(const ml_int_array &cols) const;
00278         ml_matrix sub_mat_row(int row, int n_cols, int *cols) const;
00280         ml_matrix sub_mat_row(int row, const ml_int_array &cols) const;
00282         ml_matrix sub_mat_col(int n_rows, int *rows, int col) const;
00284         ml_matrix sub_mat_col(const ml_int_array &rows, int col) const;
00286         ml_matrix extract_elements(const ml_matrix &elements);
00288         ml_matrix &delete_rows_cols(int n_rows, int *rows, int n_cols, int *cols);
00290         ml_matrix &delete_rows_cols(const ml_int_array &rows, const ml_int_array &cols);
00292         ml_matrix &delete_rows_cols(int row, const ml_int_array &cols);
00294         ml_matrix &delete_rows_cols(const ml_int_array &rows, int col);
00296         ml_matrix &delete_rows_cols(int row, int col);
00298         ml_matrix &inc_sub_matrix(const ml_matrix &m, int n_rows, int *rows);
00300         ml_matrix &inc_sub_matrix(const ml_matrix &m, const ml_int_array &rows);
00302         ml_matrix &inc_sub_matrix(const ml_matrix &m, int n_rows, int *rows, int n_cols, int *cols);
00304         ml_matrix &inc_sub_matrix(const ml_matrix &m, const ml_int_array &rows, const ml_int_array &cols);
00306         ml_matrix &inc_sub_matrix(const ml_matrix &m, int row, int n_cols, int *cols);
00308         ml_matrix &inc_sub_matrix(const ml_matrix &m, int row, const ml_int_array &cols);
00310         ml_matrix &inc_sub_matrix(const ml_matrix &m, int n_rows, int *rows, int col);
00312         ml_matrix &inc_sub_matrix(const ml_matrix &m, const ml_int_array &rows, int col);
00314         ml_matrix &inc_rows(const ml_matrix &a, int from_row, int to_row);
00316         ml_matrix &inc_cols(const ml_matrix &m, int from_col, int to_col);
00318         ml_matrix &inc_elements(const ml_matrix &values,const ml_matrix &elements);
00320         ml_matrix &dup_rows(int num);
00322         ml_matrix &dup_cols(int num);
00324         ml_matrix &append(const ml_matrix &b);
00326         ml_matrix &stack(const ml_matrix &b);
00328 
00329         #if 0
00330         #pragma mark BLAS and LAPACK Utility Functions
00331         #endif
00332 
00341 
00342 
00348         double *raw_data() const
00349         {
00350             return mat;
00351         }
00353 
00359         int data_stride() const
00360         {
00361             return ml_major_stride(real_rows, real_cols);
00362         }
00364 
00365         #if 0
00366         #pragma mark Inspection/Assignment Members
00367         #endif
00368 
00377 
00378 
00383         int error;
00385         int is_empty() const;
00387         int operator==(const ml_matrix &m) const;
00389         int operator!=(const ml_matrix &m) const;
00391         ml_matrix find(ml_comparison op, double target) const;
00393         void sort(int direction = 0);
00395         ml_matrix sort_indices(int direction = 0) const;
00397         void permute(const ml_matrix &elements);
00399         ml_matrix sum_rows() const;
00401         ml_matrix sum_cols() const;
00403         ml_matrix max() const;
00405         ml_matrix row_max() const;
00407         ml_matrix col_max() const;
00409         ml_matrix min() const;
00411         ml_matrix row_min() const;
00413         ml_matrix col_min() const;
00415         ml_matrix interpolate(int col, double value) const;
00417 
00421         inline int rows() const
00422         {
00423             return num_rows;
00424         }
00426 
00430         inline int cols() const
00431         {
00432             return num_cols;
00433         }
00435         ml_matrix &operator=(const ml_matrix &m);
00437         ml_matrix &operator=(const char *s);
00439         void zero();
00441         void ones();
00443         void set_val(double v);
00445         void set_val(const ml_matrix &elements,double v);
00447         ml_matrix &apply(double (*func)(double));
00449         void apply_to_elements(const ml_matrix &elements, double (*func)(double));
00451         void identity();
00453         void rand_seed(double seed);
00455         void rand();
00457         void randn(double std_dev);
00459 
00460         #if 0
00461         #pragma mark Arithmetic Members
00462         #endif
00463 
00471 
00472         ml_matrix &operator*=(const ml_matrix &m);
00474         ml_matrix &operator*=(double a);
00476         ml_matrix &dotstar_eq(const ml_matrix &m);
00478         ml_matrix &operator/=(const ml_matrix &m);
00480         ml_matrix &operator/=(double a);
00482         ml_matrix &dotslash_eq(const ml_matrix &m);
00484         ml_matrix &operator+=(const ml_matrix &m);
00486         ml_matrix &operator+=(double a);
00488         ml_matrix &operator-=(const ml_matrix &m);
00490         ml_matrix &operator-=(double a);
00492 
00493         #if 0
00494         #pragma mark Algebraic Members
00495         #endif
00496 
00503 
00504         ml_matrix &abs();
00506         ml_matrix &ceil();
00508         ml_matrix &floor();
00510         ml_matrix &round();
00512         ml_matrix &rint();
00514         ml_matrix &dotpow(double n);
00516         ml_matrix &sqrt();
00518         ml_matrix &exp();
00520         ml_matrix &expm1();
00522         ml_matrix &log();
00524         ml_matrix &log10();
00526         ml_matrix &log1p();
00528         ml_matrix &log2();
00530         ml_matrix &logb();
00532 
00533         #if 0
00534         #pragma mark Linear Alegbra Members
00535         #endif
00536 
00541 
00542         ml_matrix &transpose();
00544         ml_matrix &inv();
00546         ml_matrix invp(const ml_matrix &n, int k) const;
00548         ml_matrix &mpow(int n);
00550         ml_matrix diag() const;
00552         double trace() const;
00554         ml_matrix mag() const;
00556         double vmag() const;
00558         ml_matrix &cross(const ml_matrix &n);
00560         double dot(const ml_matrix &n) const;
00562         ml_matrix skew_symm() const;
00564         ml_matrix &unit();
00566         ml_matrix &sign();
00568         ml_matrix &vunit();
00570         double norm() const;
00572         ml_matrix &solve_ax_eq_b(const ml_matrix &a);
00579         inline ml_matrix &row_mult(int row, double fac)
00580         {
00581             double *m2 = ml_matloc(mat, row-1, 0, real_rows, real_cols);
00582             for (int i = 0; i < num_cols; i++)
00583             {
00584                 *m2 *= fac;
00585                 ml_incr_col(m2,real_rows, real_cols);
00586             }
00587             return *this;
00588         }
00590 
00591         #if 0
00592         #pragma mark Trigonometric Members
00593         #endif
00594 
00599 
00600         ml_matrix &sin();
00602         ml_matrix &cos();
00604         ml_matrix &tan();
00606         ml_matrix &csc();
00608         ml_matrix &sec();
00610         ml_matrix &cot();
00612         ml_matrix &asin();
00614         ml_matrix &acos();
00616         ml_matrix &atan();
00618         ml_matrix &acsc();
00620         ml_matrix &asec();
00622         ml_matrix &acot();
00624         ml_matrix &sinh();
00626         ml_matrix &cosh();
00628         ml_matrix &tanh();
00630         ml_matrix &csch();
00632         ml_matrix &sech();
00634         ml_matrix &coth();
00636         ml_matrix &asinh();
00638         ml_matrix &acosh();
00640         ml_matrix &atanh();
00642         ml_matrix &acsch();
00644         ml_matrix &asech();
00646         ml_matrix &acoth();
00648         ml_matrix &atan2(const ml_matrix &m);
00650 
00651     protected:
00652         // The array containing the elements of the matrix.
00653         double *mat;
00654         // The number of rows in the matrix.
00655         int num_rows;
00656         // The number of columns in the matrix.
00657         int num_cols;
00658         // The number of rows allocated for storage.
00659         int real_rows;
00660         // The number of columns allocated for storage.
00661         int real_cols;
00662         // The size of the storage array, equal to the product of real_rows and real_cols.
00663         int len;
00664         // Character buffer used for to_string() operations.
00665         char *buff;
00666         // Size of the character buffer.
00667         int buffsize;
00668         // Seed for randomizing operations.
00669         double seed;
00670         // Built-in static array for optimizing small matrices.
00671         double base_mat[ML_ARR_INCR*ML_ARR_INCR];
00672         // Flag indicating whether the built-in or dynamically allocated array is used.
00673         int using_base;
00674         inline void swap_rows(int a, int b);
00675         inline void row_add(int a, int b);
00676         inline void row_sub(int k, int j);
00677 };
00678 
00679 #if 0
00680 #pragma mark Construction and I/O Non-Members
00681 #endif
00682 
00685 
00686 ml_matrix linspace(double start, double finish, int n);
00688 ml_matrix colon(double start, double incr, double end);
00690 
00691 #if 0
00692 #pragma mark Matrix Manipulation Non-Members
00693 #endif
00694 
00697 
00698 ml_matrix append_identity(const ml_matrix &b);
00700 ml_matrix dup_rows(const ml_matrix &m, int num);
00702 ml_matrix dup_cols(const ml_matrix &m, int num);
00704 ml_matrix append(const ml_matrix &a, const ml_matrix &b);
00706 ml_matrix stack(const ml_matrix &a, const ml_matrix &b);
00708 
00709 #if 0
00710 #pragma mark Comparison, Inspection, Assignment Non-Members
00711 #endif
00712 
00715 
00716 ml_matrix sort(const ml_matrix &m, int direction = 0);
00718 ml_matrix apply(const ml_matrix &m, double (*func)(double));
00720 
00721 #if 0
00722 #pragma mark Arithmetic Non-Members
00723 #endif
00724 
00727 
00728 ml_matrix operator*(double b,const ml_matrix &a);
00730 ml_matrix operator*(const ml_matrix &a, double b);
00732 ml_matrix operator*(const ml_matrix &a, const ml_matrix &b);
00734 ml_matrix dotstar(const ml_matrix &a, const ml_matrix &b);
00736 ml_matrix operator/(const ml_matrix &a, double b);
00738 ml_matrix operator/(const ml_matrix &a, const ml_matrix &b);
00740 ml_matrix backslash(const ml_matrix &a, const ml_matrix &b);
00742 ml_matrix dotslash(const ml_matrix &a, const ml_matrix &b);
00744 ml_matrix operator+(double b,const ml_matrix &a);
00746 ml_matrix operator+(const ml_matrix &a, double b);
00748 ml_matrix operator+(const ml_matrix &a, const ml_matrix &b);
00750 ml_matrix operator-(double b,const ml_matrix &a);
00752 ml_matrix operator-(const ml_matrix &a, double b);
00754 ml_matrix operator-(const ml_matrix &a, const ml_matrix &b);
00756 ml_matrix operator-(const ml_matrix &a);
00758 
00759 #if 0
00760 #pragma mark Algebraic Non-Members
00761 #endif
00762 
00765 
00766 ml_matrix abs(const ml_matrix &x);
00768 ml_matrix ceil(const ml_matrix &x);
00770 ml_matrix floor(const ml_matrix &x);
00772 ml_matrix round(const ml_matrix &x);
00774 ml_matrix rint(const ml_matrix &x);
00776 ml_matrix dotpow(const ml_matrix&, double n);
00778 ml_matrix sqrt(const ml_matrix &x);
00780 ml_matrix exp(const ml_matrix &x);
00782 ml_matrix expm1(const ml_matrix &x);
00784 ml_matrix log(const ml_matrix &x);
00786 ml_matrix log10(const ml_matrix &x);
00788 ml_matrix log1p(const ml_matrix &x);
00790 ml_matrix log2(const ml_matrix &x);
00792 ml_matrix logb(const ml_matrix &x);
00794 
00795 #if 0
00796 #pragma mark Linear Algebra Non-Members
00797 #endif
00798 
00801 
00802 ml_matrix transpose(const ml_matrix &m);
00804 ml_matrix inv(const ml_matrix &m);
00806 ml_matrix mpow(const ml_matrix &m, int n);
00808 ml_matrix cross(const ml_matrix &m, const ml_matrix &y);
00810 ml_matrix unit(const ml_matrix &m);
00812 ml_matrix sign(const ml_matrix &m);
00814 ml_matrix svd(ml_matrix &u, ml_matrix &v, const ml_matrix &a);
00816 ml_matrix vunit(const ml_matrix &m);
00818 ml_matrix solve_ax_eq_b(const ml_matrix &a,const ml_matrix &b);
00820 bool simplex(ml_matrix &x, ml_matrix c, ml_matrix a, ml_matrix b, double max_val);
00822 void simplex2(ml_matrix a, ml_matrix c, ml_matrix &x, ml_int_array &s, ml_int_array &g, ml_int_array &gu, ml_matrix &b_inv, double max_val);
00824 
00825 #if 0
00826 #pragma mark Trigonometric Non-Members
00827 #endif
00828 
00831 
00832 ml_matrix sin(const ml_matrix &x);
00834 ml_matrix cos(const ml_matrix &x);
00836 ml_matrix tan(const ml_matrix &x);
00838 ml_matrix csc(const ml_matrix &x);
00840 ml_matrix sec(const ml_matrix &x);
00842 ml_matrix cot(const ml_matrix &x);
00844 ml_matrix asin(const ml_matrix &x);
00846 ml_matrix acos(const ml_matrix &x);
00848 ml_matrix atan(const ml_matrix &x);
00850 ml_matrix acsc(const ml_matrix &x);
00852 ml_matrix asec(const ml_matrix &x);
00854 ml_matrix acot(const ml_matrix &x);
00856 ml_matrix atan2(const ml_matrix &x, const ml_matrix &y);
00858 ml_matrix sinh(const ml_matrix &x);
00860 ml_matrix cosh(const ml_matrix &x);
00862 ml_matrix tanh(const ml_matrix &x);
00864 ml_matrix csch(const ml_matrix &x);
00866 ml_matrix sech(const ml_matrix &x);
00868 ml_matrix coth(const ml_matrix &x);
00870 ml_matrix asinh(const ml_matrix &x);
00872 ml_matrix acosh(const ml_matrix &x);
00874 ml_matrix atanh(const ml_matrix &x);
00876 ml_matrix acsch(const ml_matrix &x);
00878 ml_matrix asech(const ml_matrix &x);
00880 ml_matrix acoth(const ml_matrix &x);
00882 
00883 }
00884 
00885 #endif