Files
Seele/external/sdpa/sdpa_call.cpp
T
2023-01-21 18:43:21 +01:00

902 lines
22 KiB
C++

/* -------------------------------------------------------------
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
------------------------------------------------------------- */
/*--------------------------------------------------
sdpa_call.cpp
--------------------------------------------------*/
#include "sdpa_call.h"
#include "sdpa_io.h"
#include "sdpa_linear.h"
using namespace sdpa;
#define LengthOfBuffer 1024
SDPA::SDPA()
{
KAPPA = 1.5;
m = 0;
nBlock = 0;
fpout = NULL;
Display = NULL;
isInitPoint = false;
typeParameter = PARAMETER_DEFAULT;
param.setDefaultParameter(Parameter::PARAMETER_DEFAULT);
}
SDPA::~SDPA()
{
finalize();
}
void SDPA::setParameterType(ParameterType type)
{
if (type == PARAMETER_DEFAULT) {
param.setDefaultParameter(Parameter::PARAMETER_DEFAULT);
} else if (type == PARAMETER_UNSTABLE_BUT_FAST) {
param.setDefaultParameter(Parameter::PARAMETER_UNSTABLE_BUT_FAST);
} else if (type == PARAMETER_STABLE_BUT_SLOW) {
param.setDefaultParameter(Parameter::PARAMETER_STABLE_BUT_SLOW);
}
typeParameter = type;
}
void SDPA::setParameterMaxIteration(int maxIteration)
{
param.maxIteration = maxIteration;
}
void SDPA::setParameterEpsilonStar (double epsilonStar)
{
param.epsilonStar = epsilonStar;
}
void SDPA::setParameterLambdaStar (double lambdaStar)
{
param.lambdaStar = lambdaStar;
}
void SDPA::setParameterOmegaStar (double omegaStar)
{
param.omegaStar = omegaStar;
}
void SDPA::setParameterLowerBound (double lowerBound)
{
param.lowerBound = lowerBound;
}
void SDPA::setParameterUpperBound (double upperBound)
{
param.upperBound = upperBound;
}
void SDPA::setParameterBetaStar (double betaStar)
{
param.betaStar = betaStar;
}
void SDPA::setParameterBetaBar (double betaBar)
{
param.betaBar = betaBar;
}
void SDPA::setParameterGammaStar (double gammaStar)
{
param.gammaStar = gammaStar;
}
void SDPA::setParameterEpsilonDash (double epsilonDash)
{
param.epsilonDash = epsilonDash;
}
void SDPA::setParameterPrintXVec(char* xPrint)
{
strncpy(param.xPrint,xPrint,PRINT_DEFAULT_LENGTH);
}
void SDPA::setParameterPrintXMat(char* XPrint)
{
strncpy(param.XPrint,XPrint,PRINT_DEFAULT_LENGTH);
}
void SDPA::setParameterPrintYMat(char* YPrint)
{
strncpy(param.YPrint,YPrint,PRINT_DEFAULT_LENGTH);
}
void SDPA::setParameterPrintInformation(char* infPrint)
{
strncpy(param.infPrint,infPrint,PRINT_DEFAULT_LENGTH);
}
void SDPA::setDisplay(FILE* Display)
{
this->Display = Display;
}
void SDPA::setResultFile(FILE* fpout)
{
this->fpout = fpout;
}
void SDPA::setNumThreads(int NumThreads)
{
newton.setNumThreads(Display,fpout,NumThreads);
}
SDPA::ParameterType SDPA::getParameterType()
{
return typeParameter;
}
int SDPA::getParameterMaxIteration()
{
return param.maxIteration;
}
double SDPA::getParameterEpsilonStar()
{
return param.epsilonStar;
}
double SDPA::getParameterLambdaStar()
{
return param.lambdaStar;
}
double SDPA::getParameterOmegaStar()
{
return param.omegaStar;
}
double SDPA::getParameterLowerBound()
{
return param.lowerBound;
}
double SDPA::getParameterUpperBound()
{
return param.upperBound;
}
double SDPA::getParameterBetaStar()
{
return param.betaStar;
}
double SDPA::getParameterBetaBar()
{
return param.betaBar;
}
double SDPA::getParameterGammaStar()
{
return param.gammaStar;
}
double SDPA::getParameterEpsilonDash()
{
return param.epsilonDash;
}
char* SDPA::getParameterPrintXVec()
{
return param.xPrint;
}
char* SDPA::getParameterPrintXMat()
{
return param.XPrint;
}
char* SDPA::getParameterPrintYMat()
{
return param.YPrint;
}
char* SDPA::getParameterPrintInformation()
{
return param.infPrint;
}
FILE* SDPA::getDisplay()
{
return Display;
}
FILE* SDPA::getResultFile()
{
return fpout;
}
bool SDPA::getInitPoint()
{
return isInitPoint;
}
int SDPA::getNumThreads()
{
return newton.NUM_THREADS;
}
void SDPA::inputConstraintNumber(int m)
{
this->m = m;
}
void SDPA::inputBlockNumber(int nBlock)
{
this->nBlock = nBlock;
bs.initialize(nBlock);
}
void SDPA::inputBlockSize(int l, int size)
{
bs.blockStruct[l-1] = size;
}
void SDPA::inputBlockType(int l, ConeType coneType)
{
if (coneType == SDPA::SDP) {
bs.blockType[l-1] = BlockStruct::btSDP;
}
if (coneType == SDPA::LP) {
bs.blockType[l-1] = BlockStruct::btLP;
}
}
void SDPA::inputCVec(int k, double value)
{
if (k > m || k <= 0) {
rError("k exceeds ConstraintNumber or "
"k is less than or equal to zero :: m= "
<< m << " : k= " << k);
}
inputData.b.ele[k-1] = value;
}
void SDPA::inputElement(int k, int l, int i, int j, double value,
bool inputCheck)
{
if (inputCheck) {
if (k > m || k < 0) {
rError ("k exceeds ConstraintNumber or "
"k is less than zero :: m= "
<< m << " : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
if (l > nBlock || l <= 0) {
rError ("l exceeds nBlock or "
"l is less than or equal to zero :: nBlock= "
<< nBlock << " : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
int dim = bs.blockStruct[l-1];
if (i > dim || i <= 0) {
rError ("i exceeds dimension of the block or "
"i is less than or equal to zero :: dim= "
<< dim << " : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
if (j > dim || j <= 0) {
rError ("j exceeds dimension of the block or "
"j is less than or equal to zero :: dim= "
<< dim << " : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
if (bs.blockType[l-1] == BlockStruct::btSDP) {
if (i > j) {
rMessage("Swap i and j [Only Upper Triangle]"
" : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
}
if (bs.blockType[l-1] == BlockStruct::btLP) {
if (i!=j) {
rError("i should be j in LP block"
" : k= " << k << " : l= " << l
<< " : i= " << i << " : j= " << j);
}
}
}
if (i > j) {
int tmp = i; i = j; j = tmp;
}
LIJV* indexLIJv;
NewArray(indexLIJv,LIJV,1);
indexLIJv[0].SDPl = -1;
indexLIJv[0].LPl = -1;
indexLIJv[0].i = i;
indexLIJv[0].j = j;
indexLIJv[0].value = value;
if (bs.blockType[l-1] == BlockStruct::btSDP) {
int l2 = bs.blockNumber[l-1];
indexLIJv[0].SDPl = l2;
NonZeroElements[k].push_back(indexLIJv);
} else if (bs.blockType[l-1] == BlockStruct::btLP) {
int l2 = bs.blockNumber[l-1];
indexLIJv[0].LPl = l2+i-1;
NonZeroElements[k].push_back(indexLIJv);
}
// NonZeroElements[k].push_back(indexLIJv);
}
void SDPA::inputInitXVec(int k, double value)
{
rError("This routine is not available in SDPA-C");
}
void SDPA::inputInitXMat(int l, int i, int j, double value)
{
rError("This routine is not available in SDPA-C");
}
void SDPA::inputInitYMat(int l, int i, int j, double value)
{
rError("This routine is not available in SDPA-C");
}
void SDPA::initializeUpperTriangleSpace()
{
bs.makeInternalStructure();
NewArray(NonZeroElements,vector<LIJV*>,m+1);
inputData.initialize(m, bs);
// In SDPA-C, currentPt.initialize will be called later
// currentPt.initialize(m, bs, param.lambdaStar, com);
}
void SDPA::printNonZeroElements(FILE* fp)
{
for (int k=0; k<=m; ++k) {
int size = NonZeroElements[k].size();
for (int index = 0; index<size; ++index) {
LIJV* a = NonZeroElements[k][index];
int SDPl = a[0].SDPl;
int LPl = a[0].LPl;
int i = a[0].i;
int j = a[0].j;
double value = a[0].value;
if (SDPl >= 0) {
fprintf(fp,"%d, %d(S), %d, %d, ",k,SDPl,i,j);
}
if (LPl >= 0) {
fprintf(fp,"%d, %d(L), %d, %d, ",k,LPl,i,j);
}
fprintf(fp,param.infPrint,value);
fprintf(fp,"\n");
}
}
}
void SDPA::checkNonZeroElements()
{
TimeStart(FILE_CHECK_START1);
for (int k=0; k<=m; ++k) {
int size = NonZeroElements[k].size();
for (int index = 0; index<size-1; ++index) {
LIJV* a = NonZeroElements[k][index];
LIJV* b = NonZeroElements[k][index+1];
if (a[0].SDPl == b[0].SDPl && a[0].LPl == b[0].SDPl
&& a[0].i == b[0].i && a[0].j == b[0].j) {
int SDPl = a[0].SDPl;
int LPl = a[0].LPl;
int i = a[0].i;
int j = a[0].j;
rError("Twice input to the same index. "
": k = " << k << ": SDPl = " << SDPl << ": LPl = " << LPl
<< ": i = " << i << ": j = " << j);
}
}
}
TimeEnd(FILE_CHECK_END1);
com.FileChange += TimeCal(FILE_CHECK_START1,
FILE_CHECK_END1);
com.TotalTime += TimeCal(FILE_CHECK_START1,
FILE_CHECK_END1);
}
void SDPA::setNonZeroBlockStruct()
{
// almost equivalent to IO::setBlockStruct
vector<int> LP_blockCount;
vector<int> SDP_blockCount;
for (int k=0; k<m+1; ++k) {
LP_blockCount.clear();
SDP_blockCount.clear();
int length = NonZeroElements[k].size();
for (int index1 = 0; index1 < length; ++index1) {
LIJV* oneData = NonZeroElements[k].at(index1);
if (oneData[0].LPl >= 0) {
LP_blockCount.push_back(oneData[0].LPl);
}
if (oneData[0].SDPl >= 0) {
SDP_blockCount.push_back(oneData[0].SDPl);
}
}
sort(LP_blockCount.begin(), LP_blockCount.end());
sort(SDP_blockCount.begin(), SDP_blockCount.end());
int LP_sp_nBlock = 0;
int SDP_sp_nBlock = 0;
int LP_old_block = -1;
int SDP_old_block = -1;
const int LP_length = LP_blockCount.size();
const int SDP_length = SDP_blockCount.size();
for (int index1 = 0; index1 < LP_length; ++index1) {
if (LP_blockCount[index1] != LP_old_block) {
LP_old_block = LP_blockCount[index1];
LP_sp_nBlock++;
}
}
for (int index1 = 0; index1 < SDP_length; ++index1) {
if (SDP_blockCount[index1] != SDP_old_block) {
SDP_old_block = SDP_blockCount[index1];
SDP_sp_nBlock++;
}
}
CompSpace* target = &inputData.C;
if (k>0) {
target = &inputData.A[k-1];
}
target->initialize(LP_sp_nBlock, SDP_sp_nBlock);
int index_t = 0;
LP_old_block = -1;
for (int index1 = 0; index1 < LP_length; ++index1) {
const int current_block = LP_blockCount[index1];
if (current_block != LP_old_block) {
target->LP_sp_index[index_t] = current_block;
LP_old_block = current_block;
index_t++;
}
}
index_t = 0;
SDP_old_block = -1;
for (int index1 = 0; index1 < SDP_length; ++index1) {
const int current_block = SDP_blockCount[index1];
if (current_block != SDP_old_block) {
target->SDP_sp_index[index_t] = current_block;
SDP_old_block = current_block;
target->SDP_sp_block[index_t].nRow = bs.SDP_blockStruct[current_block];
target->SDP_sp_block[index_t].nCol = bs.SDP_blockStruct[current_block];
index_t++;
}
}
#if 0
rMessage("LP blocks = ");
for (int index2 = 0; index2 < LP_sp_nBlock; ++index2) {
printf(" %d", target->LP_sp_index[index2]);
}
printf("\n");
rMessage("SDP blocks = ");
for (int index2 = 0; index2 < SDP_sp_nBlock; ++index2) {
printf(" %d", target->SDP_sp_index[index2]);
}
printf("\n");
#endif
target->initializeInputVector();
}
LP_blockCount.clear();
SDP_blockCount.clear();
}
void SDPA::setNonZeroElements()
{
for (int k=0; k<m+1; ++k) {
CompSpace* target = &inputData.C;
double scale = -1.0; // Input of C should be reversed
if (k>0) {
target = &inputData.A[k-1];
scale = 1.0;
}
int length = NonZeroElements[k].size();
for (int index1 = 0; index1 < length; ++index1) {
LIJV* oneData = NonZeroElements[k].at(index1);
if (oneData[0].LPl >= 0) {
target->setElement_LP(oneData[0].LPl, oneData[0].value*scale);
}
if (oneData[0].SDPl >= 0) {
target->setElement_SDP(oneData[0].SDPl,
oneData[0].i-1, oneData[0].j-1,
oneData[0].value*scale);
}
}
}
double v1 = 0; // dummy initialize
double v2 = 0; // dummy initialize
inputData.C.sortInputVector();
int check_l = 0, check_i = 0, check_j = 0;
double check_v1 = 0, check_v2 = 0;
inputData.C.checkInputDataStructure(check_l, check_i, check_j,
check_v1, check_v2);
inputData.C.makeInternalStructure();
if (check_l>=0) {
printf("***** invalid data ******\n");
printf("F[0]:%d-th SDP block:[%d, %d]-th element has more than one input\n",
check_l+1, check_i+1, check_j+1);
rError("Stop due to input error\n");
}
for (int k=0; k<m; ++k) {
inputData.A[k].sortInputVector();
inputData.A[k].checkInputDataStructure(check_l, check_i, check_j,
check_v1, check_v2);
inputData.A[k].makeInternalStructure();
if (check_l>=0) {
printf("***** invalid data ******\n");
printf("F[%d]:%d-th SDP block:[%d, %d]-th element has more than one input\n",
k+1, check_l+1, check_i+1, check_j+1);
rError("Stop due to input error\n");
}
}
#if 0
rMessage("************** Read finished, internal data is from here.");
rMessage("C = -------------------------");
inputData.C.display();
for (int k=0; k<m; ++k) {
rMessage("A[" << k << "] = -------------------------");
inputData.A[k].display();
}
rMessage("************** Read finished, internal data is until here.");
#endif
}
void SDPA::initializeUpperTriangle(bool checkTwiceInput)
{
if (checkTwiceInput) {
checkNonZeroElements();
}
// printNonZeroElements();
setNonZeroBlockStruct();
setNonZeroElements();
for (int k=0; k<=m; ++k) {
int size = NonZeroElements[k].size();
for (int index = 0; index < size; ++index) {
DeleteArray(NonZeroElements[k][index]);
}
}
DeleteArray(NonZeroElements);
}
double* SDPA::getResultXVec()
{
return currentPt.cholmodSpace.yVec.ele;
}
double* SDPA::getResultXMat(int l)
{
if (IO::judgeZmake(param) == false) {
return NULL;
}
if (l > nBlock || l <= 0) {
rError ("l exceeds nBlock or "
"l is less than or equal to zero :: nBlock= "
<< nBlock << " : l= " << l);
}
if (bs.blockType[l-1] == BlockStruct::btSDP) {
int l2 = bs.blockNumber[l-1];
return currentPt.finalZ.SDP_block[l2].de_ele;
}
else if (bs.blockType[l-1] == BlockStruct::btLP) {
int start = bs.blockNumber[l-1];
return &currentPt.finalZ.LP_block[start];
}
return NULL;
}
double* SDPA::getResultYMat(int l)
{
if (IO::judgeXmake(param) == false) {
return NULL;
}
if (l > nBlock || l <= 0) {
rError ("l exceeds nBlock or "
"l is less than or equal to zero :: nBlock= "
<< nBlock << " : l= " << l);
}
if (bs.blockType[l-1] == BlockStruct::btSDP) {
int l2 = bs.blockNumber[l-1];
return currentPt.finalX.SDP_block[l2].de_ele;
}
else if (bs.blockType[l-1] == BlockStruct::btLP) {
int start = bs.blockNumber[l-1];
return &currentPt.finalX.LP_block[start];
}
return NULL;
}
double SDPA::getPrimalObj()
{
// Note reverse primal-dual
return -solveInfo.objValDual;
}
double SDPA::getDualObj()
{
// Note reverse primal-dual
return -solveInfo.objValPrimal;
}
double SDPA::getPrimalError()
{
// Note reverse primal-dual
return currentRes.normDual;
}
double SDPA::getDualError()
{
// Note reverse primal-dual
return currentRes.normPrimal;
}
double SDPA::getDigits()
{
double mean = (fabs(solveInfo.objValPrimal)
+ fabs(solveInfo.objValDual)) / 2.0;
double PDgap = getDualityGap();
double digits = -log10(fabs(PDgap/mean));
return digits;
}
int SDPA::getIteration()
{
return pIteration;
}
double SDPA::getMu()
{
return mu.current;
}
double SDPA::getDualityGap()
{
double PDgap = fabs(solveInfo.objValPrimal
- solveInfo.objValDual);
return PDgap;
}
SDPA::PhaseType SDPA::getPhaseValue()
{
// Note reverse primal-dual
switch (phase.value) {
case SolveInfo::noINFO : return noINFO ; break;
case SolveInfo::pFEAS : return pFEAS ; break;
case SolveInfo::dFEAS : return dFEAS ; break;
case SolveInfo::pdFEAS : return pdFEAS ; break;
case SolveInfo::pdINF : return pdINF ; break;
case SolveInfo::pFEAS_dINF: return pINF_dFEAS; break;
case SolveInfo::pINF_dFEAS: return pFEAS_dINF; break;
case SolveInfo::pdOPT : return pdOPT ; break;
case SolveInfo::pUNBD : return dUNBD ; break;
case SolveInfo::dUNBD : return pUNBD ; break;
default: break;
}
return noINFO;
}
void SDPA::getPhaseString(char* str)
{
switch (phase.value) {
case SolveInfo::noINFO : strcpy(str,(char *)"noINFO "); break;
case SolveInfo::pFEAS : strcpy(str,(char *)"pFEAS "); break;
case SolveInfo::dFEAS : strcpy(str,(char *)"dFEAS "); break;
case SolveInfo::pdFEAS : strcpy(str,(char *)"pdFEAS "); break;
case SolveInfo::pdINF : strcpy(str,(char *)"pdINF "); break;
case SolveInfo::pFEAS_dINF: strcpy(str,(char *)"pFEAS_dINF"); break;
case SolveInfo::pINF_dFEAS: strcpy(str,(char *)"pINF_dFEAS"); break;
case SolveInfo::pdOPT : strcpy(str,(char *)"pdOPT "); break;
case SolveInfo::pUNBD : strcpy(str,(char *)"pUNBD "); break;
case SolveInfo::dUNBD : strcpy(str,(char *)"dUNBD "); break;
default:
strcpy(str,(char *)"phase error");
break;
}
return;
}
double SDPA::getSolveTime()
{
return com.TotalTime;
}
int SDPA::getConstraintNumber()
{
return m;
}
int SDPA::getBlockNumber()
{
return nBlock;
}
int SDPA::getBlockSize(int l)
{
if (l<=0 || l>nBlock) {
rMessage("out of range : getBlockSize "
": l = " << l
<< " should be between 1 and nBlock " << nBlock);
}
return bs.blockStruct[l-1];
}
SDPA::ConeType SDPA::getBlockType(int l)
{
if (l<=0 || l>nBlock) {
rMessage("out of range : getBlockSize "
": l = " << l
<< " should be between 1 and nBlock " << nBlock);
}
switch (bs.blockType[l-1]) {
case BlockStruct::btSDP : return SDPA::SDP ;
case BlockStruct::btLP : return SDPA::LP ;
}
rError("Type Error in getBlockType ");
return SDPA::SDP; // dummy return
}
void SDPA::getDimacsError(double* DimacsError)
{
if (judgeDimacsAvailability() == false) {
return;
}
IO::computeDimacs(DimacsError, solveInfo, currentRes,
currentPt, inputData);
}
void SDPA::printDimacsError(double* DimacsError, char* printFormat,
FILE* fpout)
{
if (judgeDimacsAvailability() == false) {
return;
}
IO::printDimacs(DimacsError,printFormat,fpout);
}
void SDPA::printDimacsEasy(FILE* fpout)
{
double dimacs_error[7];
currentPt.makeFinalSolution(true, true, bs);
getDimacsError(dimacs_error);
printf("Dimacs = ");
for (int dd=1; dd<7; ++dd) {
printf("%.3e ", dimacs_error[dd]);
}
printf("\n");
}
void SDPA::printResultXVec(FILE* fp)
{
// Note reverse primal-dual
currentPt.cholmodSpace.yVec.display(fp,1.0,param.xPrint);
}
void SDPA::printResultXMat(FILE* fp)
{
if (IO::judgeZmake(param) == false) {
fprintf(fp, "Result XMat is not computed.\n");
return;
}
// Note reverse primal-dual
currentPt.finalZ.displaySolution(bs,fp,param.XPrint);
}
void SDPA::printResultYMat(FILE* fp)
{
if (IO::judgeXmake(param) == false) {
fprintf(fp, "Result YMat is not computed.\n");
return;
}
// Note reverse primal-dual
currentPt.finalX.displaySolution(bs,fp,param.YPrint);
}
void SDPA::printComputationTime(FILE* fp)
{
com.display(fp);
}
void SDPA::printParameters(FILE* fp)
{
param.display(fp);
}
bool SDPA::judgeDimacsAvailability() // for only SDPA-C
{
bool Xmake = IO::judgeXmake(param);
bool Zmake = IO::judgeZmake(param);
if (Xmake == false || Zmake == false) {
return false;
}
return true;
}
void SDPA::printSDPAVersion(FILE* fp)
{
if (fp) {
fprintf(fp,"%s\n",(char*)sdpa_right);
}
}
void SDPA::readInput(char* filename, FILE* fpout)
{
TimeStart(FILE_READ_START1);
FILE* fpinput = NULL;
if ((fpinput = fopen(filename,"r")) == NULL) {
rError("Cannot Open Data File " << filename);
}
#if 0
if (fpout){
fprintf(fpout,"data is %s ", filename);
fprintf(fpout," : sparse\n");
}
#endif
char titleAndComment[LengthOfBuffer];
IO::read(fpinput,fpout,m,titleAndComment);
IO::read(fpinput,nBlock);
bs.initialize(nBlock);
IO::read(fpinput,bs);
bs.makeInternalStructure();
inputData.initialize(m, bs);
IO::read(fpinput, inputData.b);
IO::read(fpinput, m, bs, inputData);
// inputData.initialize_index();
fclose(fpinput);
TimeEnd(FILE_READ_END1);
com.FileRead += TimeCal(FILE_READ_START1,
FILE_READ_END1);
com.TotalTime += TimeCal(FILE_READ_START1,
FILE_READ_END1);
return;
}
void SDPA::readParameter(char* filename, FILE* fpout)
{
FILE* fp = NULL;
if ((fp=fopen(filename,"r"))==NULL) {
rError("Cannot Open parameter File " << filename);
}
param.readFile(fp);
fclose(fp);
return;
}
void SDPA::finalize()
{
bs.finalize();
inputData.finalize();
chordal.finalize();
newton.finalize();
currentPt.finalize();
initPt_xMat.finalize();
initPt_zMat.finalize();
currentRes.finalize();
alpha.finalize();
}
void SDPA::copyCurrentToInit()
{
// This function is only compatibility with SDPA.
rMessage("The function SDPA::copyCurrentToInit() does nothing in SDPA-C");
return;
}
void SDPA::setKappa(double KAPPA)
{
this->KAPPA = KAPPA;
}