/*============================================================================== //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_ v_vecmat.C++ Homebrewed vector/matrix library. Uses the C preprocessor to allow redefinition of vec,matrix element type (C++ templates are a better way, but the syntax is too exasperating to use) by changing the #define VECTYPE and a define stmt. for the vector size VV; however all the member names include a '3' or '4' that you should change manually if you change 'VV'. Implemented for VV=2,3,4. Most functions pass-by-reference for input parameters and all use local temporary storage of intermediate results so that in-place calculations (where an object invokes a member function using itself as one or more of the arguments to the function)never cause problems. The results of the calculations of each member function places results in the data members of the calling object, unless the result is of a different type; then the member function's results are passed as a returned value. For example, the Mat3 matrix class has a member function named mm_mpy() that multiplies a 'left' matrix and a 'rt' matrix. Suppose we have three Mat3 objects named A,B, and C. The statement C.mm_mpy(A,B); will multiply A by B to find new values for the C matrix. Note that we always use internal storage, so it is acceptable to make calls like B.mm_mpy(B,B) for in-place calculations; the temporary storage used in member functions make sure that the new B values are equal to the matrix product of the old B values. What happens if the result of a member function is a type that doesn't match the calling object? we simply return the result. For example, the Vec3 matrix class has a member function named 'dot()' that finds the dot product (a scalar) from multiplying a vector 'in1' by another vector 'in2'; the result is a scalar value. Suppose we have a VECTYPE scalar 'dotprod', and three vectors vvA,vvB, and vvC. If we invoke the 'dot' member function of vvC using vvA,vvB as arguments; dotprod = vvC.dot(vvA,vvB); then 'dotprod' gets the returned scalar value found by calculating the dot product of vvA and vvB, while vvC is completely unaffected. However since all member functions use temporary storage to allow in-place calcs, we could get the same result with either: dotprod = vvA.dot(vvA,vvB); or with dotprod = vvB.dot(vvA,vvB); REVISIONS: 5/14/93 J. Tumblin CREATED from my3vec.c 9?/??/98 J. Tumblin added separate integer matrix/vector classes Ivec,Imat 12/12/98 J. Tumblin added arbitrary matrix class (from old mtx,matrx) 01/??/2002 J. Tumblin added poly2 functions, complete convolution support. 04/24/2002 J. Tumblin added SVD_full(), split off subset for CS395 IBMR class. ==============================================================================*/ #if !defined(__JT__V_VECMAT)// if we haven't already included this file, #define __JT__V_VECMAT // compile it! (#endif at end-of-file). //================== // DEFINE stmts; //================== #define VECTYPE double // 'float' or 'double'-- sets element data type. #define IS_FLOAT FALSE #define IS_DOUBLE TRUE // define matrix/vector data // type---(double or float) #if !defined(M_PI) #define M_PI 3.141592653589793 // VC++ doesn't have M_PI constant // defined! #endif //#include "globals.h" // for 'DPF' debug printing calls //#define DPF printf // for non-MS Windows debugging, #define DPF TRACE // for Windows VC++ debugging. #include //================== // FWD declarations; //================== // class Vec3; // (don't fwd-declare Vec3, since it is never // used before declaration. class Mat2; // Do fwd-declare of Mat2: Vec2 uses it. class Mat3; // DO fwd-... class Mat4; // DO fwd-... class Matrx; //============================================================================== //================================ ============================== //================================ 2x2 Vectors ============================== //================================ ============================== //============================================================================== class Vec2 { //============================================================================== /* a 1-D homogeneous 'column vector'; [row[0] ] [row[1] ] */ //-----------------------DATA------------------- public: VECTYPE row[2]; //======-----------------FCNS------------------- public: Vec2() { // void constructor row[0] = (VECTYPE)0.0; row[1] = (VECTYPE)0.0; }; Vec2(VECTYPE r0,VECTYPE r1=0) { // explicit constructor row[0] = r0; row[1] = r1; }; void set(VECTYPE r0,VECTYPE r1) { // set vec elements row[0] = r0; row[1] = r1; }; void zero() { // clear a vector to 0.0 row[0] = (VECTYPE)0.0; row[1] = (VECTYPE)0.0; }; void prnt(); // prettyprint a vec void prnt(char* name); // print a labeled vec VECTYPE norm(Vec2& src); // normalize, & return length void add(Vec2& src1, Vec2& src2); // add: [this] = src1+src2 void sub(Vec2& src1, Vec2& src2); // subtract;[this] = src1-src2 void scale(Vec2& src1, VECTYPE c); // scale: [this]= src1.*c VECTYPE dot(Vec2& src1, Vec2& src2); // dot product; retn [in1].[in2] VECTYPE cross(Vec2& src1); // 2D cross product; [this]X[in1] void mpy(Mat2& srcM, Vec2& srcV); // matrix-vector mpy: // [this] = [in1m][in2v] BOOL isZero(void); // TRUE iff all are zero. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all elements are // 0.0 or 1/integer. BOOL isCloserTo(Vec2& srcA, Vec2& srcB);// TRUE iff srcA is closer than srcB. VECTYPE CCWAngleTo(Vec2& dest); // Find angle in CCW radians, // (0-to-2pi) from 'this' to 'dest'. VECTYPE signedAngleTo(Vec2& dest); // Get angle in radians (+/- PI) // from 'this' to 'dest' vector. }; class Mat2 { //============================================================================== /* A 1D homogeneous matrix data type. Note colrow[][] indices are just like colrow[x][y] (x,y position within matrix). [ col[0][0] colrow[1][0] ] [ col[0][1] colrow[1][1] ] [ col[0][2] colrow[1][2] ] */ //-----------------DATA------------------- public: VECTYPE colrow[2][2]; // gives [column#][row#], equivalent to // to the x,y position in matrix //-----------------FCNS------------------- public: Mat2(void); // void constructor Vec2 getcol(int col); // return a column. void putcol(Vec2& in1, int col); // overwrite a column. void zero(void); // clear matrix to 0.0 void ident(void); // set to identity matrix void scale(Mat2& in2, VECTYPE scale);// make scaled copy of a matrix void prnt(void); // prettyprint matrix void prnt(char *name); // print a labeled matrix void mpy(Mat2& left, Mat2& rt); // matrix-matrix mpy:[this] = [left][rt] void transpose(void); // in-place transpose void makeTrans(VECTYPE xoff); // make 1D trans. matx void makeScale(VECTYPE xscale); // make scale matrix BOOL isZero(void); // TRUE iff all zero. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all are 1/int or 0 //--------------------For 2D Vector operations: void makeRot90(); // CCW 90 degree rotation. void makeRot180(); // CCW 180 degree rotation. void makeRot270(); // CCW 270 degree rotation. //--------------------Compatibility with other matrix classes void copyTo(Matrx &out); // resize out, copy contents to it. }; //============================================================================== //================================ ============================== //================================ 3x3 Vectors ============================== //================================ ============================== //============================================================================== class Vec3 { //============================================================================== /* a 2-D homogeneous 'column vector'; [row[0] ] [row[1] ] [row[2] ] */ //-----------------DATA------------------- public: VECTYPE row[3]; //-----------------FCNS------------------- public: Vec3(void) { // void constructor row[0] = (VECTYPE)0.0; row[1] = (VECTYPE)0.0; row[2] = (VECTYPE)0.0; }; Vec3(VECTYPE r0,VECTYPE r1,VECTYPE r2) { // explicit constructor row[0] = r0; row[1] = r1; row[2] = r2; }; void set(VECTYPE r0,VECTYPE r1,VECTYPE r2) { // set vec elements row[0] = r0; row[1] = r1; row[2] = r2; }; void zero(void) { // clear a vector to 0.0 row[0] = (VECTYPE)0.0; row[1] = (VECTYPE)0.0; row[2] = (VECTYPE)0.0; }; void prnt(void); // prettyprint a vec void prnt(char* name); // print a labeled vec VECTYPE norm(Vec3& src); // normalize, & return length void add(Vec3& src1, Vec3& src2); // add: [this] = src1+src2 void sub(Vec3& src1, Vec3& src2); // subtract;[this] = src1-src2 void scale(Vec3& src1, VECTYPE c); // scale: [this]= src1.*c VECTYPE dot(Vec3& src1, Vec3& src2);// dot product; retn [in1].[in2] void cross(Vec3& src1, Vec3& src2); // cross product; [this]= [in1]X[in2] void mpy(Mat3& srcM, Vec3& srcV); // matrix-vector mpy: // [this] = [in1m][in2v] BOOL isZero(void); // TRUE iff all zero elements. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all are 1/integer. }; class Mat3 { //============================================================================== /* A 2D homogeneous matrix data type. Note colrow[][] indices are just like colrow[x][y] (x,y position within matrix). [ col[0][0] colrow[1][0] colrow[2][0] ] [ col[0][1] colrow[1][1] colrow[2][1] ] [ col[0][2] colrow[1][2] colrow[2][2] ] */ //-----------------DATA------------------- public: VECTYPE colrow[3][3]; // gives [column#][row#], equiv // to x,y position in matrix, // and allows 'a=b' assignments. //-----------------FCNS------------------- public: Mat3(void) { zero(); }; // void constructor Vec3 getcol(int col); // return a column. void putcol(Vec3& in1, int col); // overwrite a column. void zero(void); // clear matrix to 0.0 void ident(void); // set to identity matrix void copy(Mat3& src); // element-by-element copy of matrix. void prnt(void); // prettyprint matrix void prnt(char *name); // print a labeled matrix void mpy(Mat3& left, Mat3& rt); // matrix-matrix mpy:[this] = [left][rt] void convolve(Mat2& inA2, Mat2& inB2); // for 2D polynomial multiply void transpose(void); // in-place transpose void makeRBT(VECTYPE xctr,VECTYPE yctr,VECTYPE theta_rad); // make matrix for 2D rotation // about xctr,yctr void makeTrans(VECTYPE xoff, VECTYPE yoff) { // make 2D translation matrix: ident(); // write ident mtx over 'self' colrow[2][0] = xoff; // write x,y offset values colrow[2][1] = yoff; }; void makeScale(VECTYPE xscale, VECTYPE yscale) { // make scale matrix zero(); colrow[0][0] = xscale; colrow[1][1] = yscale; colrow[2][2] = (VECTYPE)1.0; }; // --origin-centered rotation matrices: void makeRot(VECTYPE theta_rad); // 2D rigid-body CCW (theta in radians) void makeRot90(); // 90 degrees CCW (2D). void makeRot180(); // 180 degrees CCW void makeRot270(); // 270 degrees CCW BOOL isZero(void); // TRUE iff all zero elements. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all are 1/int or 0 //--------------------Compatibility with other matrix classes void copyTo(Matrx &out); // resize out, copy contents to it. }; //============================================================================== //================================ ============================== //================================ 4x4 Vectors ============================== //================================ ============================== //============================================================================== class Vec4 { //============================================================================== /* an 3-D homogeneous 'column vector'; [row[0] ] [row[1] ] [row[2] ] [row[3] ] */ //-----------------DATA------------------- public: VECTYPE row[4]; //-----------------FCNS------------------- public: Vec4(void) { zero(); }; // void constructor Vec4(VECTYPE r0,VECTYPE r1,VECTYPE r2,VECTYPE r3) { // explicit constructor row[0] = r0; row[1] = r1; row[2] = r2; row[3] = r3; }; void set(VECTYPE r0,VECTYPE r1,VECTYPE r2,VECTYPE r3) { // set vec elements row[0] = r0; row[1] = r1; row[2] = r2; row[3] = r3; }; void zero(void) { // clear a vector to 0.0 row[0] = (VECTYPE)0.0; row[1] = (VECTYPE)0.0; row[2] = (VECTYPE)0.0; row[3] = (VECTYPE)0.0; }; void prnt(void); // prettyprint a vec void prnt(char* name); // print a labeled vec VECTYPE norm(Vec4& src); // normalize, then return length void add(Vec4& src1, Vec4& src2); // add: [this] = src1+src2 void sub(Vec4& src1, Vec4& src2); // subtract;[this] = src1-src2 void scale(Vec4& src1, VECTYPE c); // scale: [this]= src1.*c VECTYPE dot(Vec4& src1, Vec4& src2);// dot product; retn [in1].[in2] void cross(Vec4& src1, Vec4& src2); // homogeneous coord cross prod; // [this]=[src1]X[src2] void mpy(Mat4& srcM, Vec4& srcV); // matrix-vector mpy: // [this] = [in1m][in2v] BOOL isZero(void); // TRUE iff all elements zero. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all are 1/int or 0. //--------------------Compatibility with other matrix classes void copyTo(Matrx &out); // resize out, copy contents to it. }; class Mat4 { //============================================================================== /* matrix data type for 3D homogeneous matrices; NOTE colrow[][] indices are just like colrow[x][y] (x,y position within matrix). [ col[0][0] colrow[1][0] colrow[2][0] ... ] [ col[0][1] colrow[1][1] colrow[2][1] ... ] [ col[0][2] colrow[1][2] colrow[2][2] ... ] [ ... ... ... ... ] */ //-----------------DATA------------------- public: VECTYPE colrow[4][4]; // gives [column#][row#], equiv to x,y // position in matrix //-----------------FCNS------------------- public: Mat4(void) { zero(); }; // void constructor // Vec4 getcol(int col); // return a column. // void putcol(Vec4& in1, int col); // overwrite a column. void zero(void); // clear matrix to 0.0 void ident(void); // set to identity matrix void prnt(void); // prettyprint matrix void prnt(char *name); // print a labeled matrix void mpy(Mat4& left, Mat4& rt); // matrix-matrix mpy: // [this] = [this][rt] void transpose(void); // in-place transpose void makeTrans(VECTYPE xoff, VECTYPE yoff, VECTYPE zoff); // make translation matx void makeRot(Vec4& axis, VECTYPE theta_rad); // make a matrix to rotate // about arbitrary axis. void makeScale(VECTYPE xscale, VECTYPE yscale, VECTYPE zscale) { // make 3D scale matrix zero(); colrow[0][0] = xscale; colrow[1][1] = yscale; colrow[2][2] = zscale; colrow[3][3] = (VECTYPE)1.0; }; BOOL isZero(void); // TRUE iff all zero elements. BOOL isInteger(void); // TRUE iff all integer elements BOOL isInvInteger(void); // TRUE iff all are 1/int or 0. //--------------------Compatibility with other matrix classes void copyTo(Matrx &out); // resize out, copy contents to it. }; //============================================================================== //================================ ============================== //================================ Arbitrary ============================== //================================ Sized Matrix ============================== //================================ ============================== //============================================================================== class Matrx { //============================================================================== // An arbitrary-sized matrix class using a storage method compatible with IMSL // libraries (linkable FORTRAN). PLEASE PLEASE PLEASE don't directly access // the 'a' array; use the 'get()' and 'put()' member functions, because I may // change the matrix storage methods later to add 'sparse' matrix types, etc. // Written for use with the usual 0-based array indices of C,C++, BUT you can // use the 1-based indices common to FORTRAN code and all the "Numerical Recipes // in C" code by using 'get1()' and put1()' instead of the zero-based 'get0()' // and 'put0()'. // 12/14/98: added dyn.alloc'd array of pointers to each row so we are // also compatible with Numerical Recipes code. //private: //-----------------DATA----------------- public: VECTYPE *a; // dynam. allocated space at this ptr holds // 2D array of matrix // entries in row-major order-- // A00,A10,A20,.. (all of col 0, // then all of col 1, etc) // stored value is element int xsize; // # columns in the matrix. int ysize; // # of rows public: //-----------------Access----------------- Matrx(void); // make an 'empty' object ~Matrx(void); // destructor; de-alloc memory BOOL wipe(void); // release space for matrix. void sizer(int iysize,int ixsize); // allocate space for matrix; // sizer(#rows,#columns) void sizer(Matrx& src); int getXsize(void) { return(xsize);}; int getYsize(void) { return(ysize);}; BOOL copy(Matrx& src); // auto-resizing entry-by-entry copy // (no change to our object's name) void copy0Col(int destCol, Matrx &src, int srcCol); // copy one column from 'src' matrix. void put0(int row,int col, VECTYPE val); VECTYPE get0(int row, int col); // read/write 'val' at row,col. // (uses zero-based indexing) void put1(int row,int col, VECTYPE val); VECTYPE get1(int row, int col); // read/write 'val' at row,col. // (uses ONE-based indexing) void addTo0(int row, int col, VECTYPE val); // add 'val' to current value at row,col. // (uses zero-based indexing) void addTo1(int row, int col, VECTYPE val); // add 'val' to current value at row,col. // (uses ONE-based indexing) void put0Row(int row, VECTYPE c0,...); void put0Row(int row, Vec4 &src); // Write values at (row,c0),(row,c1),... void put0Col(int col, VECTYPE r0,...); void put0Col(int col, Vec4 &src); // Write values at (r0,col),(r1,col),... VECTYPE* getPtr0(int row=0, int col=0) { //(zero-based indexing) // return pointer to element; // default to 1st element. return(&(a[row + col*ysize])); }; VECTYPE* getPtr1(int row=1, int col=1) {// (one-based indexing) return(&(a[(row-1) + (col-1)*ysize])); }; //---------------Math------------------ void mpyScalar(VECTYPE wt); // scale every element by 'wt'. BOOL mmpy(Matrx& left, Matrx& rt);// replace our current contents with // result of matrix multiply [left][rt]. // Return FALSE on err. BOOL augment(Matrx& left, Matrx& rt); // place rows of left,rt side-by-side. // return FALSE on error. BOOL stack(Matrx& top, Matrx& bot); // place columns of 'top' above 'bot'. // return FALSE on error. void swapRows1(int rA,int rB); // swap contents of rows rA,rB // (rA,rB using 1-based indexing) void swapCols1(int cA,int cB); // swap contents of columns cA,cB // (cA,cB use 1-based indexing) BOOL add(Matrx& left,Matrx& rt);// 'this'=left+rt('this' as input is OK) BOOL sub(Matrx& left,Matrx& rt);// 'this'=left-rt('this' as input is OK) // BOOL add(Matrx& src); // add; us += src; // BOOL sub(Matrx& src); // subtract: us -= src; BOOL transpose(Matrx& src); // in-place is OK(src=*this) BOOL scaleRows(Matrx& scale_vec); BOOL GaussJordan_elim(Matrx& a, Matrx& b); // in-place,full-pivot, Gauss-Jordan // elimination; solves Ax=b given NxN matrix // A and NxM matrix b. A is replaced by its // inverse, and b is replaced by x. Returns // FALSE if A is singular. BOOL invert(void); // In-place matrix inversion; uses code from // GaussJordan_elim() with 'b' vector deleted private: VECTYPE pythag(VECTYPE a, VECTYPE b); // computes sqrt(a^2 + b^2) without destructive // overflow or underflow. Used in SVD_full, // taken from Numerical Recipes. public: void SVD_test(int cnt=10); // Test SVD_full() 'cnt' times. BOOL isOrthonormal(Matrx& in, VECTYPE errmax=0.01); // checks columns... BOOL SVD_full(Matrx& u, Matrx& ss, Matrx& v); //-----SVD (from Numerical Recipes)---------- // Perform a full Singular Value Decomposition // Using current contents ('this') as 'A', // find matrices that satisfy A = U S V^T // Where U,V are orthonormal (its columns are // unit length & orthogonal), S is diagonal. // A matrix is unchanged, but U,S,V matrices // contents (if any) are always replaced. // S is returned as a column vector of // singular values to save space. // Returns FALSE error. void randFill(VECTYPE min=(VECTYPE)0.0, VECTYPE max=(VECTYPE)1.0); // fill matrix with random #s. void zero(void); // fill matrix with zeroes void ident(void); // make identity matrix. void countR(void); // fill with counting; row-major void countC(void); // fill with counting; column-major BOOL isEqual(Matrx &src,VECTYPE tol2=1.0E-15); // TRUE iff 'this'=='src', (+/- tol) void copyTo(Mat2& out); // Copy first 2x2 elements to 'out' void copyTo(Mat3& out); // Copy first 3x3 elements to 'out' void copyTo(Mat4& out); // Copy first 4x4 elements to 'out' void textOut(FILE* fptr, char* title, int linewidth); // make printout in stream 'fptr' void prnt(const char *name); // Print to debug window using 'dprintf'. // usage: mymat.prnt("mymat"); }; //============================================================================== //================================ ============================== //================================ Integer ============================== //================================ Arbitrary ============================== //================================ Sized Vectors ============================== //================================ ============================== //============================================================================== class Ivec //============================================================================== // Simple integer vector class for use as indices, flags, etc., inspired by // 'ivector' functions in 'Numerical Recipes in C'. As with the Matrx class, // PLEASE PLEASE PLEASE don't access array 'a' directly but instead use the // 'get' and 'put' functions. Offers zero-based and 1-based indexing // (as used in FORTRAN & NR code). { private: //-----------------DATA----------------- int *a; // dynam. allocated space at this ptr holds // 1D array of elements. int size; // # elements. public: //-----------------FCNS----------------- Ivec(void); // make an 'empty' object ~Ivec(void); // destructor; de-alloc memory BOOL wipe(void); // release space for vector. void sizer(int isize); // allocate space for vector. void sizer(Ivec& src); // match our size to 'src'. int getSize(void) { return(size);}; BOOL copy(Ivec& src); // auto-resizing entry-by-entry copy // (no change to our object's name) void put0(int indx, int val); int get0(int indx); // read/write 'val' at row,col. // (uses zero-based indexing) void put1(int indx, int val); int get1(int indx); // read/write 'val' at row,col. // (uses ONE-based indexing) //-------------------------------------- BOOL add(Ivec& src); // add; us += src; BOOL sub(Ivec& src); // subtract: us -= src; void incr0(int indx); // increment@indx (zero-based) void incr1(int indx); // increment@indx (one-based) void decr0(int indx); // decrement@indx (zero-based) void decr1(int indx); // decrement@indx (one-based) //-------------------------------------- void zero(void); // fill vector with zeroes void count(void); // fill with counting. void textOut(FILE* fptr, char* title, int linewidth); // make printout in stream 'fptr' }; class Imat //============================================================================== // An arbitrary-sized INTEGER matrix class for use as indices, flags, etc., // inspired by 'ivector' functions in 'Numerical Recipes in C', and a storage // method compatible with IMSL libraries (linkable FORTRAN). PLEASE PLEASE // PLEASE don't directly access the 'a' array; use the 'get()' and 'put()' // member functions, because I may change the matrix storage methods later to // add 'sparse' matrix types, etc. // // Written for use with the usual 0-based array indices of C,C++, BUT you can // use the 1-based indices common to FORTRAN code and all the "Numerical Recipes // in C" code by using 'get1()' and put1()' instead of the zero-based 'get0()' // and 'put0()'. // 12/14/98: added dyn.alloc'd array of pointers to each row so we are // also compatible with Numerical Recipes code. { private: //-----------------DATA----------------- int *a; // dynam. allocated space at this ptr holds // 2D array of matrix entries in row-major // order--A00,A10,A20,.. (all of col 0,then // all of col 1, etc) stored value is // the matrix element value. int xsize; // # columns in the matrix. int ysize; // # of rows public: //-----------------FCNS----------------- Imat(void); // make an 'empty' object ~Imat(void); // destructor; de-alloc memory BOOL wipe(void); // release space for matrix. void sizer(int iysize,int ixsize); // allocate space for matrix; // sizer(#rows,#columns) void sizer(Imat& src); int getXsize(void) { return(xsize);}; int getYsize(void) { return(ysize);}; BOOL wipeCopy(Imat& src); // auto-resizing entry-by-entry copy // (no change to our object's name) void put0(int row,int col, int val); int get0(int row, int col); // read/write 'val' at row,col. // (uses zero-based indexing) void put1(int row,int col, int val); int get1(int row, int col); // read/write 'val' at row,col. // (uses ONE-based indexing) void put0_Row(int row,int c0,...);// Write a row of values into matrix. // (CAREFUL! No over/under-run checks!) void put0_Col(int col,int r0,...);// Write a column of values into matrix. // (CAREFUL! No over/under-run checks!) void put0_OR(int row, int col, int val); // in-place OR with val void put1_OR(int row, int col, int val); // (zero, one-based addr) void put0_AND(int row, int col, int val); // in-place AND with val void put1_AND(int row, int col, int val); // (zero, one-based addr) // Write 'val' bits if 'mask' bits are true. void put0_mask(int row, int col, int val, int mask); void put1_mask(int row, int col, int val, int mask); int* getPtr0(int row=0, int col=0) { //(zero-based indexing) // return pointer to element; // default to 1st element. return(&(a[row + col*ysize])); }; int* getPtr1(int row=1, int col=1) {// (one-based indexing) return(&(a[(row-1) + (col-1)*ysize])); }; //-------------------------------------- void swapRows1(int rA,int rB); // swap contents of rows rA,rB // (rA,rB using 1-based indexing) void swapCols1(int cA,int cB); // swap contents of columns cA,cB // (cA,cB use 1-based indexing) BOOL add(Imat& src); // add; us += src; BOOL sub(Imat& src); // subtract: us -= src; BOOL transpose(Imat& src); // in-place is OK(src=*this) BOOL mmpy(Imat& left, Imat& rt);// replace our current contents // with result of matrix multiply // [left][rt]. Return FALSE on err. BOOL augment(Imat& left, Imat& right); // Merge two matrices side-by-side. // Return FALSE on err. BOOL stack(Imat& top, Imat& bot); // Merge to matrices, top-over-bot. // Retunr FALSE on err. //-------------------------------------- void zero(void); // fill matrix with zeroes void ident(void); // make identity matrix. void countR(void); // fill with counting; row-major void countC(void); // fill with counting; column-major void textOut(FILE* fptr, char* title, int linewidth); // make printout in stream 'fptr' void prnt(char *name); // Print to debug window via VC++ 'TRACE' }; #endif // conditional compile (#if defined _V_VECMAT at top of file).