/*
 * Copyright (C) 1996-2011 Daniel Waggoner
 *
 * This free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * If you did not received a copy of the GNU General Public License
 * with this software, see <http://www.gnu.org/licenses/>.
 */

#include "matrix_test.hpp"

class TFunction_Node
{
private:
  TFunction *node;
  TFunction_Node *next;

public:
  TFunction_Node(TFunction *f, TFunction_Node *stack) { node=f; next=stack; };
  ~TFunction_Node();
  TFunction* GetNode() { return node; };
  TFunction_Node* Next() { return next; };
};
TFunction_Node* CreateFunctionList(void);

//===============================================================================
class CreateVector_T : public TFunction
{
public:
  CreateVector_T() : TFunction((char*)"CreateVector",(char*)"V(m)",(char*)"I(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class CreateMatrix_T : public TFunction
{
public:
  CreateMatrix_T() : TFunction((char*)"CreateMatrix",(char*)"M(m,n)",(char*)"I(m);I(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InitializeVector_T : public TFunction
{
public:
  InitializeVector_T() : TFunction((char*)"InitializeVector",(char*)"V(m)",(char*)"V(m)+;F") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InitializeMatrix_T : public TFunction
{
public:
  InitializeMatrix_T() : TFunction((char*)"InitializeMatrix",(char*)"M(m,n)",(char*)"M(m,n)+;F") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class EquateVector_T : public TFunction
{
public:
  EquateVector_T() : TFunction((char*)"EquateVector",(char*)"V(m)",(char*)"V(m)!+;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class EquateMatrix_T : public TFunction
{
public:
  EquateMatrix_T() : TFunction((char*)"EquateMatrix",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Transpose_T : public TFunction
{
public:
  Transpose_T() : TFunction((char*)"Transpose",(char*)"M(m,n)",(char*)"M(m,n)!+;M(n,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class IdentityMatrix_T : public TFunction
{
public:
  IdentityMatrix_T() : TFunction((char*)"IdentityMatrix",(char*)"M(m,m)",(char*)"M(m,m)!+;I(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class DiagonalMatrix_T : public TFunction
{
public:
  DiagonalMatrix_T() : TFunction((char*)"DiagonalMatrix",(char*)"M(n,m)",(char*)"M(m,n)!+;V(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class AbsV_T : public TFunction
{
public:
  AbsV_T() : TFunction((char*)"AbsV",(char*)"V(m)",(char*)"V(m)!+;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class AbsM_T : public TFunction
{
public:
  AbsM_T() : TFunction((char*)"AbsM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class MinusV_T : public TFunction
{
public:
  MinusV_T() : TFunction((char*)"MinusV",(char*)"V(m)",(char*)"V(m)!+;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class MinusM_T : public TFunction
{
public:
  MinusM_T() : TFunction((char*)"MinusM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InsertSubMatrix_T: public TFunction
{
public:
  InsertSubMatrix_T() : TFunction((char*)"InsertSubMatrix",(char*)"M(m,n)",
				  (char*)"M(m,n)+;M(r,s);I(?);I(?);I(?);I(?);I(?);I(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
  virtual int ArgumentsError(void);
  virtual void DefaultTestSizes(void);
};

//===============================================================================
class InsertColumnVector_T: public TFunction
{
public:
  InsertColumnVector_T() : TFunction((char*)"InsertColumnVector",(char*)"M(m,n)",(char*)"M(m,n)+;V(m);I(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class InsertRowVector_T: public TFunction
{
public:
  InsertRowVector_T() : TFunction((char*)"InsertRowVector",(char*)"M(m,n)",(char*)"M(m,n)+;V(n);I(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};


//===============================================================================
class SubMatrix_T: public TFunction
{
public:
  SubMatrix_T() : TFunction((char*)"SubMatrix",(char*)"M(m,n)",(char*)"M(m,n)!+;M(?,?);I(r);I(c);I(m);I(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class SubVector_T: public TFunction
{
public:
  SubVector_T() : TFunction((char*)"SubVector",(char*)"V(d)",(char*)"V(d)!+;V(?);I(b);I(d)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class ColumnVector_T: public TFunction
{
public:
  ColumnVector_T() : TFunction((char*)"ColumnVector",(char*)"V(m)",(char*)"V(m)!+;M(m,n);I(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class RowVector_T: public TFunction
{
public:
  RowVector_T() : TFunction((char*)"RowVector",(char*)"V(n)",(char*)"V(n)!+;M(m,n);I(?)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class ColumnMatrix_T: public TFunction
{
public:
  ColumnMatrix_T() : TFunction((char*)"ColumnMatrix",(char*)"M(m,?)",(char*)"M(m,?)!+;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class RowMatrix_T: public TFunction
{
public:
  RowMatrix_T() : TFunction((char*)"RowMatrix",(char*)"M(?,n)",(char*)"M(?,n)!+;V(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual void MakeSizeInvalid(int i);
  virtual int SizesOK(void);
};

//===============================================================================
class AddVV_T : public TFunction
{
public:
  AddVV_T() : TFunction((char*)"AddVV",(char*)"V(m)",(char*)"V(m)!+;V(m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class AddMM_T : public TFunction
{
public:
  AddMM_T() : TFunction((char*)"AddMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class SubtractVV_T : public TFunction
{
public:
  SubtractVV_T() : TFunction((char*)"SubtractVV",(char*)"V(m)",(char*)"V(m)!+;V(m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class SubtractMM_T : public TFunction
{

public:
  SubtractMM_T() : TFunction((char*)"SubtractMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductSV_T : public TFunction
{
public:
  ProductSV_T() : TFunction((char*)"ProductSV",(char*)"V(m)",(char*)"V(m)!+;F;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductVS_T : public TFunction
{
public:
  ProductVS_T() : TFunction((char*)"ProductVS",(char*)"V(m)",(char*)"V(m)!+;V(m);F") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductSM_T : public TFunction
{

public:
  ProductSM_T() : TFunction((char*)"ProductSM",(char*)"M(m,n)",(char*)"M(m,n)!+;F;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductMS_T : public TFunction
{
public:
  ProductMS_T() : TFunction((char*)"ProductMS",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);F") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductVM_T : public TFunction
{
public:
  ProductVM_T() : TFunction((char*)"ProductVM",(char*)"V(n)",(char*)"V(n)!+;V(m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductMV_T : public TFunction
{

public:
  ProductMV_T() : TFunction((char*)"ProductMV",(char*)"V(m)",(char*)"V(m)!+;M(m,n);V(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductMM_T : public TFunction
{

public:
  ProductMM_T() : TFunction((char*)"ProductMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,k);M(k,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductMU_T : public TFunction
{

public:
  ProductMU_T() : TFunction((char*)"ProductMU",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);U(n,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductML_T : public TFunction
{

public:
  ProductML_T() : TFunction((char*)"ProductML",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);L(n,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductUM_T : public TFunction
{

public:
  ProductUM_T() : TFunction((char*)"ProductUM",(char*)"M(m,n)",(char*)"M(m,n)!+;U(m,m);U(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductLM_T : public TFunction
{

public:
  ProductLM_T() : TFunction((char*)"ProductLM",(char*)"M(m,n)",(char*)"M(m,n)!+;L(m,m);U(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TransposeProductMM_T : public TFunction
{
public:
  TransposeProductMM_T() : TFunction((char*)"TransposeProductMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(r,m);M(r,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TransposeProductMV_T : public TFunction
{
public:
  TransposeProductMV_T() : TFunction((char*)"TransposeProductMV",(char*)"V(m)",(char*)"V(m)!+;M(n,m);V(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductTransposeVM_T : public TFunction
{
public:
  ProductTransposeVM_T() : TFunction((char*)"ProductTransposeVM",(char*)"V(m)",(char*)"V(m)!+;V(n);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductTransposeMM_T : public TFunction
{

public:
  ProductTransposeMM_T() : TFunction((char*)"ProductTransposeMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,r);M(n,r)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseVM_T : public TFunction
{
public:
  ProductInverseVM_T() : TFunction((char*)"ProductInverseVM",(char*)"V(m)",(char*)"V(m)!+;V(m);M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseMM_T : public TFunction
{
public:
  ProductInverseMM_T() : TFunction((char*)"ProductInverseMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);M(n,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseVU_T : public TFunction
{
public:
  ProductInverseVU_T() : TFunction((char*)"ProductInverseVU",(char*)"V(m)",(char*)"V(m)!+;V(m);U(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseMU_T : public TFunction
{
public:
  ProductInverseMU_T() : TFunction((char*)"ProductInverseMU",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);U(n,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseVL_T : public TFunction
{
public:
  ProductInverseVL_T() : TFunction((char*)"ProductInverseVL",(char*)"V(m)",(char*)"V(m)!+;V(m);L(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductInverseML_T : public TFunction
{
public:
  ProductInverseML_T() : TFunction((char*)"ProductInverseML",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);L(n,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};


//===============================================================================
class InverseProductMM_T : public TFunction
{
public:
  InverseProductMM_T() : TFunction((char*)"InverseProductMM",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InverseProductMV_T : public TFunction
{
public:
  InverseProductMV_T() : TFunction((char*)"InverseProductMV",(char*)"V(m)",(char*)"V(m)!+;M(m,m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InverseProductUM_T : public TFunction
{
public:
  InverseProductUM_T() : TFunction((char*)"InverseProductUM",(char*)"M(m,n)",(char*)"M(m,n)!+;U(m,m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InverseProductUV_T : public TFunction
{
public:
  InverseProductUV_T() : TFunction((char*)"InverseProductUV",(char*)"V(m)",(char*)"V(m)!+;U(m,m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InverseProductLM_T : public TFunction
{
public:
  InverseProductLM_T() : TFunction((char*)"InverseProductLM",(char*)"M(m,n)",(char*)"M(m,n)!+;L(m,m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InverseProductLV_T : public TFunction
{
public:
  InverseProductLV_T() : TFunction((char*)"InverseProductLV",(char*)"V(m)",(char*)"V(m)!+;L(m,m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Inverse_LU_T : public TFunction
{
public:
  Inverse_LU_T() : TFunction((char*)"Inverse_LU",(char*)"M(m,m)",(char*)"M(m,m)!+;M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Inverse_SVD_T : public TFunction
{
public:
  Inverse_SVD_T() : TFunction((char*)"Inverse_SVD",(char*)"M(m,m)",(char*)"M(m,m)!+;M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Inverse_Cholesky_T : public TFunction
{
public:
  Inverse_Cholesky_T() : TFunction((char*)"Inverse_Cholesky",(char*)"M(m,m)",(char*)"M(m,m)!+;SPD(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Inverse_UT_T : public TFunction
{
public:
  Inverse_UT_T() : TFunction((char*)"Inverse_UT",(char*)"M(m,m)",(char*)"M(m,m)!+;U(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Inverse_LT_T : public TFunction
{
public:
  Inverse_LT_T() : TFunction((char*)"Inverse_LT",(char*)"M(m,m)",(char*)"M(m,m)!+;L(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class GeneralizedInverse_T : public TFunction
{
public:
  GeneralizedInverse_T() : TFunction((char*)"GeneralizedInverse",(char*)"M(m,n)",(char*)"M(m,n)!+;M(n,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class SVD_T : public TFunction
{
public:
  SVD_T() : TFunction((char*)"SVD",(char*)"I",(char*)"M(m,a)!+;V(a)+;M(n,a)!+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
  virtual int ArgumentsError(void);
  virtual void DefaultTestSizes(void);
};

//===============================================================================
class QR_T : public TFunction
{
public:
  QR_T() : TFunction((char*)"QR",(char*)"I",(char*)"M(m,a)!+;M(a,n)+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
  virtual int ArgumentsError(void);
  virtual void DefaultTestSizes(void);
};

//===============================================================================
class CholeskyUT_T : public TFunction
{
public:
  CholeskyUT_T() : TFunction((char*)"CholeskyUT",(char*)"M(m,m)",(char*)"M(m,m)!+;SPD(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class CholeskyLT_T : public TFunction
{
public:
  CholeskyLT_T() : TFunction((char*)"CholeskyLT",(char*)"M(m,m)",(char*)"M(m,m)!+;SPD(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LU_T : public TFunction
{
public:
  LU_T() : TFunction((char*)"LU",(char*)"I",(char*)"P(m)+;M(m,n)+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LU_SolveCol_T : public TFunction
{
public:
  LU_SolveCol_T() : TFunction((char*)"LU_SolveCol",(char*)"V(m)",(char*)"V(m)!+;V(m);M(m,m);P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LU_SolveRow_T : public TFunction
{
public:
  LU_SolveRow_T() : TFunction((char*)"LU_SolveRow",(char*)"V(m)",(char*)"V(m)!+;V(m);M(m,m);P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TArgInc_EqualPointers_GeneralizedSchur_Real : public TArgInc
{
protected:
  int i;

public:
  TArgInc_EqualPointers_GeneralizedSchur_Real(TArgList* p_args, int min, int max) : TArgInc(p_args,min,max) { i=0; };
  TArgInc_EqualPointers_GeneralizedSchur_Real(TArgList* p_args, int nts, int* ts) : TArgInc(p_args,nts,ts) { i=0; };

  virtual int First(void) { i=0; args->ResetMinimalIndexes(); return Next(); };
  virtual int Next(void);
};
class GeneralizedSchur_Real_T : public TFunction
{
public:
  GeneralizedSchur_Real_T() : TFunction((char*)"GeneralizedSchur_Real",(char*)"I",(char*)"M(m,m)+;M(m,m)+;M(m,m)!+;M(m,m)!+;M(m,m);M(m,m);V(m)!+;V(m)!+;V(m)!+") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void DefaultTestSizes_InvalidNulls(void);
  virtual int TestEqualPointers(int min=-1, int max=-1);
};

//===============================================================================
class TArgInc_EqualPointers_ReorderGeneralizedSchur_Real : public TArgInc
{
protected:
  int i;

public:
  TArgInc_EqualPointers_ReorderGeneralizedSchur_Real(TArgList* p_args, int min, int max) : TArgInc(p_args,min,max) { i=0; };
  TArgInc_EqualPointers_ReorderGeneralizedSchur_Real(TArgList* p_args, int nts, int* ts) : TArgInc(p_args,nts,ts) { i=0; };

  virtual int First(void) { i=0; args->ResetMinimalIndexes(); return Next(); };
  virtual int Next(void);
};
class ReorderGeneralizedSchur_Real_T : public TFunction
{
protected:
  TMatrix A, B, Q, Z;
  TVector alpha_r, alpha_i, beta;
  PRECISION div;

public:
  ReorderGeneralizedSchur_Real_T() : TFunction((char*)"ReorderGeneralizedSchur_Real",(char*)"I",(char*)"M(m,m)+;M(m,m)+;M(m,m)!+;M(m,m)!+;M(m,m);M(m,m);M(m,m)!;M(m,m)!;pI(m)+;V(m)!+;V(m)!+;V(m)!+") { A=B=Q=Z=(TMatrix)NULL; alpha_r=alpha_i=beta=(TVector)NULL; };
  ~ReorderGeneralizedSchur_Real_T() { FreeMatrix(A); FreeMatrix(B); FreeMatrix(Q); FreeMatrix(Z); 
    FreeVector(alpha_r); FreeVector(alpha_i); FreeVector(beta); };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void Initialize(void);
  virtual void DefaultTestSizes_InvalidNulls(void);
  virtual int TestEqualPointers(int min=-1, int max=-1);
  virtual int TestSpeed(int size=10);
};

//===============================================================================
class TArgInc_EqualPointers_SortGeneralizedSchur_Real : public TArgInc
{
protected:
  int i;

public:
  TArgInc_EqualPointers_SortGeneralizedSchur_Real(TArgList* p_args, int min, int max) : TArgInc(p_args,min,max) { i=0; };
  TArgInc_EqualPointers_SortGeneralizedSchur_Real(TArgList* p_args, int nts, int* ts) : TArgInc(p_args,nts,ts) { i=0; };

  virtual int First(void) { i=0; args->ResetMinimalIndexes(); return Next(); };
  virtual int Next(void);
};
class SortGeneralizedSchur_Real_T : public TFunction
{
protected:
  TMatrix A, B, Q, Z;
  TVector alpha_r, alpha_i, beta;

public:
  SortGeneralizedSchur_Real_T() : TFunction((char*)"SortGeneralizedSchur_Real",(char*)"I",(char*)"M(m,m)+;M(m,m)+;M(m,m)!+;M(m,m)!+;M(m,m);M(m,m);M(m,m)!;M(m,m)!;V(m)+;V(m)+;V(m)+;I") { A=B=Q=Z=(TMatrix)NULL; alpha_r=alpha_i=beta=(TVector)NULL; };
  ~SortGeneralizedSchur_Real_T() { FreeMatrix(A); FreeMatrix(B); FreeMatrix(Q); FreeMatrix(Z); 
    FreeVector(alpha_r); FreeVector(alpha_i); FreeVector(beta); };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void Initialize(void);
  virtual void DefaultTestSizes_InvalidNulls(void);
  virtual int TestEqualPointers(int min=-1, int max=-1);
  virtual int TestSpeed(int size=10);
};

//===============================================================================
class Eigenvalues_T : public TFunction
{
public:
  Eigenvalues_T() : TFunction((char*)"Eigenvalues",(char*)"I",(char*)"V(m)+;V(m)+;M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  int ArgumentsError(void);
};

//===============================================================================
class Eigen_T : public TFunction
{
public:
  Eigen_T() : TFunction((char*)"Eigen",(char*)"I",(char*)"V(m)+;V(m)+;M(m,m)+;M(m,m)+;M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  int ArgumentsError(void);
};

//===============================================================================
class NullSpace_T : public TFunction
{
public:
  NullSpace_T() : TFunction((char*)"NullSpace",(char*)"M(n,?)",(char*)"M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class CreatePermutation_T : public TFunction
{
public:
  CreatePermutation_T() : TFunction((char*)"CreatePermutation",(char*)"P(m)",(char*)"I(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class EquatePermutation_T : public TFunction
{
public:
  EquatePermutation_T() : TFunction((char*)"EquatePermutation",(char*)"P(m)",(char*)"P(m)!+;P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class PermutationMatrix_T : public TFunction
{
public:
  PermutationMatrix_T() : TFunction((char*)"PermutationMatrix",(char*)"M(m,m)",(char*)"M(m,m)!+;P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TranspositionPermutation_T : public TFunction
{
public:
  TranspositionPermutation_T() : TFunction((char*)"TranspositionPermutation",(char*)"P(m)",(char*)"P(m)!+;I(?);I(?);I(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
  virtual void MakeSizeInvalid(int i);
};

//===============================================================================
class InitializePermutation_T : public TFunction
{
public:
  InitializePermutation_T() : TFunction((char*)"InitializePermutation",(char*)"P(m)",(char*)"P(m)!+;pI(m);I(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductPM_T : public TFunction
{
public:
  ProductPM_T() : TFunction((char*)"ProductPM",(char*)"M(m,n)",(char*)"M(m,n)!+;P(m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductMP_T : public TFunction
{
public:
  ProductMP_T() : TFunction((char*)"ProductMP",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);P(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductPV_T : public TFunction
{
public:
  ProductPV_T() : TFunction((char*)"ProductPV",(char*)"V(m)",(char*)"V(m)!+;P(m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductVP_T : public TFunction
{
public:
  ProductVP_T() : TFunction((char*)"ProductVP",(char*)"V(m)",(char*)"V(m)!+;V(m);P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TransposeProductPM_T : public TFunction
{
public:
  TransposeProductPM_T() : TFunction((char*)"TransposeProductPM",(char*)"M(m,n)",(char*)"M(m,n)!+;P(m);M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductTransposeMP_T : public TFunction
{
public:
  ProductTransposeMP_T() : TFunction((char*)"ProductTransposeMP",(char*)"M(m,n)",(char*)"M(m,n)!+;M(m,n);P(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class TransposeProductPV_T : public TFunction
{
public:
  TransposeProductPV_T() : TFunction((char*)"TransposeProductPV",(char*)"V(m)",(char*)"V(m)!+;P(m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class ProductTransposeVP_T : public TFunction
{
public:
  ProductTransposeVP_T() : TFunction((char*)"ProductTransposeVP",(char*)"V(m)",(char*)"V(m)!+;V(m);P(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Norm_T : public TFunction
{
public:
  Norm_T() : TFunction((char*)"Norm",(char*)"F",(char*)"V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class MatrixNormEuclidean_T : public TFunction
{
public:
  MatrixNormEuclidean_T() : TFunction((char*)"MatrixNormEuclidean",(char*)"F",(char*)"M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class MatrixNorm_T : public TFunction
{
public:
  MatrixNorm_T() : TFunction((char*)"MatrixNorm",(char*)"F",(char*)"M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class DotProduct_T : public TFunction
{
public:
  DotProduct_T() : TFunction((char*)"DotProduct",(char*)"F",(char*)"V(m);V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class InnerProduct_T : public TFunction
{
public:
  InnerProduct_T() : TFunction((char*)"InnerProduct",(char*)"F",(char*)"V(m);V(m);S(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class OuterProduct_T : public TFunction
{
public:
  OuterProduct_T() : TFunction((char*)"OuterProduct",(char*)"M(m,n)",(char*)"M(m,n)!+;V(m);V(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class CrossProduct_LU_T : public TFunction
{
public:
  CrossProduct_LU_T() : TFunction((char*)"CrossProduct_LU",(char*)"V(?)",(char*)"V(?)!+;M(?,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
};

//===============================================================================
class Trace_T : public TFunction
{
public:
  Trace_T() : TFunction((char*)"Trace",(char*)"F",(char*)"M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class Vec_T : public TFunction
{
public:
  Vec_T() : TFunction((char*)"Vec",(char*)"V(?)",(char*)"V(?)!+;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
};

//===============================================================================
class ReshapeV_T : public TFunction
{
public:
  ReshapeV_T() : TFunction((char*)"ReshapeV",(char*)"M(m,n)",(char*)"M(m,n)!+;V(?);I(m);I(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
};

//===============================================================================
class Rank_SVD_T : public TFunction
{
public:
  Rank_SVD_T() : TFunction((char*)"Rank_SVD",(char*)"I",(char*)"M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class KroneckerProduct_T : public TFunction
{
public:
  KroneckerProduct_T() : TFunction((char*)"KroneckerProduct",(char*)"M(?,?)",(char*)"M(?,?)!+;M(m,n);M(r,s)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual void ComputeCorrectSizes(void);
  virtual int SizesOK(void);
};

//===============================================================================
class ComplexProductMM_T : public TFunction
{
public:
  ComplexProductMM_T() : TFunction((char*)"ComplexProductMM",(char*)"I",(char*)"M(m,n)+;M(m,n)+;M(m,k);M(m,k);M(k,n);M(k,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
  virtual int ArgumentsError(void);
};

//===============================================================================
class Determinant_LU_T : public TFunction
{
public:
  Determinant_LU_T() : TFunction((char*)"Determinant_LU",(char*)"F",(char*)"M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LogAbsDeterminant_LU_T : public TFunction
{
public:
  LogAbsDeterminant_LU_T() : TFunction((char*)"LogAbsDeterminant_LU",(char*)"F",(char*)"M(m,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LinearCombinationV_T : public TFunction
{
public:
  LinearCombinationV_T() : TFunction((char*)"LinearCombinationV",(char*)"V(m)",(char*)"V(m)!+;F;V(m);F;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class LinearCombinationM_T : public TFunction
{
public:
  LinearCombinationM_T() : TFunction((char*)"LinearCombinationM",(char*)"M(m,n)",(char*)"M(m,n)!+;F;M(m,n);F;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class UpdateM_T : public TFunction
{
public:
  UpdateM_T() : TFunction((char*)"UpdateM",(char*)"M(m,n)",(char*)"F;M(m,n)+;F;M(m,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class UpdateV_T : public TFunction
{
public:
  UpdateV_T() : TFunction((char*)"UpdateV",(char*)"V(m)",(char*)"F;V(m)+;F;V(m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class UpdateProductMV_T : public TFunction
{
public:
  UpdateProductMV_T() : TFunction((char*)"UpdateProductMV",(char*)"V(m)",(char*)"F;V(m)+;F;M(m,n);V(n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class UpdateProductVM_T : public TFunction
{
public:
  UpdateProductVM_T() : TFunction((char*)"UpdateProductVM",(char*)"V(m)",(char*)"F;V(m)+;F;V(n);M(n,m)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};

//===============================================================================
class UpdateProductMM_T : public TFunction
{
public:
  UpdateProductMM_T() : TFunction((char*)"UpdateProductMM",(char*)"M(m,n)",(char*)"F;M(m,n)+;F;M(m,k);M(k,n)") { };
  virtual int CallFunction(void);
  virtual PRECISION ResultOK(void);
};


