Commit c4fdc197 authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

Inexact Breakdown on R0 is now detected, and is present in default version of Arnoldi_IB

parent a0a0c3a5
......@@ -8,7 +8,7 @@
typedef void* IbGMResDr_handle;
/**
* @file Header for using the Ib-GMRes-Dr library from C.
* @file Ib-GMRes-Dr.h Header for using the Ib-GMRes-Dr library from C.
*
* @brief This Library is Matrix free, meaning that the user must
* provide a method to compute a Matrix x Block of Vector
......
......@@ -54,7 +54,7 @@ option(BUILD_WARNINGS "Build with warning options" ON)
if(DEBUG_MODE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -O0")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
......
......@@ -864,7 +864,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/image_dox
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
......
......@@ -24,7 +24,19 @@ This library does not implement the Matrix Product. Thus, the user
must provide to the library a Matrix x block of vector product. To
provide it, the user must pass it through a function pointer with the
C Api, or by providing a Matrix class similar to the one displayed and
used inside the examples provided. (testMatrixMarket ...).
used inside the examples provided. (testMatrixMarket ...). Similarly,
the user can provide a right preconditionner, to be used during
computation.
\subsection perfs Performances
This graphe plots the min and max residual of the block solution
during the algorithm. On the x axis, is displayed the number of
Matrice Vector products needed to achieve the error displayed.
@image html MatCone_matvect.png
@image html MatCone_IB_matvect.png
\section qstart Quick Start
......
......@@ -99,6 +99,7 @@ struct Arnoldi{
//Tests over criterion
Hess.ComputeBlockResidual(R1,Yj);
std::cout<<"["<<j<<"]\t"<<"Residual computed"<<std::endl;
std::pair<Primary,Primary> MinMax;
{//Display residual to see convergence
......@@ -138,6 +139,7 @@ struct Arnoldi{
}
}
std::cout<<"################# Iterations done ... "<<j<<"\n";
returned_struct.sizeKSpace = (j+1)*SizeBlock;
returned_struct.nbIteDone = j;
returned_struct.hasConverged = convergence;
return returned_struct;
......
......@@ -37,16 +37,10 @@ struct Arnoldi_IB{
//Return struct
ArnReturn returned_struct;
//We store the size of each block -- Could be delegated to a class ?
// std::vector<int> sizeOfEachBlock;
// sizeOfEachBlock.reserve(max_iter);
// sizeOfEachBlock.push_back(SizeBlock);
std::vector<int> sumOfSizeOfEachBlock;
sumOfSizeOfEachBlock.push_back(SizeBlock);
returned_struct.sizeKSpace = 0;
//Set the hessenberg
HessExtended<Scalar> L(MaxKSize,SizeBlock);
HessExtended<Scalar,Primary> L(MaxKSize,SizeBlock);
Base<Scalar,Primary> base(SizeBlock,MaxKSize,dim);
//Create Block to Store W and P (if IB happens)
BlockWP<Scalar,Primary> WP(SizeBlock,dim);
......@@ -62,18 +56,86 @@ struct Arnoldi_IB{
R0.getPtr(i)[k] = B.getPtr(i)[k] - R0.getPtr(i)[k];
}
}
Block<Scalar,Primary> V1(SizeBlock,dim);
Block<Scalar,Primary> R1(SizeBlock,SizeBlock);
Block<Scalar,Primary> q0(SizeBlock,dim);
Block<Scalar,Primary> r0(SizeBlock,SizeBlock);
//Q-R Decomposition of (R0)
R0.ComputeQRFacto(V1,R1);
//First block of base added
base.addBlockDatas(V1);
R0.ComputeQRFacto(q0,r0);
//here, insert inexact breakdown on R0
{
//Copy r0 because needed to compute Lambda, but is
//destroyed if SVD is called
Block<Scalar,Primary> r0_cpy(SizeBlock,SizeBlock);
r0_cpy.CopyBlock(r0);
//U is of full size, in order to get all the left singular vectors
Block<Scalar,Primary> U{r0.getSizeBlock(),r0.getLeadingDim()};
//SVD
int nbKDir = r0_cpy.DecompositionSVD(U,epsilon);
//Test if needed to launch algorithm again
if(nbKDir == 0){
std::cout<<"\t\tINEXACT BREAKDOWN on R0\n";
std::cout<<"\t\tNb Kept Dir :"<<nbKDir<<"/"<<SizeBlock<<std::endl;
returned_struct.sizeKSpace = 0;
returned_struct.nbIteDone = 0;
returned_struct.hasConverged = true;
return returned_struct;
}
if(nbKDir == SizeBlock){
std::cout<<"\t\tNo INEXACT BREAKDOWN on R0\n";
//First block of base added
base.addBlockDatas(q0);
L.initLambda(r0);
}else{
std::cout<<"\t\tINEXACT BREAKDOWN on R0\n";
std::cout<<"\t\tNb Kept Dir :"<<nbKDir<<"/"<<SizeBlock<<std::endl;
//Block empty that will contains the first base vectors
Block<Scalar,Primary> V1ToBeAdded{nbKDir,dim};
//V1ToBeAdded = V1 * U1
call_gemm<>(dim,nbKDir,SizeBlock,
q0.getPtr(),q0.getLeadingDim(),
U.getPtr(),U.getLeadingDim(),
V1ToBeAdded.getPtr(),V1ToBeAdded.getLeadingDim(),
Scalar(1),Scalar(0));
//P = V1*U2
call_gemm<>(dim,SizeBlock-nbKDir,SizeBlock,
q0.getPtr(),q0.getLeadingDim(),
U.getPtr(nbKDir),U.getLeadingDim(),
WP.getP(),WP.getLeadingDim(),
Scalar(1),Scalar(0));
WP.incSizeP(SizeBlock-nbKDir);
base.addBlockDatas(V1ToBeAdded);
//Create a Lambda1 = [U1,U2]^{H} * R0;
Block<Scalar,Primary> Lambda1{SizeBlock,SizeBlock};
call_Tgemm<>(SizeBlock,SizeBlock,SizeBlock,
U.getPtr(),U.getLeadingDim(),
r0.getPtr(),r0.getLeadingDim(),
Lambda1.getPtr(),Lambda1.getLeadingDim(),
Scalar(1),Scalar(0));
L.initLambda(Lambda1);
//Create and initialize Phi (\Phi_1)
L.initPhi(nbKDir);
}
}
//We store the size of each block -- Could be delegated to a class ?
std::vector<int> sumOfSizeOfEachBlock;
sumOfSizeOfEachBlock.push_back(SizeBlock - WP.getSizeP());
//Nb directions discarded
int nbDeflDir = 0;
bool convergence = false;
int nbDeflDir = WP.getSizeP();
bool convergence = (nbDeflDir == SizeBlock);
//Counter
int j=0;
while(j<max_iter){ //Main Loop
double timestamp = Logger<Primary>::GetTime();
std::cout<<"\t\tStart of Iteration\n";
......@@ -92,6 +154,7 @@ struct Arnoldi_IB{
A.MatBaseProduct(base.getPtr(base.getCurrentBlock()-1),WP.getSizeW(),
WP.getW());
}
returned_struct.sizeKSpace += WP.getSizeW();
//Ortho against V and store coeff inside new block column of Hess L
base.ComputeMGSOrtho(WP,toWrite,L.getLeadingDim(),WP.getSizeP());
std::cout<<"Ortho against V and P"<<std::endl;
......@@ -104,10 +167,13 @@ struct Arnoldi_IB{
//Create Block and Residual
Block<Scalar,Primary> Res(SizeBlock,L.getNbLineUsed() + SizeBlock);
//Compute residual
L.ComputeResidual(R1,Y,Res);
L.ComputeResidual(Y,Res);
std::cout<<"\nResidual Computed ...\n";
Block<Scalar,Primary> Directions(SizeBlock,SizeBlock);
//Do we really need that ?
std::pair<Primary,Primary> MinMax = Res.getMinMaxNorm();
std::cout<<"Ite ["<<j<<"] Done\t"<<
......@@ -125,11 +191,11 @@ struct Arnoldi_IB{
//Block to Store U
Block<Scalar,Primary> U;
Res.DecompositionSVD(U,epsilon);
int nbDirKept = Res.DecompositionSVD(U,epsilon);
std::cout<<"Decomposition SVD done !\n\t\tSingular Values kept "
<<U.getSizeBlock()<<" !"<<std::endl;
<<nbDirKept<<" !"<<std::endl;
//Here : If no inexact breakdowns occured, updates procedures are easiers
//Here : If no inexact breakdowns occured, updates procedures are easier
if(U.getSizeBlock() == SizeBlock){
//Augment base : [P_{j-1},~Wj] = [~Wj]
base.addBlockDatas(WP);
......@@ -139,11 +205,16 @@ struct Arnoldi_IB{
}
std::cout<<"### Inexact Breakdowns Occured ###!\t\t Ite : \t"<<j<<"\n";
//Create Block to store \W
Block<Scalar,Primary> Directions(SizeBlock,SizeBlock);
Block<Scalar,Primary> tempRpart;
//Qr facto of bottom block of U
std::cout<<"About to compute QR of bottom part of U\n"
<<"Starting point : "<<sumOfSizeOfEachBlock.back()
<<"\n";
U.ComputeQRFacto(Directions,tempRpart,sumOfSizeOfEachBlock.back());
//Update Phi with directions (W1W2), doc Annexe Eq 2.7
L.updatePhi(Directions,nbDirKept);
//Update
//V_{j+1} = [P_{j-1},~Wj] * Directions_1
......@@ -157,7 +228,6 @@ struct Arnoldi_IB{
}
//Pj = [P_{j-1},~Wj] * Directions_2
WP.ComputeProduct(Directions,U.getSizeBlock());
//L.displayHessExtended("hess before update bottom line");
//L_{j+1,} = | Directions_1^{H} | * H_j
//Gj = | Directions_2^{H} |
L.UpdateBottomLine(Directions);
......
......@@ -102,6 +102,7 @@ struct Arnoldi_QRInc{
//Tests over criterion
std::pair<Primary,Primary> MinMax = Hess.LeastSquare(Yj,epsilon);
std::cout<<"["<<j<<"]\t"<<"Residual computed\n"
<<"\t\tMin\t"<<MinMax.first<<"\tMax\t"<<MinMax.second
<<std::endl;
......@@ -140,6 +141,7 @@ struct Arnoldi_QRInc{
}
}
std::cout<<"################# Iterations done ... "<<j<<"\n";
returned_struct.sizeKSpace = (j+1)*SizeBlock;
returned_struct.nbIteDone = j;
returned_struct.hasConverged = convergence;
return returned_struct;
......
......@@ -70,11 +70,14 @@ int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0,
ArnReturn ret = Arn::Exec_Procedure(A,X0,B,arnoldi_ite,MaxKSize,epsilon,log);
nbIteDone+=ret.nbIteDone;
std::cout<<"\n################## Restart Done "<<nb_restart
<<" #################\n";
std::cout<<"\n################## Total iterations "<<nbIteDone
<<" #################\n";
std::cout<<"######################################################\n";
std::cout<<"\t\t Restart Done "<<nb_restart
<<"\n";
std::cout<<"\t\t Total iterations "<<nbIteDone
<<"\n";
std::cout<<"\t\t Size of Krylov Space "<<ret.sizeKSpace
<<"\n";
std::cout<<"######################################################\n";
//Three case :
//--1 Arnoldi converged
//--2 Arnoldi reached Max Krylov Size allowed
......
......@@ -58,6 +58,7 @@ public:
std::cout<<name<<"\t LeadingDim x SizeBlock : "<<getLeadingDim()
<<" x "<<getSizeBlock()<<"\n";
for(int a=0 ; a<SizeBlock ; ++a){
std::cout<<"["<<a<<"] ";
for(int b=0 ; b<ldb ; ++b){
std::cout<<datas[a*ldb+b]<<"\t";
}
......@@ -247,8 +248,13 @@ public:
/**
* @brief Compute SVD of current block, and write down U inside
* output, and Singular Values inside sigma.
* @param U, output block. Will contain only the vectors
* corresponding to the singular values superior to the threshold
* given.
* @param epsilon, treshold
*/
void DecompositionSVD(Block<Scalar,Primary>& output, Primary epsilon){
int DecompositionSVD(Block<Scalar,Primary>& output, Primary epsilon){
//What I need:
char jobu = 'S'; //jobu : S --> Only first size_block vectors computed
char jobvt = 'N'; //jobvt : N --> no part of V^{H} is computed
......@@ -278,15 +284,17 @@ public:
while(id<getSizeBlock() && sigma[id]>epsilon){
id++;
}
//Display all the singular values
// for(int i=0 ; i<getSizeBlock() ; ++i){
// std::cout<<"sigma["<<i<<"]\t : "<<sigma[i]<<"\n";
// }
//std::cout<<"Number of sv sup. to "<<epsilon<<"\t: "<<id<<"\n";
output.initData(id,getLeadingDim());
memcpy(output.getPtr(),U.getPtr(),sizeof(Scalar)*id*U.getLeadingDim());
//Test if output is already allocated
if(output.getSizeBlock() != 0){ //Fill the output with vectors from U
memcpy(output.getPtr(),U.getPtr(),
sizeof(Scalar)*output.getSizeBlock() * U.getLeadingDim());
}else{//Only fill ouptut with vctors corresponding to the directions kept
output.initData(id,getLeadingDim());
memcpy(output.getPtr(),U.getPtr(),sizeof(Scalar)*id*U.getLeadingDim());
}
delete [] sigma;
delete [] superb;
return id;
}
};
......
......@@ -35,6 +35,10 @@ public:
return Parent::getSizeBlock()-cursor;
}
void incSizeP(int inc){
cursor += inc;
}
/**
* @brief Compute C = P^{H} * W and then W = W-C*P
*
......@@ -121,6 +125,7 @@ public:
input.getPtr(nbKeptDir),input.getLeadingDim(),
temp.getPtr(),temp.getLeadingDim(),
Scalar(1),Scalar(0));
//temp will be copied back inside P part, and cursor will be
//updated
memcpy(getP(),temp.getPtr(),
......
......@@ -9,10 +9,10 @@
* Ib-BGMRes version.
*
*/
template<typename Scalar>
template<typename Scalar,typename Primary=Scalar>
class HessExtended{
//Relative to global parameters
int p; //Size of first block
int p; //Number of RHS
//Relative to total size
int MaxKSize;
......@@ -34,6 +34,11 @@ class HessExtended{
//Datas:
Scalar * data;
//Storage of what's needed to compte the rhs for Least square
//Ref : IB BGMRes Dr : Page 10.
Block<Scalar,Primary> * Phi;
Block<Scalar,Primary> * Lambda1;
public:
/**
* @param inMaxKSize : Maximum size of Krylov search space
......@@ -43,7 +48,8 @@ public:
MaxKSize(inMaxKSize),
ldHess(inMaxKSize+inP),
nbBlckColUsed(0),
nbLineUsed(0),data(nullptr){
nbLineUsed(0),data(nullptr),
Phi(nullptr),Lambda1(nullptr){
data = new Scalar[ldHess*MaxKSize];
memset(data,0,sizeof(Scalar)*ldHess*MaxKSize);
sumNbVectInBlck.push_back(0);
......@@ -56,8 +62,43 @@ public:
~HessExtended(){
delete [] data;
if(Lambda1)
delete Lambda1;
if(Phi)
delete Phi;
}
void initLambda(Block<Scalar,Primary>& lambda){
//Check
if(lambda.getSizeBlock() != p){
std::cout<<"Lambda sizeBlock is wrong while initiating lambda in Hess\n";
}
if(lambda.getLeadingDim() != p){
std::cout<<"Lambda leadingDim is wrong while initiating lambda in Hess\n";
}
Lambda1 = new Block<Scalar,Primary>{p,p};
memcpy(Lambda1->getPtr(),lambda.getPtr(),p*p*sizeof(Scalar));
}
/**
* @brief Initialize Phi
* (refer to Annex, Eq 2.5)
*/
void initPhi(int p1){
if(!Phi){
Phi = new Block<Scalar,Primary>{Lambda1->getSizeBlock(),
Lambda1->getSizeBlock() + p1};
for(int i=0 ; i<Lambda1->getSizeBlock() ; ++i){
Phi->getPtr(i)[i] = Scalar(1);
}
}else{
std::cout<<"Should not be there !!\nExiting\n";
exit(0);
}
}
void reset(){
memset(data,0,sizeof(Scalar)*ldHess*MaxKSize);
sumNbVectInBlck.clear();
......@@ -85,7 +126,7 @@ public:
}
std::cout<<std::endl;
}
template<class Primary>
void displayHessExtendedBitMap(std::string name = ""){
std::cout<<name<<"\n";
for(int j=0 ; j<nbLineUsed+p ; ++j){
......@@ -134,7 +175,6 @@ public:
* @param W FullBlock
* @param sizeToRead : limite between W1 and W2
*/
template<typename Primary>
void UpdateBottomLine(Block<Scalar,Primary>& W){
int nj = sumNbVectInBlck.back();
//Save H in order to write directly inside L
......@@ -151,22 +191,81 @@ public:
//nbLineUsed += sizeToRead;
}
/**
* @brief Update the Phi (if needed, thus if IB happened on the R0)
*
* Could be optimized in order to avoid copying, allocating and destroying
*/
void updatePhi(Block<Scalar,Primary> & Directions, int p_jplus1){
if(Phi){ //If Phi has been set, it means that an I.B. happened
//on R0, and we have a modified RHS for least square
//that depends on Phi
int nj = sumNbVectInBlck.back();
// std::cout<<"Update Phi ::\n"
// <<"p\t"<<p<<"\n"
// <<"Phi->getLeadingDim()\t"<<Phi->getLeadingDim()<<"\n"
// <<"nbVectInBlck.back()\t"<<nbVectInBlck.back()<<"\n"
// <<"nj (== sumNbVectInBlck.back()\t"<<sumNbVectInBlck.back()<<"\n"
// <<"p_jplus1\t"<<p_jplus1<<"\n"
// <<"\n";
//Create New Phi
Block<Scalar,Primary> * newPhi =
new Block<Scalar,Primary>{p,Phi->getLeadingDim() + p_jplus1};
//Init first n_j rows
for(int i=0 ; i<p ; ++i){
memcpy(newPhi->getPtr(i),Phi->getPtr(i),
nj*sizeof(Scalar));
}
//Compute W1W2^{H} * Phi(nj+1:nj+p,:)
call_Tgemm<>(p,p,p,
Directions.getPtr(),Directions.getLeadingDim(),
&Phi->getPtr()[nj],Phi->getLeadingDim(),
&newPhi->getPtr()[nj],newPhi->getLeadingDim(),
Scalar(1),Scalar(0));
delete Phi;
Phi = newPhi;
}else{
//Do nothing
}
}
/**
* @brief Modify RHS given using Phi and Lambda1
* Return Phi * Lambda
*/
void ComputeRHS(Scalar * RHS, int ldRHS){
call_gemm<>(Phi->getLeadingDim(),p,p,
Phi->getPtr(),Phi->getLeadingDim(),
Lambda1->getPtr(),Lambda1->getLeadingDim(),
RHS,ldRHS,
Scalar(1),Scalar(0));
std::cout<<"Computing RHS done at ite "
<< sumNbVectInBlck.size() <<"\n";
}
/**
* @brief Compute Least Square and product to get residual :
* |Lj|
* |Hj| x |Y|
*/
template<typename Primary>
void ComputeResidual(Block<Scalar,Primary>& gamma,
Block<Scalar,Primary>& outputY,
void ComputeResidual(Block<Scalar,Primary>& outputY,
Block<Scalar,Primary>& outputResidual){
//Complete gamma
int ldR = nbLineUsed + p;
Scalar * r = new Scalar[ldR*p];
memset(r,0,((nbLineUsed + p)*p)*sizeof(Scalar));
for(int i=0 ; i<p ; ++i){
memcpy(&r[i*ldR],gamma.getPtr(i),
sizeof(Scalar)*(i+1));
if(!Phi){
memset(r,0,((nbLineUsed + p)*p)*sizeof(Scalar));
for(int i=0 ; i<p ; ++i){
memcpy(&r[i*ldR],Lambda1->getPtr(i),
sizeof(Scalar)*(i+1));
}
}else{
ComputeRHS(r,ldR);
}
//get a working copy of F
Scalar*workingCopy = new Scalar[ldR*sumNbVectInBlck.back()];
......@@ -195,10 +294,13 @@ public:
outputY.getPtr(),outputY.getLeadingDim(),
outputResidual.getPtr(),outputResidual.getLeadingDim(),
Scalar(1),Scalar(0));
std::cout<<"Compute F*Y done\n";
//Add gamma to residual
for(int i=0 ; i<outputResidual.getSizeBlock();++i){
for(int j=0 ; j<i+1 ; ++j){
outputResidual.getPtr(i)[j] -= gamma.getPtr(i)[j];
outputResidual.getPtr(i)[j] -= Lambda1->getPtr(i)[j];
}
}
......
......@@ -81,7 +81,9 @@ void call_Tgemm(int m, int n, int k,
double * res, int ldRes,
double alpha, double beta){
cblas_dgemm(CblasColMajor,CblasTrans,CblasNoTrans,
m,n,k,alpha,base,ldBase,block,ldBlock,beta,
m,n,k,
alpha,base,ldBase,
block,ldBlock,beta,
res,ldRes);
}
......
......@@ -9,16 +9,18 @@
* procedure.
*/
struct ArnReturn{
int sizeKSpace;
int nbIteDone;
bool hasConverged;
};
/**
* @brief This function test if the current solution is accurate
* enough. It will works only if the RHS are scaled, (i.e each column
* vector of B has a norm of 1)
* vector of B has a norm of 1).
* If the epsilon conditon is o completed, at the end, X0 contains
* Base*Y + X0, or PreCond*Base*Y + X0 if a right precond is used.
*
* @param A Matrix provided buy the user
* @param B RHS (each column vector of B must be of norm 1)
......
......@@ -141,14 +141,17 @@ int main(int ac, char ** av){
X0.getPtr(i)[j] = dis(gen);
}
}
//Copy inside first col of X0 the first col of B
memcpy(X0.getPtr(),X_Exact.getPtr(0),sizeof(Scalar)*dim);
Block<Scalar> sol(SizeBlock,dim);
Logger<Primary> log;
//Using for the arnoldi procedure choosen
using Arnoldi1 = Arnoldi_QRInc<InputMatrix<Scalar>,Scalar,Primary>;
using Arnoldi2 = Arnoldi<InputMatrix<Scalar>,Scalar,Primary>;
using Arnoldi3 = Arnoldi_IB<InputMatrix<Scalar>,Scalar,Primary>;
int nb = BGMRes<Arnoldi1,Matrix,Scalar,Primary>(mat,RHS,X0,nbBlock,restart,sol,log,
0.000001);
int nb = BGMRes<Arnoldi3,Matrix,Scalar,Primary>(mat,RHS,X0,nbBlock+4,restart,sol,log,
0.000001);
std::cout<<"Total Nb iter done::\t"<<nb<<"\n";
//Check solution
......
......@@ -161,7 +161,12 @@ int main(int ac, char ** av){
int SizeBlock = 26;
int max_ite = 200;
int maxiteIB = 320;
int restart = 200;
int restart;
if(args.size() > 1){
restart = std::stoi(args[1]);
}else{
restart = dim+1;
}
Block<Scalar,Primary> RHS{SizeBlock,dim};
Block<Scalar,Primary> XExact{SizeBlock,dim};
......@@ -194,35 +199,35 @@ int main(int ac, char ** av){
double elapsed1,elapsed2,elapsed3;
int nb1,nb2,nb3;
std::pair<Primary,Primary> minmax1,minmax2,minmax3;
{
std::cout<<"\n\tVersion Standard\n\n";
Block<Scalar,Primary> X0(SizeBlock,dim);
Block<Scalar,Primary> sol(SizeBlock,dim);
Logger<Primary> log;
double tic = Logger<Primary>::GetTime();
nb1 = BGMRes<Arnoldi1,Matrix,Scalar,Primary>(mat,RHS,X0,max_ite,restart,sol,log,
0.0001);
elapsed1 = Logger<Primary>::GetTime() - tic;
std::cout<<"Return value / max_ite : "<<nb1<<"/"<<max_ite<<"\n";
std::string locationRes("../data/res/MatCone.res");
std::ofstream fileRes(locationRes,std::ios::out);
log.forEachIte([&](int ite, int nbMatVect, int currSize,
Primary min, Primary max, double time)
{
fileRes<<ite<<"\t"
<<nbMatVect<<"\t"
<<currSize<<"\t"
<<min<<"\t"
<<max<<"\t"
<<time<<"\n";
});
minmax1 = CompareBlocks<Scalar,Primary>(sol,XExact);
// {
// std::cout<<"\n\tVersion Standard\n\n";
// Block<Scalar,Primary> X0(SizeBlock,dim);
// Block<Scalar,Primary> sol(SizeBlock,dim);
// Logger<Primary> log;
// double tic = Logger<Primary>::GetTime();
// nb1 = BGMRes<Arnoldi1,Matrix,Scalar,Primary>(mat,RHS,X0,max_ite,restart,sol,log,
// 0.0001);
// elapsed1 = Logger<Primary>::GetTime() - tic;
// std::cout<<"Return value / max_ite : "<<nb1<<"/"<<max_ite<<"\n";
// std::string locationRes("../data/res/MatCone.res");
// std::ofstream fileRes(locationRes,std::ios::out);
// log.forEachIte([&](int ite, int nbMatVect, int currSize,
// Primary min, Primary max, double time)
// {
// fileRes<<ite<<"\t"
// <<nbMatVect<<"\t"
// <<currSize<<"\t"
// <<min<<"\t"
// <<max<<"\t"
// <<time<<"\n";
// });
// minmax1 = CompareBlocks<Scalar,Primary>(sol,XExact);
}
// }
{
std::cout<<"\tVersion with Inexact Breakdown\n\n";
Block<Scalar,Primary> X0(SizeBlock,dim);
......
......@@ -176,7 +176,7 @@ int main(int ac, char ** av){
int SizeBlock = 16;
if(ac>1){
SizeBlock = std::stoi(av[1]);
SizeBlock = std::stoi(args[1]);
}
using Primary= double;
......@@ -189,7 +189,8 @@ int main(int ac, char ** av){
Matrix mat{};
std::string location("../data/conf5_0_00l4x4_1000.mtx");
std::string location("../data/young1c.mtx");
std::cout<<"File ::\t"<<location<<"\n";
std::ifstream myfile(location,std::ios::in);
mat.importMatrixCmplx(myfile);
......@@ -210,7 +211,12 @@ int main(int ac, char ** av){
int nbIte = (dim/SizeBlock)*2;
int nbIteIB = nbIte + SizeBlock-1;
int restart = mat.size();
int restart;
if(args.size() > 2){
restart = std::stoi(args[2]);
}else{
restart = dim+1;
}
using Arnoldi1 = Arnoldi<Matrix,Scalar,Primary>;
using Arnoldi2 = Arnoldi_IB<Matrix,Scalar,Primary>;
......@@ -260,7 +266,7 @@ int main(int ac, char ** av){
elapsed2 = Logger<Primary>::GetTime() - tic;
std::cout<<"Return value / max_ite : "<<nb2<<"/"<<nbIteIB<<"\n";
std::string locationRes("../data/res/conf5_0_00l4x4_1000_IB.res");
std::string locationRes("../data/res/young1c_IB.res");
std::ofstream fileRes(locationRes,std::ios::out);
log.forEachIte([&](int ite, int nbMatVect, int currSize,
Primary min, Primary max, double time)
......@@ -287,7 +293,7 @@ int main(int ac, char ** av){
elapsed3 = Logger<Primary>::GetTime() - tic;
std::cout<<"Return value / max_ite : "<<nb3<<"/"<<nbIte<<"\n";
std::string locationRes("../data/res/sherman4_QR.res");
std::string locationRes("../data/res/young1c_QR.res");
std::ofstream fileRes(locationRes,std::ios::out);
log.forEachIte([&](int ite, int nbMatVect, int currSize,
Primary min, Primary max, double time)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment