Files
Seele/external/sdpa/sdpa_struct.h
T

575 lines
15 KiB
C++
Raw Normal View History

2023-01-21 18:43:21 +01:00
/* -------------------------------------------------------------
This file is a component of SDPA
Copyright (C) 2004-2013 SDPA Project
This program is 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 2 of the License, or
(at your option) any later version.
This program 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
------------------------------------------------------------- */
// printing presicion of vectors and matrices
#define P_FORMAT ((char*)"%+8.3e")
#define NO_P_FORMAT "NOPRINT"
#ifndef __sdpa_struct_h__
#define __sdpa_struct_h__
#include "sdpa_include.h"
#include "sdpa_block.h"
#include <cholmod.h>
#define DATA_CAPSULE 1
// DATA_CAPSULE 0 : Three Arrays (row,column,sp_ele)
// DATA_CAPSULE 1 : Capsuled data storage
namespace sdpa {
class CholmodMatrix;
class CholmodSpace;
class OrderingMatrix;
class OrderingSpace;
class Vector
{
public:
int nDim;
double* ele;
Vector();
Vector(int nDim, double value = 0.0);
~Vector();
void initialize();
void initialize(int nDim, double value = 0.0);
void initialize(double value);
void finalize();
void setZero();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void display(FILE* fpout,double scalar, char* printFormat = P_FORMAT);
bool copyFrom(Vector& other);
};
class BlockVector
{
public:
int nBlock;
int* blockStruct;
Vector* ele;
BlockVector();
BlockVector(BlockStruct& bs, double value = 0.0);
BlockVector(int nBlock, int* blockStruct, double value = 0.0);
~BlockVector();
void initialize(BlockStruct& bs, double value = 0.0);
void initialize(int nBlock, int* blockStruct, double value = 0.0);
void initialize(double value);
void finalize();
void setZero();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
bool copyFrom(BlockVector& other);
};
class SparseMatrix
{
public:
int nRow, nCol;
enum Type { SPARSE, DENSE};
Type type;
int NonZeroNumber;
// for memory
int NonZeroCount;
// currentry stored
int NonZeroEffect;
// use for calculation of F1,F2,F3
// for Dense
double* de_ele;
// for Sparse ; 0:sparse 1:dense
enum dsType {DSarrays, DScapsule};
dsType DataStruct;
// for Sparse Data1 // dsArrays
int* row_index;
int* column_index;
double* sp_ele;
// for Sparse Data2 // dsCapsule
typedef struct{
int vRow;
int vCol;
double vEle;
} SparseElement __attribute__( (aligned (16)));
SparseElement* DataS;
SparseMatrix();
SparseMatrix(int nRow,int nCol, Type type, int NonZeroNumber);
~SparseMatrix();
#if DATA_CAPSULE
void initialize(int nRow,int nCol, Type type, int NonZeroNumber,
dsType DataStruct = DScapsule);
#else
void initialize(int nRow,int nCol, Type type, int NonZeroNumber,
dsType DataStruct = DSarrays);
#endif
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
bool copyFrom(SparseMatrix& other);
void changeToDense(bool forceChange = false);
void setZero();
void setIdentity(double scalar = 1.0);
bool sortSparseIndex(int&i, int& j);
};
class DenseMatrix
{
public:
int nRow, nCol;
double* de_ele;
DenseMatrix();
~DenseMatrix();
void initialize();
void initialize(int nRow,int nCol);
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
bool copyFrom(DenseMatrix& other);
bool copyFrom(SparseMatrix& other);
void setZero();
void setIdentity(double scalar = 1.0);
};
class SparseLinearSpace
{
public:
int SDP_sp_nBlock;
int SOCP_sp_nBlock;
int LP_sp_nBlock;
int* SDP_sp_index;
int* SOCP_sp_index;
int* LP_sp_index;
SparseMatrix* SDP_sp_block;
SparseMatrix* SOCP_sp_block;
double* LP_sp_block;
SparseLinearSpace();
SparseLinearSpace(int SDP_nBlock, int* SDP_blockStruct,
int* SDP_NonZeroNumber,
int SOCP_nBlock, int* SOCP_blockStruct,
int* SOCP_NonZeroNumber,
int LP_nBlock, bool* LP_NonZeroNumber);
SparseLinearSpace(int SDP_sp_nBlock,
int* SDP_sp_index,
int* SDP_sp_blockStruct,
int* SDP_sp_NonZeroNumber,
int SOCP_sp_nBlock,
int* SOCP_sp_index,
int* SOCP_sp_blockStruct,
int* SOCP_sp_NonZeroNumber,
int LP_sp_nBlock,
int* LP_sp_index);
~SparseLinearSpace();
// dense form of block index
void initialize(int SDP_nBlock, int* SDP_blockStruct,
int* SDP_NonZeroNumber,
int SOCP_nBlock, int* SOCP_blockStruct,
int* SOCP_NonZeroNumber,
int LP_nBlock, bool* LP_NonZeroNumber);
// sparse form of block index 2008/02/27 kazuhide nakata
void initialize(int SDP_sp_nBlock,
int* SDP_sp_index,
int* SDP_sp_blockStruct,
int* SDP_sp_NonZeroNumber,
int SOCP_sp_nBlock,
int* SOCP_sp_index,
int* SOCP_sp_blockStruct,
int* SOCP_sp_NonZeroNumber,
int LP_sp_nBlock,
int* LP_sp_index);
void finalize();
void changeToDense(bool forceChange=false);
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
bool copyFrom(SparseLinearSpace& other);
void setElement_SDP(int block, int nCol, int nRow, double ele);
void setElement_SOCP(int block, int nCol, int nRow, double ele);
void setElement_LP(int block, double ele);
void setZero();
void setIdentity(double scalar = 1.0);
// no check
bool sortSparseIndex(int&l , int& i, int& j);
};
class DenseLinearSpace
{
public:
int SDP_nBlock;
int LP_nBlock;
DenseMatrix* SDP_block;
double* LP_block;
DenseLinearSpace();
DenseLinearSpace(BlockStruct& bs);
~DenseLinearSpace();
void initialize(BlockStruct& bs);
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void displaySolution(BlockStruct& bs, FILE* fpout = stdout,
char* printFormat = P_FORMAT);
bool copyFrom(DenseLinearSpace& other);
void setElement_SDP(int block, int nCol, int nRow, double ele);
void setElement_SOCP(int block, int nCol, int nRow, double ele);
void setElement_LP(int block, double ele);
void setZero();
void setIdentity(double scalar = 1.0);
};
// Input Matrix A_k for Compleition
// Column-Compressed structure
class CompMatrix
{
public:
int nRow;
int nCol;
int nzColumn; // nunmber of non-zero columns
int effectiveNzColumn; // nunmber of non-zero LOWER columns
int* column_index; // index of non-zero columns [length:nzColumn]
int NNZ; // number of non-zero
int lowerNNZ; // number of non-zero in lower triangular matrix
int* column_start; // starting point of each non-zero columns
// [length:nzColumn+1]
// the last one should be NNZ
int* row_index; // row-index of each element [length:NNZ]
double* ele; // value of each element [length:NNZ]
int* diag_index; // diagonal point of each non-zero columns
// [length:nzColumn]
// if diagonal is empty, diag_index[j] = -1;
int* agg_index; // aggregate index [length: NNZ]
// This element corresponds to X.ele[blockNumber].de_ele[blockIndex]
int* blockNumber;
int* blockIndex;
int nzColumn_diag; // number of LOWER non-zero columns with diagonal elements
int* column_diag_index;
int nzColumn_nondiag; // number of LOWER non-zero columns WITHOUT diagonal elements
int* column_nondiag_index;
class inputIJV
{
public:
int i;
int j;
double v;
};
vector<CompMatrix::inputIJV*>* inputVector;
// inputVector is the vector
// After makeInternalStructure(), this vector will be released
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void initialize();
CompMatrix();
void finalize();
~CompMatrix();
void initializeInputVector();
void setElement(int i, int j, double v);
static bool compareIJV(inputIJV* a, inputIJV* b);
void sortInputVector();
void makeInternalStructure();
void checkInputDataStructure(int& i, int& j, double& v1, double& v2);
void assignAgg(CholmodMatrix& cholmodMatrix);
// Aggregate contains only lower triangular
void assignBlockIndex(OrderingMatrix& order);
};
// diagonal block structure of CompMatrix
class CompSpace
{
public:
int LP_sp_nBlock;
int SDP_sp_nBlock;
int* LP_sp_index;
int* SDP_sp_index;
double* LP_sp_block;
CompMatrix* SDP_sp_block;
int NNZ;
int lowerNNZ;
// LP_agg_index is not neccesarry, because LP_sp_index does the same thing
CompSpace();
~CompSpace();
void initialize();
void initialize(int LP_sp_nBlock, int SDP_sp_nBlock);
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void initializeInputVector();
void setElement_LP(int i, double v);
void setElement_SDP(int l, int i, int j, double v);
void sortInputVector();
void makeInternalStructure();
void checkInputDataStructure(int& l, int& i, int& j, double& v1, double& v2);
void assignAgg(CholmodSpace& cholModSpace);
void assignBlockIndex(OrderingSpace& order);
};
// CliqueMatrix should be diagonal block of fully-dense matrix
// LP block is handled separately by CliqueSpace
class CliqueMatrix
{
public:
int nBlock;
int* blockStruct;
DenseMatrix* ele;
CliqueMatrix();
~CliqueMatrix();
void initialize();
void initialize(int nBlock, int* blockStruct);
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void setZero();
void setIdentity(double scalar = 1.0);
};
// diagonal block structure of CliqueMatrix
class CliqueSpace
{
public:
int LP_nBlock;
double* LP_block;
int SDP_nBlock;
CliqueMatrix* SDP_block; // each block is decomposed into multiple matrices
CliqueSpace();
~CliqueSpace();
void initialize();
void initialize(BlockStruct& bs, OrderingSpace& order);
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void setZero();
void setIdentity(double scalar = 1.0);
};
class OrderingMatrix
{
public:
int nClique;
int* cliqueSize; //length nCliques
// arrays of nCliques, i-th array has cliqueSize[i] length
int** cliqueIndex;
int nDim;
int* Perm;
int* ReversePerm;
// dXt means dX~tilde
// This matrix is nonsymemetric and [dX~]_{*k}
// is usually computed.
// By copying nonzero elements of [dX~]_{*k} to a clique structure,
// its efficiency will be enhanced.
// Details::
// The dXtildeIndex-th element of [dX~]_{*k} will be mapped to
// cliqueMatrix{dXtilde[k][dXtClique]}(dXtBlock);
// dXtBlock is the index of the corresponding block inside.
int* dXtNonzeros; // size of nDim
int** dXtIndex; // size of nDim*dXtNonzeros
int** dXtClique; // size of nDim*dXtNonzeros
int** dXtBlock; // size of nDim*dXtNonzeros
// tmporary class for making dXtNonzers, etc.
class ISB {
public:
int i;
int s;
int b; // blockIndex
};
static bool compareISB(ISB* a, ISB* b);
OrderingMatrix();
~OrderingMatrix();
void initialize();
void initialize(int nDim);
void finalize();
// A[i,j] * X[i,j] means A[i,j] * X.ele[blockNumber].ele[blockIndex]
void getIndex(int i, int j, int& blockNumber, int& blockIndex);
void extractCliques(CholmodMatrix& C);
void displayDxIndex(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void displayStatistics(FILE* fpout, CholmodMatrix& cholmodMatrix);
};
class OrderingSpace
{
public:
int SDP_nBlock;
OrderingMatrix* SDP_block;
OrderingSpace();
~OrderingSpace();
void initialize();
void initialize(int SDP_nBlock, int* SDP_blockStruct);
void finalize();
void displayDxIndex(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void displayStatistics(FILE* fpout, CholmodSpace& cholmodSpace);
void extractCliques(CholmodSpace& C);
};
class CholmodMatrix
{
public:
int nDim;
cholmod_sparse* Z;
cholmod_factor* Lz;
cholmod_factor* Lx;
cholmod_sparse* dZ;
cholmod_sparse* rD;
CliqueMatrix clique_xMat;
CliqueMatrix clique_dX;
CliqueMatrix clique_choleskyX;
CliqueMatrix clique_invCholeskyX;
cholmod_dense* x_x; // solution of cholmod_solve
cholmod_dense* x_z; // solution of cholmod_solve
cholmod_dense* b_x; // right-hand-side of cholmod_solve
cholmod_dense* b_z; // right-hand-side of cholmod_solve
cholmod_common common;
int NNZ_Z;
int NNZ_L;
int* Z_blockNumber;
int* Z_blockIndex;
CholmodMatrix();
~CholmodMatrix();
void initialize();
void finalize();
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
static void display_sparse(cholmod_sparse* A, FILE* fpout = stdout,
char* printFormat = P_FORMAT);
static void display_factor(cholmod_factor* L, FILE* fpout = stdout,
char* printFormat = P_FORMAT);
static void display_dense(cholmod_dense* X, FILE* fpout = stdout,
char* printFormat = P_FORMAT);
void analyze();
void solveByZ(); // b should be set properly before solve.
void solveByX(); // b should be set properly before solve.
void assignBlockIndex(OrderingMatrix& order);
static void setZero_sparse(cholmod_sparse* A);
void setZzero();
void setZIdentity(double scalar = 1.0);
void setXIdentity(double scalar = 1.0);
void setB_Zzero();
void setB_Xzero();
void setDxZero();
void initializeClique(OrderingMatrix& order);
bool getCholesky(OrderingMatrix& order);
};
class InputData;
// diagonal block structure of cholmod_sparse & cholmod_factor
// for Aggregate Matrix & Factorized Matrix
class CholmodSpace
{
public:
int LP_nBlock;
double* LP_Z;
double* LP_invZ;
double* LP_dZ;
double* LP_X;
double* LP_invX;
double* LP_dX;
int SDP_nBlock;
CholmodMatrix* SDP_block;
Vector yVec;
Vector dyVec;
Vector rp; // primal residual vector
double* LP_rD; // dual residual vector
CholmodSpace();
~CholmodSpace();
void initialize();
void initialize(int LP_nBlock, int SDP_nBlock);
void finalize();
void makeAggregate(int m, int SDP_nBlock, int* SDP_blockStruct,
CompSpace& C, CompSpace* A);
void assignBlockIndex(OrderingSpace& order);
void setZzero();
void setZIdentity(double scalar = 1.0);
void setXIdentity(double scalar = 1.0);
void display(FILE* fpout = stdout, char* printFormat = P_FORMAT);
void analyze();
void initializeClique(int m, OrderingSpace& order);
void getInnerProductAX(double& ret,
CompSpace& A, OrderingSpace& order);
void getInnerProductAdX(double& ret,
CompSpace& A, OrderingSpace& order);
void computeResiduals(InputData& inputData, OrderingSpace& order);
bool getCholesky(OrderingSpace& order);
};
} // end of namespace 'sdpa'
#endif // __sdpa_struct_h__