 /******************
 * Simple Math     *
 *                 *
 * Marcelo Gattass *
 * Dec01,2005      *
 ******************/

/*
 * Vectors are represented in ANSI C as double*
 * Matrices are stored as vectors in a line by line fashion.
 * i.e., the ij element of a matrix Amxn (m rowns and n coluns) is 
 * stored in the i*n+j  position of the vector that stores the 
 * matrix.
 *
 * The ideia is to enable simple matrix creations such as:
   double a[2*3] = {  1., 2., 7.,
                     -1., 5., 4.};
 * This ANSI C statment declares and stores the 2x3 matrix:
 *     |  1. 2. 7. |
 *     | -1  5. 4. |
 */
 
 /*
 * Computes the Singlar Value Decomposition of a matrix [a]
 * i.e.: [a]=[u][d][v]T
 * input: 
 *   [a] = a mxn matrix.
 *    m  = number of rows of matrix [a].
 *    n  = number of coluns of matrix [a].
 * 
 * output:
 *   [u] = a mxn matrix (columns are orthogonal vectors).
 *   {d} = 1xn matrix that contains the elements of the diagonal matrix [d](nxn).
 *   [v] = a nxn orthogonal matrix.
 *
 * temporary space:
 *  {tmp}= a temporary 1xn vector (space used by the function).
 *
 */ 
int smSVD(double* a, int m, int n, double* u, double* d, double* v, double* tmp);

/* 
 * Add the tensor product of the vector {v} (i.e., {v}{v}T) 
 * to the matrix [A].  
 * [A]+={v}{v}T
 *
 */
void smAddMatVecTensor(double* a, double* v, int n);

/* {x}=[A]{b}    Dimensions: [A]=mxn, {b}=m and {x}=n. */
void smAb(double* a, double* b, int m, int n, double* x);

/* {x}=[A]T{b}    Dimensions: [A]=mxn, {b}=m and {x}=n. */
void smAtb(double* a, double* b, int m, int n, double* x);

/* [X]=[A][B]    Dimensions: [A]=mxp, [B]=pxn and [X]=mxn. */
void smAB(double* a, double* b, int m, int p, int n, double* x);

/* [X]=[A][B]T    Dimensions: [A]=mxp, [B]=nxp and [X]=mxn. */
void smABt(double* a, double* b, int m, int p, int n, double* x);

/*  [X]=[A]T[B]    Dimensions: [A]=mxp, [B]=mxn and [X]=pxn */
void smAtB(double* a, double* b, int m, int p, int n, double* x);

/*  [X]=[A]+[B]    Dimensions: [A]=mxn, [B]=mxn and [X]=mxn */
void smAddMat(double* a, double* b, int m, int n, double* x);

/*  [X]=[A]-[B]    Dimensions: [A]=mxn, [B]=mxn and [X]=mxn */
void smSubMat(double* a, double* b, int m, int n, double* x);

/*  [X]=s[A]    Dimensions: [A]=mxn and [X]=mxn */
void smScaMat(double* a, double s,int m, int n, double* x);

/*  [X]=[A]T    Dimensions: [A]=mxn and [X]=nxm */
void smAt(double* a, int m, int n, double* x);

/*  [X]=[A]    Dimensions: [A]=mxn and [X]=mxn */
void smMatCopy(double* a, int m, int n, double* x);

/*  {x}={v}+{u}  Dimensions: {v}=m, {u}=m and {x}=m */
void smAddVec(double* u, double* v, int m, double* x);

/*  {x}={v}-{u}  Dimensions: {v}=m, {u}=m and {x}=m */
void smSubVec(double* u, double* v, int m, double* x);

/*  {x}=s{u}  Dimensions: {u}=m and {x}=m */
void smScaVec(double* u, int m,  double s, double* x);

/*  s={v}.{u}  Dimensions: {v}=m and  {u}=m */
double smDotProd(double* u, double* v, int m);

/* Print matrix */
void smShowMat(char * title, double *a, int m, int n);

/* Print vector */
void smShowVec(char * title, double *v, int n);


