00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define PSS_OS_MACOSX
00081
00082
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
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
00142 mat = new double[real_cols * real_rows];
00143
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
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
00173
00174
00175 real_rows = ((num_rows>>2)+1) << 2;
00176 real_cols = ((num_cols>>2)+1) << 2;
00177
00178 len = real_rows * real_cols;
00179 copysize = sizeof(double) * len;
00180
00181 mat = new double[len];
00182 using_base = 0;
00183 }
00184
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
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
00653 double *mat;
00654
00655 int num_rows;
00656
00657 int num_cols;
00658
00659 int real_rows;
00660
00661 int real_cols;
00662
00663 int len;
00664
00665 char *buff;
00666
00667 int buffsize;
00668
00669 double seed;
00670
00671 double base_mat[ML_ARR_INCR*ML_ARR_INCR];
00672
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