/* read a problem from a file; use %g for integers to avoid int conflicts */ problem *get_problem (FILE *f, double tol) { cs *T, *A, *C ; int sym, m, n, mn, nz1, nz2 ; problem *Prob ; Prob = cs_calloc (1, sizeof (problem)) ; if (!Prob) return (NULL) ; T = cs_load (f) ; /* load triplet matrix T from a file */ Prob->A = A = cs_compress (T) ; /* A = compressed-column form of T */ cs_spfree (T) ; /* clear T */ if (!cs_dupl (A)) return (free_problem (Prob)) ; /* sum up duplicates */ Prob->sym = sym = is_sym (A) ; /* determine if A is symmetric */ m = A->m ; n = A->n ; mn = CS_MAX (m,n) ; nz1 = A->p [n] ; cs_dropzeros (A) ; /* drop zero entries */ nz2 = A->p [n] ; if (tol > 0) cs_droptol (A, tol) ; /* drop tiny entries (just to test) */ Prob->C = C = sym ? make_sym (A) : A ; /* C = A + triu(A,1)', or C=A */ if (!C) return (free_problem (Prob)) ; printf ("\n--- Matrix: %g-by-%g, nnz: %g (sym: %g: nnz %g), norm: %8.2e\n", (double) m, (double) n, (double) (A->p [n]), (double) sym, (double) (sym ? C->p [n] : 0), cs_norm (C)) ; if (nz1 != nz2) printf ("zero entries dropped: %g\n", (double) (nz1 - nz2)); if (nz2 != A->p [n]) printf ("tiny entries dropped: %g\n", (double) (nz2 - A->p [n])) ; Prob->b = cs_malloc (mn, sizeof (double)) ; Prob->x = cs_malloc (mn, sizeof (double)) ; Prob->resid = cs_malloc (mn, sizeof (double)) ; return ((!Prob->b || !Prob->x || !Prob->resid) ? free_problem (Prob) : Prob) ; }
/* print a sparse matrix */ int cs_print (const cs *A, int brief) { int p, j, m, n, nzmax, nz, *Ap, *Ai ; double *Ax ; if (!A) { Rprintf ("(null)\n") ; return (0) ; } m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; nzmax = A->nzmax ; nz = A->nz ; Rprintf ("CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; if (nz < 0) { Rprintf ("%d-by-%d, nzmax: %d nnz: %d, 1-norm: %g\n", m, n, nzmax, Ap [n], cs_norm (A)) ; for (j = 0 ; j < n ; j++) { Rprintf (" col %d : locations %d to %d\n", j, Ap [j], Ap [j+1]-1); for (p = Ap [j] ; p < Ap [j+1] ; p++) { Rprintf (" %d : %g\n", Ai [p], Ax ? Ax [p] : 1) ; if (brief && p > 20) { Rprintf (" ...\n") ; return (1) ; } } } } else { Rprintf ("triplet: %d-by-%d, nzmax: %d nnz: %d\n", m, n, nzmax, nz) ; for (p = 0 ; p < nz ; p++) { Rprintf (" %d %d : %g\n", Ai [p], Ap [p], Ax ? Ax [p] : 1) ; if (brief && p > 20) { Rprintf (" ...\n") ; return (1) ; } } } return (1) ; }
/* compute residual, norm(A*x-b,inf) / (norm(A,1)*norm(x,inf) + norm(b,inf)) */ static void print_resid (int ok, cs *A, double *x, double *b, double *resid) { int i, m, n ; if (!ok) { printf (" (failed)\n") ; return ; } m = A->m ; n = A->n ; for (i = 0 ; i < m ; i++) resid [i] = -b [i] ; /* resid = -b */ cs_gaxpy (A, x, resid) ; /* resid = resid + A*x */ printf ("resid: %8.2e\n", norm (resid,m) / ((n == 0) ? 1 : (cs_norm (A) * norm (x,n) + norm (b,m)))) ; }
void test_ppp_add(char const * A_file, char const * B_file, char const * C_file) { cs * A = ppp_load_ccf(A_file); cs * B = ppp_load_ccf(B_file); cs *C = NULL, *D = NULL; if(C_file) C = ppp_load_ccf(C_file); cs * R = cs_spalloc(A->m, A->n, A->p[A->n] + B->p[B->n], 1, 0); /* allocate result*/ csi mn = A->n > A->m ? A->n : A->m; ppp_init_cs(mn); ppp_add(R, A, B, 1); /* Test equivalence */ if(C_file){ D = cs_add(C,R,1,-1); if(cs_norm(D) > cs_norm(C) * PPP_EPSILON){ fprintf(stderr, "Diff found [%s + %s != %s]:\n", A_file, B_file, C_file); fprintf(stdout, "Diff found [%s + %s != %s]:\n", A_file, B_file, C_file); fprintf(stdout, "Expected:\n"); cs_print(C,0); fprintf(stdout, "Obtained:\n"); cs_print(R,0); fprintf(stdout, "Diff:\n"); cs_print(D,0); }else{ fprintf(stdout, "Success!\n"); } } /* clean up*/ cs_spfree(A); cs_spfree(B); cs_spfree(C); cs_spfree(R); cs_spfree(D); ppp_done(); }
/* print a sparse matrix */ int cs_printInFile(const cs *A, int brief, FILE* file) { csi m, n, nzmax, nz, p, j, *Ap, *Ai ; double *Ax ; if(!A) { fprintf(file,"(null)\n") ; return (0) ; } m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; nzmax = A->nzmax ; nz = A->nz ; fprintf(file,"CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; if(nz < 0) { fprintf(file,"%ld-by-%ld, nzmax: %ld nnz: %ld, 1-norm: %g\n", m, n, nzmax, Ap [n], cs_norm(A)) ; for(j = 0 ; j < n ; j++) { fprintf(file," col %ld : locations %ld to %ld\n", j, Ap [j], Ap [j+1]-1); for(p = Ap [j] ; p < Ap [j+1] ; p++) { fprintf(file," %ld : %g\n", Ai [p], Ax ? Ax [p] : 1) ; if(brief && p > 20) { fprintf(file," ...\n") ; return (1) ; } } } } else { fprintf(file,"triplet: %ld-by-%ld, nzmax: %ld nnz: %ld\n", m, n, nzmax, nz) ; for(p = 0 ; p < nz ; p++) { fprintf(file," %ld %ld : %g\n", Ai [p], Ap [p], Ax ? Ax [p] : 1) ; if(brief && p > 20) { fprintf(file," ...\n") ; return (1) ; } } } return (1) ; }
/* print a sparse matrix; use %g for integers to avoid differences with CS_INT */ CS_INT cs_print (const cs *A, CS_INT brief) { CS_INT p, j, m, n, nzmax, nz, *Ap, *Ai ; CS_ENTRY *Ax ; if (!A) { printf ("(null)\n") ; return (0) ; } m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; nzmax = A->nzmax ; nz = A->nz ; printf ("CXSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; if (nz < 0) { printf ("%g-by-%g, nzmax: %g nnz: %g, 1-norm: %g\n", (double) m, (double) n, (double) nzmax, (double) (Ap [n]), cs_norm (A)) ; for (j = 0 ; j < n ; j++) { printf (" col %g : locations %g to %g\n", (double) j, (double) (Ap [j]), (double) (Ap [j+1]-1)) ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { printf (" %g : ", (double) (Ai [p])) ; #ifdef CS_COMPLEX printf ("(%g, %g)\n", Ax ? CS_REAL (Ax [p]) : 1, Ax ? CS_IMAG (Ax [p]) : 0) ; #else printf ("%g\n", Ax ? Ax [p] : 1) ; #endif if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } } else { printf ("triplet: %g-by-%g, nzmax: %g nnz: %g\n", (double) m, (double) n, (double) nzmax, (double) nz) ; for (p = 0 ; p < nz ; p++) { printf (" %g %g : ", (double) (Ai [p]), (double) (Ap [p])) ; #ifdef CS_COMPLEX printf ("(%g, %g)\n", Ax ? CS_REAL (Ax [p]) : 1, Ax ? CS_IMAG (Ax [p]) : 0) ; #else printf ("%g\n", Ax ? Ax [p] : 1) ; #endif if (brief && p > 20) { printf (" ...\n") ; return (1) ; } } } return (1) ; }
int main ( void ) { cs *A; cs *AT; cs *C; cs *D; cs *Eye; int i; int m; cs *T; printf ( "\n" ); printf ( "CS_DEMO1:\n" ); printf ( " Demonstration of the CSPARSE package.\n" ); /* Load the triplet matrix T from standard input. */ T = cs_load ( stdin ); /* Print T. */ printf ( "T:\n" ); cs_print ( T, 0 ); /* A = compressed-column form of T. */ A = cs_triplet ( T ); printf ( "A:\n" ); cs_print ( A, 0 ); /* Clear T. */ cs_spfree ( T ); /* AT = A'. */ AT = cs_transpose ( A, 1 ); printf ( "AT:\n" ); cs_print ( AT, 0 ); /* M = number of rows of A. */ m = A->m; /* Create triplet identity matrix. */ T = cs_spalloc ( m, m, m, 1, 1 ); for ( i = 0; i < m; i++ ) { cs_entry ( T, i, i, 1 ); } /* Eye = speye ( m ) */ Eye = cs_triplet ( T ); cs_spfree ( T ); /* Compute C = A * A'. */ C = cs_multiply ( A, AT ); /* Compute D = C + Eye * norm (C,1). */ D = cs_add ( C, Eye, 1, cs_norm ( C ) ); printf ( "D:\n" ); cs_print ( D, 0 ); /* Clear A, AT, C, D, Eye, */ cs_spfree ( A ); cs_spfree ( AT ); cs_spfree ( C ); cs_spfree ( D ); cs_spfree ( Eye ); /* Terminate. */ printf ( "\n" ); printf ( "CS_DEMO1:\n" ); printf ( " Normal end of execution.\n" ); return ( 0 ); }
cs *cs_inv(const cs *C){ int n, i, icol,irow,j,k,l,ll; double big,dum,pivinv,temp, det, CN; CN = cs_norm(C); cs *A; n = C->n; det=1.0; int indxc[n], indxr[n], ipiv[n]; A = cs_spalloc (n, n, n*n, 1, 0); if (!A ) return (cs_done (A, NULL, NULL, 0)); for(i = 0; i<(n*n); i++){ A->i[i] = C->i[i]; A->x[i] = C->x[i]; } for(i = 0; i<=n; i++){ A->p[i] = C->p[i]; } for (j=0;j<n;j++) ipiv[j]=0; for (i=0;i<n;i++) { big=0.0; for (j=0;j<n;j++) if (ipiv[j] != 1) for (k=0;k<n;k++) { if (ipiv[k] == 0) { if (fabs(A->x[A->i[j]+A->p[k]]) >= big) { big=fabs(A->x[A->i[j]+A->p[k]]); irow=j; icol=k; } } else if (ipiv[k] > 1) error("Singular G/R structure: use proper priors\n");// //exit(1); } ++(ipiv[icol]); if (irow != icol) { for (l=0;l<n;l++){ temp = A->x[A->i[irow]+A->p[l]]; A->x[A->i[irow]+A->p[l]] = A->x[A->i[icol]+A->p[l]]; A->x[A->i[icol]+A->p[l]]= temp; } } indxr[i]=irow; indxc[i]=icol; det *= A->x[A->i[icol]+A->p[icol]]; pivinv = 1.0/(A->x[A->i[icol]+A->p[icol]]); A->x[A->i[icol]+A->p[icol]]=1.0; for (l=0;l<n;l++) A->x[A->i[icol]+A->p[l]] *= pivinv; for (ll=0;ll<n;ll++) if (ll != icol) { dum=A->x[A->i[ll]+A->p[icol]]; A->x[A->i[ll]+A->p[icol]]=0.0; for (l=0;l<n;l++) A->x[A->i[ll]+A->p[l]] -= A->x[A->i[icol]+A->p[l]]*dum; } } for (l=(n-1);l>=0;l--) { if (indxr[l] != indxc[l]){ for (k=0;k<n;k++){ temp = A->x[A->i[k]+A->p[indxr[l]]]; A->x[A->i[k]+A->p[indxr[l]]] = A->x[A->i[k]+A->p[indxc[l]]]; A->x[A->i[k]+A->p[indxc[l]]] = temp; } } } CN *= cs_norm(A); if(1.0/fabs(CN) < DBL_EPSILON){ if(n==1){ A->x[0] = 1.0/DBL_EPSILON; }else{ PutRNGstate(); error("ill-conditioned G/R structure (CN = %f): use proper priors if you haven't or rescale data if you have\n", CN); } } return (cs_done (A, NULL, NULL, 1)) ; /* success; free workspace, return C */ }