//////////////////////////////////////////////////////////////////////////////
//
//       Title           : MathTut5.cpp
//       Project         : OSCAR
//       Created         : 7/31/2003
//       Author          : Peter S. March
//       Platforms       : All
///      Copyright       : Copyright© The University of Texas at Austin, 2002. All rights reserved.
///                 
///          This software and documentation constitute an unpublished work
///          and contain valuable trade secrets and proprietary information
///          belonging to University.  None of the foregoing material may be
///          copied  or duplicated or disclosed without the express, written
///          permission of University.  UNIVERSITY EXPRESSLY DISCLAIMS ANY
///          AND ALL WARRANTIES CONCERNING THIS SOFTWARE AND DOCUMENTATION,
///          INCLUDING ANY WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
///          PARTICULAR PURPOSE, AND WARRANTIES OF PERFORMANCE, AND ANY WARRANTY
///          THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF TRADE.
///          NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO THE USE OF
///          THE SOFTWARE OR DOCUMENTATION.  Under no circumstances shall
///          University be liable for incidental, special, indirect, direct or
///          consequential damages or loss of profits, interruption of business,
///          or related expenses which may arise from use of software or documentation,
///          including but not limited to those resulting from defects in software
///          and/or documentation, or loss or inaccuracy of data of any kind.
//       Access          : Company Confidential
//       Purpose         :
//
//----------------------------------------------------------------------------
//
//       Classes:
//               <none>
//
//       Global Functions:
//               <none>
//
//       Global Variables:
//               <none>
//
//----------------------------------------------------------------------------
//
//       $Revisions$
//
//       $Log: MathTut5.cpp,v $
//       Revision 1.4  2006/08/25 19:42:11  jknoll
//       now compatible with current OSCAR
//
//       Revision 1.3  2005/01/11 17:41:18  pmarch
//       no message
//
//       Revision 1.2  2003/09/26 16:25:49  pmarch
//       Changed project settings to match new CVS structure and made minor formatting changes.
//
//       Revision 1.1  2003/08/14 16:46:48  pmarch
//       no message
//
//
//////////////////////////////////////////////////////////////////////////////

#include "Math/Vector.h"
#include "Math/Matrix.h"
#include "Math/MathUtilities.h"

using namespace OSCAR;
using namespace std;


int main(void){
  //Create the first 4x4 square matrix
  Matrix matrix(4,4);
 
  //Fill the matrix with data.  The at() method is used here to
  //access paticular data members
  matrix.at(0,0)=1.0;  matrix.at(0,1)=0.5;  matrix.at(0,2)=3.1;  matrix.at(0,3)=5.0;
  matrix.at(1,0)=2.3;  matrix.at(1,1)=2.7;  matrix.at(1,2)=2.0;  matrix.at(1,3)=1.0;
  matrix.at(2,0)=1.7;  matrix.at(2,1)=0.5;  matrix.at(2,2)=0.7;  matrix.at(2,3)=1.5;
  matrix.at(3,0)=2.0;  matrix.at(3,1)=0.2;  matrix.at(3,2)=1.1;  matrix.at(3,3)=0.1;

  //calculate and display the infinity norm
  cout << "Infinity Norm: " << matrix.MatrixNorm(6) << endl;

  //calculate and display the froebenius norm
  cout << "Froebenius Norm: " << matrix.MatrixNorm(9) << endl << endl;

  //Create the first 4x5 matrix
  Matrix matrix2(4,5);
 
  //Fill the matrix with data.  The at() method is used here to
  //access paticular data members
  matrix2.at(0,0)=1.0;  matrix2.at(0,1)=0.5;  matrix2.at(0,2)=3.1;  matrix2.at(0,3)=5.0;  matrix2.at(0,4)=0.5;
  matrix2.at(1,0)=2.3;  matrix2.at(1,1)=2.7;  matrix2.at(1,2)=2.0;  matrix2.at(1,3)=1.0;  matrix2.at(1,4)=3.4;
  matrix2.at(2,0)=1.7;  matrix2.at(2,1)=0.5;  matrix2.at(2,2)=0.7;  matrix2.at(2,3)=1.5;  matrix2.at(2,4)=2.1;
  matrix2.at(3,0)=2.0;  matrix2.at(3,1)=0.2;  matrix2.at(3,2)=1.1;  matrix2.at(3,3)=0.1;  matrix2.at(3,4)=4.2;

  //create necessary objects to hold info
  //from SVD

  //U must be of size nrow x ncol
  Matrix U(4,5);
  
  //W must be of size ncol
  Vector W(5);

  //V must be of size ncol x ncol
  Matrix V(5,5);

  //Call the SVD() method to perform a Singular Value
  //Decomposition on the matrix.  If this method fails,
  //display the error.
  if (matrix2.SVD(U,W,V)){

    //U and V are orthogonal matrices.  This means that
    //V multiplied by V transpose should be the Identity
    //Matrix.
    cout << "V times V Transpose: " << endl << V * V.t() << endl << endl;

    //Fit the W vector into a Matrix where the values
    //of W are placed on the diagonal.  The final column
    //will all be zeros.
    Matrix tempMat(5,5);
    for (unsigned int i=0;i<4;i++)
      tempMat.at(i,i)=W.at(i);
	cout << "W (eigen vector) diagonal matrix: " << endl << tempMat << endl << endl;

    //U times W times V transpose should yield the original
    //matrix.
    cout << "U*W*Vtranspose: " << endl << (U*tempMat)*V.t() << endl;
  }
  else{
    OSCARError err=matrix.GetError();
    cout << err.GetCustomDescription() << endl;
  }
  return 0;
}