00001 #include "dsdpdatamat_impl.h"
00002 #include "dsdpsys.h"
00008 typedef struct {
00009 double ev;
00010 const double *spval;
00011 const int *spai;
00012 int nnz;
00013 int n;
00014 int ishift;
00015 char UPLQ;
00016 } r1mat;
00017
00018 static int R1MatDestroy(void*);
00019 static int R1MatView(void*);
00020 static int R1MatVecVec(void*, double[], int, double *);
00021 static int R1MatDotP(void*, double[],int,int,double *);
00022 static int R1MatDotU(void*, double[],int,int,double *);
00023 static int R1MatGetRank(void*, int*, int);
00024 static int R1MatFactor(void*);
00025 static int R1MatGetEig(void*, int, double*, double[], int,int[],int*);
00026 static int R1MatRowNnz(void*, int, int[], int*, int);
00027 static int R1MatAddRowMultiple(void*, int, double, double[], int);
00028 static int R1MatAddMultipleP(void*, double, double[], int,int);
00029 static int R1MatAddMultipleU(void*, double, double[], int,int);
00030
00031 static struct DSDPDataMat_Ops r1matopsP;
00032 static struct DSDPDataMat_Ops r1matopsU;
00033 static int R1MatOpsInitializeP(struct DSDPDataMat_Ops*);
00034 static int R1MatOpsInitializeU(struct DSDPDataMat_Ops*);
00035
00036
00037 #undef __FUNCT__
00038 #define __FUNCT__ "DSDPGetR1Mat"
00039 int DSDPGetR1Mat(int n, double ev, int ishift, const int spai[], const double spval[], int nnz, char UPLQ, void**mmat){
00040 int i;
00041 r1mat*AA;
00042 DSDPFunctionBegin;
00043 for (i=0;i<nnz;i++){
00044 if (spai[i]-ishift<0 || spai[i]-ishift >=n){
00045 printf("Invalid entry: Entry %d . Is %d <= %d < %d?\n",i,ishift,spai[i],n+ishift);
00046 return 1;
00047 }
00048 }
00049 AA=(r1mat*) malloc(1*sizeof(r1mat));
00050 if (AA==NULL) return 1;
00051 AA->n=n;
00052 AA->UPLQ=UPLQ;
00053 AA->spval=spval;
00054 AA->spai=spai;
00055 AA->nnz=nnz;
00056 AA->ev=ev;
00057 AA->ishift=ishift;
00058 if (mmat){*mmat=(void*)AA;}
00059 DSDPFunctionReturn(0);
00060 }
00061
00062 #undef __FUNCT__
00063 #define __FUNCT__ "DSDPGetR1PMat"
00064
00077 int DSDPGetR1PMat(int n, double ev, int ishift, const int spai[], const double spval[], int nnz, struct DSDPDataMat_Ops**mops, void**mmat){
00078 int info;
00079 DSDPFunctionBegin;
00080 info=DSDPGetR1Mat(n,ev,ishift,spai,spval,nnz,'P',mmat);
00081 info=R1MatOpsInitializeP(&r1matopsP); if(info){return 1;}
00082 if (mops){*mops=&r1matopsP;}
00083 DSDPFunctionReturn(0);
00084 }
00085
00086 #undef __FUNCT__
00087 #define __FUNCT__ "DSDPGetR1UMat"
00088
00101 int DSDPGetR1UMat(int n, double ev, int ishift, const int spai[], const double spval[], int nnz, struct DSDPDataMat_Ops**mops, void**mmat){
00102 int info;
00103 DSDPFunctionBegin;
00104 info=DSDPGetR1Mat(n,ev,ishift,spai,spval,nnz,'U',mmat);
00105 info=R1MatOpsInitializeU(&r1matopsU); if(info){return 1;}
00106 if (mops){*mops=&r1matopsU;}
00107 DSDPFunctionReturn(0);
00108 }
00109
00110 static int R1MatDotP(void* A, double x[], int nn, int n, double *v){
00111 r1mat* AA = (r1mat*)A;
00112 int i,i2,i3,j,j2;
00113 int nnz=AA->nnz,ishift=AA->ishift;
00114 const int *ai=AA->spai;
00115 double dtmp=0.0,d3;
00116 const double *val=AA->spval;
00117 for (i=0;i<nnz;i++){
00118 d3=val[i];
00119 i2=ai[i]-ishift;
00120 i3=(i2+1)*i2/2;
00121 for (j=0;j<nnz;j++){
00122 j2=ai[j]-ishift;
00123 if (j2<=i2){
00124 dtmp+=2*x[i3+j2]*d3*val[j];
00125 }
00126 }
00127 }
00128 *v=dtmp*AA->ev;
00129 return 0;
00130 }
00131
00132 static int R1MatDotU(void* A, double x[], int nn, int n, double *v){
00133 r1mat* AA = (r1mat*)A;
00134 int i,i2,i3,j,j2;
00135 int nnz=AA->nnz,ishift=AA->ishift;
00136 const int *ai=AA->spai;
00137 const double *val=AA->spval;
00138 double dtmp=0.0,d3;
00139
00140 for (i=0;i<nnz;i++){
00141 d3=val[i];
00142 i2=ai[i]-ishift;
00143 i3=i2*n;
00144 for (j=0;j<nnz;j++){
00145 j2=ai[j]-ishift;
00146 if (j2<=i2){
00147 dtmp+=2*x[i3+j2]*d3*val[j];
00148 }
00149 }
00150 }
00151 *v=dtmp*AA->ev;
00152 return 0;
00153 }
00154
00155 static int R1MatVecVec(void* A, double x[], int n, double *v){
00156
00157 r1mat* AA = (r1mat*)A;
00158 double dtmp=0.0;
00159 const double *val=AA->spval;
00160 int i,ishift=AA->ishift,nnz=AA->nnz;
00161 const int *ai=AA->spai;
00162 for (i=0; i<nnz; i++){
00163 dtmp+=val[i] * x[ai[i]-ishift];
00164 }
00165 *v=dtmp*dtmp*AA->ev;
00166 return 0;
00167 }
00168
00169 static int R1MatAddMultipleP(void*A, double dd, double vv[], int nn, int n){
00170 r1mat* AA = (r1mat*)A;
00171 int i,i2,i3,j,j2;
00172 int nnz=AA->nnz,ishift=AA->ishift;
00173 const int *ai=AA->spai;
00174 const double *val=AA->spval;
00175 double d3,ddd=dd*AA->ev;
00176 for (i=0;i<nnz;i++){
00177 d3=ddd*val[i];
00178 i2=ai[i]-ishift;
00179 i3=(i2+1)*i2/2;
00180 for (j=0;j<nnz;j++){
00181 j2=ai[j]-ishift;
00182 if (j2<=i2){
00183 vv[i3+j2]+=d3*val[j];
00184 }
00185 }
00186 }
00187 return 0;
00188 }
00189 static int R1MatAddMultipleU(void*A, double dd, double vv[], int nn, int n){
00190 r1mat* AA = (r1mat*)A;
00191 int i,i2,i3,j,j2;
00192 int nnz=AA->nnz,ishift=AA->ishift;
00193 const int *ai=AA->spai;
00194 const double *val=AA->spval;
00195 double d3,ddd=dd*AA->ev;
00196 for (i=0;i<nnz;i++){
00197 d3=ddd*val[i];
00198 i2=ai[i]-ishift;
00199 i3=i2*n;
00200 for (j=0;j<nnz;j++){
00201 j2=ai[j]-ishift;
00202 if (j2<=i2){
00203 vv[i3+j2]+=d3*val[j];
00204 }
00205 }
00206 }
00207 return 0;
00208 }
00209
00210 static int R1MatAddRowMultiple(void*A, int nrow, double dd, double row[], int n){
00211 r1mat* AA = (r1mat*)A;
00212 int nnz=AA->nnz,ishift=AA->ishift;
00213 const int *ai=AA->spai;
00214 const double *val=AA->spval;
00215 double ddd=dd*AA->ev;
00216 int i,j;
00217 for (i=0;i<nnz;i++){
00218 if (ai[i]-ishift==nrow){
00219 for (j=0;j<nnz;j++){
00220 row[ai[j]-ishift]+= ddd*val[i]*val[j];
00221 }
00222 }
00223 }
00224 return 0;
00225 }
00226
00227
00228 static int R1MatFactor(void*A){
00229 return 0;
00230 }
00231
00232
00233 static int R1MatGetRank(void *A, int*rank, int n){
00234 *rank=1;
00235 return 0;
00236 }
00237
00238 static int R1MatGetEig(void*A, int neig, double *eig, double v[], int n, int indx[], int*nind){
00239 r1mat* AA = (r1mat*)A;
00240 int i,aii,ishift=AA->ishift,nnz=AA->nnz;
00241 const int *ai=AA->spai;
00242 const double *val=AA->spval;
00243 for (i=0;i<n;i++){ v[i]=0.0; }
00244 *eig=0; *nind=0;
00245 if (neig==0){
00246 for (i=0;i<nnz;i++){
00247 aii=ai[i]-ishift;
00248 v[aii]=val[i];
00249 indx[i]=aii;
00250 }
00251 *eig=AA->ev; *nind=AA->nnz;
00252 }
00253 return 0;
00254 }
00255
00256
00257 static int R1MatRowNnz(void*A, int row, int nz[], int *rnnz, int n){
00258 r1mat* AA = (r1mat*)A;
00259 int i,j;
00260 int nnz=AA->nnz,ishift=AA->ishift;
00261 const int *ai=AA->spai;
00262 *rnnz=0;
00263 for (i=0;i<nnz;i++){
00264 if (ai[i]-ishift==row){
00265 for (j=0;j<nnz;j++){
00266 nz[ai[j]-ishift]++;
00267 }
00268 }
00269 *rnnz=nnz;
00270 }
00271 return 0;
00272 }
00273
00274 static int R1MatFNorm2(void*A, int n, double *fnorm2){
00275 r1mat* AA = (r1mat*)A;
00276 double dd=0;
00277 const double *val=AA->spval;
00278 int i,nnz=AA->nnz;
00279 for (i=0;i<nnz;i++){
00280 dd+=val[i]*val[i];
00281 }
00282 *fnorm2=dd*dd*AA->ev*AA->ev;
00283 return 0;
00284 }
00285
00286 static int R1MatCountNonzeros(void*A, int *nnz, int n){
00287 r1mat* AA = (r1mat*)A;
00288 *nnz=AA->nnz*AA->nnz;
00289 return 0;
00290 }
00291
00292
00293 static int R1MatView(void* A){
00294 int i;
00295 r1mat* AA = (r1mat*)A;
00296 printf("This matrix is %4.8e times the outer product of \n",AA->ev);
00297 for (i=0;i<AA->nnz;i++){
00298 printf("%d %4.8e \n",AA->spai[i],AA->spval[i]);
00299 }
00300 return 0;
00301 }
00302
00303
00304 static int R1MatDestroy(void* A){
00305 if (A) free(A);
00306 return 0;
00307 }
00308
00309 static const char *datamatname="RANK 1 Outer Product";
00310 static int R1MatOpsInitializeP(struct DSDPDataMat_Ops* r1matops){
00311 int info;
00312 if (r1matops==NULL) return 0;
00313 info=DSDPDataMatOpsInitialize(r1matops); DSDPCHKERR(info);
00314 r1matops->matfactor1=R1MatFactor;
00315 r1matops->matgetrank=R1MatGetRank;
00316 r1matops->matgeteig=R1MatGetEig;
00317 r1matops->matvecvec=R1MatVecVec;
00318 r1matops->matdot=R1MatDotP;
00319 r1matops->mataddrowmultiple=R1MatAddRowMultiple;
00320 r1matops->mataddallmultiple=R1MatAddMultipleP;
00321 r1matops->matdestroy=R1MatDestroy;
00322 r1matops->matview=R1MatView;
00323 r1matops->matrownz=R1MatRowNnz;
00324 r1matops->matfnorm2=R1MatFNorm2;
00325 r1matops->matnnz=R1MatCountNonzeros;
00326 r1matops->id=15;
00327 r1matops->matname=datamatname;
00328 return 0;
00329 }
00330 static int R1MatOpsInitializeU(struct DSDPDataMat_Ops* r1matops){
00331 int info;
00332 if (r1matops==NULL) return 0;
00333 info=DSDPDataMatOpsInitialize(r1matops); DSDPCHKERR(info);
00334 r1matops->matfactor1=R1MatFactor;
00335 r1matops->matgetrank=R1MatGetRank;
00336 r1matops->matgeteig=R1MatGetEig;
00337 r1matops->matvecvec=R1MatVecVec;
00338 r1matops->matdot=R1MatDotU;
00339 r1matops->mataddrowmultiple=R1MatAddRowMultiple;
00340 r1matops->mataddallmultiple=R1MatAddMultipleU;
00341 r1matops->matdestroy=R1MatDestroy;
00342 r1matops->matview=R1MatView;
00343 r1matops->matrownz=R1MatRowNnz;
00344 r1matops->matfnorm2=R1MatFNorm2;
00345 r1matops->matnnz=R1MatCountNonzeros;
00346 r1matops->id=15;
00347 r1matops->matname=datamatname;
00348 return 0;
00349 }
00350