/* 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) ; }
static cs *cs_frand (csi n, csi nel, csi s) { csi ss = s*s, nz = nel*ss, e, i, j, *P ; cs *A, *T = cs_spalloc (n, n, nz, 1, 1) ; if (!T) return (NULL) ; P = cs_malloc (s, sizeof (csi)) ; if (!P) return (cs_spfree (T)) ; for (e = 0 ; e < nel ; e++) { for (i = 0 ; i < s ; i++) P [i] = rand () % n ; for (j = 0 ; j < s ; j++) { for (i = 0 ; i < s ; i++) { cs_entry (T, P [i], P [j], rand () / (double) RAND_MAX) ; } } } for (i = 0 ; i < n ; i++) cs_entry (T, i, i, 1) ; A = cs_compress (T) ; cs_spfree (T) ; return (cs_dupl (A) ? A : cs_spfree (A)) ; }
sparse_matrix* create_mna_sparse(LIST *list, sparse_vector** b, int* vector_len){ int i; int rows; int columns; sparse_vector* vector = NULL; sparse_matrix* matrix = NULL; LIST_NODE* curr; int num_nodes = ht_get_num_nodes(list->hashtable); int* nodeids = (int*)malloc(sizeof(int) * num_nodes); if(!nodeids) return NULL; for( i = 0; i < num_nodes; i++) nodeids[i] = 0; int m2_elements_found = 0; // # of elements in group 2 /* allocate matrix and vector */ rows = list->hashtable->num_nodes + list->m2; columns = list->hashtable->num_nodes + list->m2; matrix = cs_spalloc( rows , columns , DEFAULT_NZ , 1 , 1 ); if(!matrix) return NULL; vector = (sparse_vector*) malloc( sizeof(sparse_vector) * rows); if( !vector){ cs_spfree(matrix); return NULL; } for( curr = list->head ; curr; curr = curr->next){ /* * RESISTANCE ELEMENT */ if( curr->type == NODE_RESISTANCE_TYPE ){ double conductance = 1 / curr->node.resistance.value ; long plus_node = curr->node.resistance.node1 - 1; long minus_node = curr->node.resistance.node2 - 1; //printf("plus_node: %d minus_node: %d\n",plus_node,minus_node); /* <+> is ground */ if( plus_node == -1 ){ //double value = gsl_matrix_get(tmp_matrix , minus_node , minus_node); //value += conductance ; //gsl_matrix_set( tmp_matrix , minus_node , minus_node , value ); //printf("Adding to matrix element (%d,%d) value:%f\n\n",minus_node,minus_node,value); if( !cs_entry(matrix, minus_node , minus_node , conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } } /* <-> is ground */ else if ( minus_node == -1 ){ if( !cs_entry(matrix, plus_node , plus_node , conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } } else { /* <+> <+> */ if( !cs_entry(matrix, plus_node , plus_node , conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } /* <+> <-> */ if( !cs_entry(matrix, plus_node , minus_node , -conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } /* <-> <+> */ if( !cs_entry(matrix, minus_node , plus_node , -conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } /* <-> <-> */ if( !cs_entry(matrix, minus_node , minus_node , conductance) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } } } /* * CURRENT SOURCE */ else if( curr->type == NODE_SOURCE_I_TYPE ){ /* change only the vector */ double current = curr->node.source_i.value; double value; if( curr->node.source_i.node1 != 0 ){ /* ste <+> */ value = vector[curr->node.source_i.node1 - 1 ]; value -= current; vector[curr->node.source_i.node1 -1 ] = value; } if( curr->node.source_i.node2 != 0 ){ /* <-> */ value = vector[curr->node.source_i.node2 - 1 ]; value += current; vector[curr->node.source_i.node2 -1 ] = value; } } /* * VOLTAGE SOURCE */ else if ( curr->type == NODE_SOURCE_V_TYPE ){ m2_elements_found++; int matrix_row = list->hashtable->num_nodes + m2_elements_found - 1; curr->node.source_v.mna_row = matrix_row; double value; /* set vector value */ value = vector[matrix_row]; value += curr->node.source_v.value; vector[ matrix_row ] = value; long plus_node = curr->node.source_v.node1 - 1; long minus_node = curr->node.source_v.node2 - 1; //printf("Voltage %s plus = %d minus = %d matrix_row = %d\n", curr->node.source_v.name,plus_node,minus_node,matrix_row ); /* <+> */ if( plus_node != -1 ){ //if( nodeids[plus_node] == 0 ){ //printf("mphke plus node...\n"); if( !cs_entry(matrix, matrix_row , plus_node , 1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } if( !cs_entry(matrix, plus_node , matrix_row , 1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } //nodeids[plus_node] = 1; //} } /* <-> */ if( minus_node != -1 ){ //if( nodeids[minus_node] == 0 ){ //printf("mphke minus node...\n"); if( !cs_entry(matrix, matrix_row , minus_node , -1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } if( !cs_entry(matrix, minus_node , matrix_row , -1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } //nodeids[minus_node] = 1; //} } } /* * Inductance */ else if ( curr->type == NODE_INDUCTANCE_TYPE ){ m2_elements_found++; int matrix_row = list->hashtable->num_nodes + m2_elements_found - 1 ; /* Change the matrix */ long plus_node = curr->node.inductance.node1 - 1; long minus_node = curr->node.inductance.node2 - 1; // printf("Inductance %s plus = %d minus = %d\n matrix_row = %d\n", curr->node.inductance.name,plus_node,minus_node,matrix_row); /* <+> */ if( plus_node != -1 ){ //if( nodeids[plus_node] == 0 ){ //printf("mphke inductance sto plus...\n"); if( !cs_entry(matrix, matrix_row , plus_node , 1.0) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } if( !cs_entry(matrix, plus_node , matrix_row , 1.0) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } //nodeids[plus_node] = 1; //} } /* <-> */ if( minus_node != -1 ){ //if( nodeids[minus_node] == 0 ){ //printf("mpahke Inductance minus_node...\n"); if( !cs_entry(matrix, matrix_row , minus_node , -1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } if( !cs_entry(matrix, minus_node , matrix_row , -1.0 ) ){ fprintf(stderr, "Error while inserting element in sparse matrix\n"); free(vector); cs_spfree(matrix); return NULL; } //nodeids[minus_node] = 1; //} } } } matrix = cs_compress(matrix); /* remove duplicates */ if( !cs_dupl(matrix) ){ fprintf(stderr, "Sparse matrix: duplicates not removed \n"); cs_spfree(matrix); free(vector); return NULL; } *vector_len = matrix->n; *b = vector; //cs_print(matrix,"sparse_matrix.txt",0); return matrix; }
static int cs_fact_init_umfpack( cs_fact_t *umfd, const cs *A ) { #ifdef USE_UMFPACK int ret; void *symbolic; cs *T; /* Create matrix and sort. */ /* Non-symmetric case. */ if (0) { T = cs_transpose( A, 1 ); umfd->A = cs_transpose( T, 1 ); cs_spfree( T ); } /* Symmetric case. */ else { umfd->A = cs_transpose( A, 1 ); } cs_dupl( umfd->A ); /* Generate symbolic. */ ret = umfpack_di_symbolic( umfd->n, umfd->n, umfd->A->p, umfd->A->i, umfd->A->x, &symbolic, NULL, NULL ); if (ret < UMFPACK_OK) goto err_sym; /* Generate numeric. */ ret = umfpack_di_numeric( umfd->A->p, umfd->A->i, umfd->A->x, symbolic, &umfd->numeric, NULL, NULL ); if (ret < UMFPACK_OK) goto err_num; else if (ret > UMFPACK_OK) { switch (ret) { case UMFPACK_WARNING_singular_matrix: fprintf( stderr, "UMFPACK: Matrix is singular.\n" ); break; case UMFPACK_WARNING_determinant_underflow: fprintf( stderr, "UMFPACK: Determinant underflow.\n" ); break; case UMFPACK_WARNING_determinant_overflow: fprintf( stderr, "UMFPACK: Determinant overflow.\n" ); break; } } /* Clean up symbolic. */ umfpack_di_free_symbolic( &symbolic ); /* Allocate buffers. */ umfd->wi = malloc( umfd->n * sizeof(int) ); if (umfd->wi == NULL) goto err_wi; umfd->w = malloc( umfd->n*5 * sizeof(double) ); /* We consider iteration refinement. */ if (umfd->w == NULL) goto err_w; umfd->x = calloc( umfd->n, sizeof(double) ); if (umfd->x == NULL) goto err_x; umfd->type = CS_FACT_UMFPACK; return 0; err_x: free( umfd->w ); err_w: free( umfd->wi ); err_wi: umfpack_di_free_numeric( &umfd->numeric ); err_num: umfpack_di_free_symbolic( &symbolic ); err_sym: cs_spfree( umfd->A ); return -1; #else /* USE_UMFPACK */ (void) umfd; (void) A; return -1; #endif /* USE_UMFPACK */ }
void computeMNASparse(){ int i,j; int b=1; int n=hashNode_num-1; sizeA = (hashNode_num-1)+m2; //Initialize and Allocate memory for A,B,x A_sparse = cs_spalloc((hashNode_num-1)+m2,(hashNode_num-1)+m2, sizeA_sparse, 1, 1); if(TRAN==1) D_sparse = cs_spalloc((hashNode_num-1)+m2,(hashNode_num-1)+m2, sizeD_sparse, 1, 1); sizeB = (hashNode_num-1)+m2; B_sparse = (double *)calloc(sizeB,sizeof(double)); x_sparse = (double *)calloc(sizeB,sizeof(double)); //Check Resistors, compute the 1st (n-1 x n-1) part of A ResistorT *runnerR=rootR; while(runnerR!=NULL) { i=atoi(ht_get(hashtable,runnerR->pos_term)); j=atoi(ht_get(hashtable,runnerR->neg_term)); if(i!=0) { cs_entry(A_sparse,i-1,i-1,1/runnerR->value); } if(j!=0) { cs_entry(A_sparse,j-1,j-1,1/runnerR->value); } if(i!=0&&j!=0) { cs_entry(A_sparse,i-1,j-1,-1/runnerR->value); cs_entry(A_sparse,j-1,i-1,-1/runnerR->value); } runnerR=runnerR->next; } //Check Voltage Sources, compute 2nd (n-1 x m2) part of A and 2nd (m2x1) part of B VoltageSourceT *runnerV=rootV; while(runnerV != NULL) { i=atoi(ht_get(hashtable,runnerV->pos_term)); //get nodes of Voltage Source j=atoi(ht_get(hashtable,runnerV->neg_term)); if(i!=0) { cs_entry(A_sparse,n-1+b,i-1,1.000); cs_entry(A_sparse,i-1,n-1+b,1.000); } if(j!=0) { cs_entry(A_sparse,n-1+b,j-1,-1.000); cs_entry(A_sparse,j-1,n-1+b,-1.000); } if((i!=0)||(j!=0)){B_sparse[n-1+b]=runnerV->value;} //Voltage value at B b++; runnerV= runnerV ->next; } //Check Inductors, compute 2nd (n-1 x m2) part of A InductorT *runnerL=rootL; while(runnerL != NULL) { i = atoi(ht_get(hashtable,runnerL->pos_term)); //get nodes of Inductor j = atoi(ht_get(hashtable,runnerL->neg_term)); if(i!=0) { cs_entry(A_sparse,n-1+b,i-1,1.000); cs_entry(A_sparse,i-1,n-1+b,1.000); } if(j!=0) { cs_entry(A_sparse,n-1+b,j-1,-1.000); cs_entry(A_sparse,j-1,n-1+b,-1.000); } if(TRAN==1){ cs_entry(D_sparse,n-1+b,n-1+b,-runnerL->value); cs_entry(D_sparse,n-1+b,n-1+b,-runnerL->value); } b++; runnerL= runnerL ->next; } //Check Current Source, compute 1st (n-1 x 1) part of B CurrentSourceT *runnerI=rootI; while(runnerI != NULL) { i = atoi(ht_get(hashtable,runnerI->pos_term)); //get nodes of Current Source j = atoi(ht_get(hashtable,runnerI->neg_term)); if(i!=0) { B_sparse[i-1]-=runnerI->value; } if(j!=0) { B_sparse[j-1]+=runnerI->value; } runnerI = runnerI ->next; } //Diatrexoume ti lista twn puknwtwn kai simplirwnoume katallila to 1o n-1 * n-1 kommati tou pinaka C if (TRAN==1){ CapacitorT *runnerC=rootC; while(runnerC!=NULL){ i=atoi(ht_get(hashtable,runnerC->pos_term)); j=atoi(ht_get(hashtable,runnerC->neg_term)); if(i!=0){ cs_entry(D_sparse,i-1,i-1,runnerC->value); } if(j!=0){ cs_entry(D_sparse,j-1,j-1,runnerC->value); } if(i!=0&&j!=0){ cs_entry(D_sparse,i-1,j-1,-runnerC->value); cs_entry(D_sparse,j-1,i-1,-runnerC->value); } runnerC=runnerC->next; } } cs_print(A_sparse, "./SparseFiles/A_Sparse.txt", 0); if (TRAN==1) cs_print(D_sparse, "./SparseFiles/D_Sparse.txt", 0); //Afou exoume ftiaksei ton A (mna) se triplet morfi, ton metatrepoume se //compressed-column morfi kai eleutherwnoume ton xwro me tin palia morfi kai //sigxwneuoume ta diaforetika non zeros pou vriskontai stin idia thesi C_sparse = cs_compress(A_sparse); cs_spfree(A_sparse); cs_dupl(C_sparse); cs_print(C_sparse, "./SparseFiles/C_Sparse.txt", 0); if (TRAN==1){ E_sparse = cs_compress(D_sparse); cs_spfree(D_sparse); cs_dupl(E_sparse); cs_print(E_sparse, "./SparseFiles/E_Sparsel.txt", 0); } }
int main(int argc, char *argv[]){ char c; int n=0, m=0; init(); FILE *fp=NULL; fp=fopen(argv[1],"r"); //Anoigma tou arxeiou if(fp==NULL){ //Elegxos an to arxeio anoikse kanonika, alliws termatismos.. printf("\nProblem opening file. Program terminated...\n"); return -1; } //Diavasma xaraktira kai antistoixi leitourgia analoga me auton (Provlepsi gia grammi sxoliwn kai gia telos arxeiou) c=fgetc(fp); do{ if(c=='V' || c=='v'){ m++; creatVoltList(fp); } else if(c=='I' || c=='i'){ creatAmberList(fp); } else if(c=='R' || c=='r'){ creatResistanceList(fp); } else if(c=='C' || c=='c'){ creatCapacitorList(fp); } else if(c=='L' || c=='l'){ m++; creatInductorList(fp); } else if(c=='D' || c=='d'){ creatDiodeList(fp); } else if(c=='M' || c=='m'){ creatMOSList(fp); } else if(c=='B' || c=='b'){ creatBJTList(fp); } else if(c=='%'){ c=fgetc(fp); while(c!='\n'&&(c!=EOF)){c=fgetc(fp);}/*MOVE TO NEXT LINE*/ } else if(c=='.'){ analysis(fp); } else{ } if(c!=EOF){c=fgetc(fp);} }while(!feof(fp)); fclose(fp); if(ground==0) { printf("No ground node! Program terminated!"); return -1; } else { printVoltList(rootV); printAmperList(rootI); printResistanceList(rootR); printCapacitorList(rootC); printInductorList(rootL); printDiodeList(rootD); printMosList(rootM); printBjttList(rootB); } n=count_nodes(); printf("\n m=%d , n=%d \n\n", m, n); int size=0; size = (n-1)+m; if(sparse_option == 0){ gsl_matrix* pinakasA = gsl_matrix_calloc(size,size); gsl_vector* pinakasB = gsl_vector_calloc(size); fill_matrix_A(pinakasA, pinakasB, n); fill_matrix_B(pinakasB); printf(" O pinakas A einai o: \n"); print2DMatrix(pinakasA, size); printf("\n O pinakas B einai o: \n"); print1DMatrix(pinakasB,size); printf("\n"); if(use_lu==1){ if(found_iter==1){ call_bi_cg(pinakasA, pinakasB, size); } else{ luDecomp(pinakasA, pinakasB, size); } } else if (use_cholesky==1){ if (found_iter==1){ call_cg(pinakasA, pinakasB, size); } else{ choleskyDecomp(pinakasA, pinakasB, size); } } } else { int i; cs* pinakasA_sparse = cs_spalloc(size,size,4*sparse_elements,1,1); double* pinakasB_sparse = (double *)calloc(size,sizeof(double)); double* pinakasX_sparse = (double *)calloc(size,sizeof(double)); fill_sparse_matrix_A(pinakasA_sparse, pinakasB_sparse,n); cs* pinakasC_sparse = cs_compress(pinakasA_sparse); cs_spfree(pinakasA_sparse); cs_dupl(pinakasC_sparse); if(use_lu==1){ if(found_iter==1){ call_bi_cg_sparse(pinakasC_sparse, pinakasB_sparse, pinakasX_sparse, size); } else{ luDecomp_sparse(pinakasC_sparse, pinakasB_sparse, pinakasX_sparse, size); } } else if (use_cholesky==1){ if (found_iter==1){ call_cg_sparse(pinakasC_sparse, pinakasB_sparse, pinakasX_sparse, size); } else{ choleskyDecomp_sparse(pinakasC_sparse, pinakasB_sparse, pinakasX_sparse, size); } } } return 0; }
mnaSpSystem *formatMnaTableSparse ( zeroCircuit *circuit, hashTable *names, int v_num, int l_num, int r_num, int i_num ) { int rows; int k_pos; int maxEstimated; zeroCircuit *cur; mnaSpSystem *finalSystem; cs *A, *Cm; //initialize k position k_pos = 0; finalSystem = ( mnaSpSystem * )malloc ( sizeof( mnaSpSystem ) ); rows = ( names->currPos ) + v_num + l_num ; //dimension of original matrix maxEstimated = 2 * ( 4 * r_num + 1 * v_num + 2 * i_num ); A = cs_spalloc(rows, rows, maxEstimated, 1, 1); if ( A == NULL ) { printf( "!!!WARNING!!! Table A was NOT allocated successfully\n" ); printf( "\t-Dimension of system to be allocated : %d\n\n", rows ); } //Transient Analysis : Build C if (cmdList->_transient == 1) { Cm = cs_spalloc(rows,rows,maxEstimated,1,1); } finalSystem->vector_B = (double *)calloc(rows, sizeof(double)); finalSystem->vector_X = (char **)malloc( rows * sizeof (char *) ); finalSystem->dim = rows; //for ( cur = circuit->next; (cur->linElement == NULL && cur->nonlinElement == NULL); cur = cur->next ) for( cur = circuit->next; ( (cur->linElement != NULL) || (cur->nonlinElement != NULL) ); cur = cur->next ) { if (( cur->linElement->element == 2 ) || ( cur->linElement->element == 5 )) //if element is voltage source or inductor { k_pos++; } addElementStampSparse ( cur, finalSystem, A, names, rows, k_pos ); //Transient Analysis : Build C if (cmdList->_transient == 1) { buildCSp( cur, Cm, names, k_pos); } } finalSystem->array_A = cs_compress(A); cs_dupl(finalSystem->array_A); cs_spfree(A); //Transient Analysis : Build C if (cmdList->_transient == 1) { finalSystem->array_C = cs_compress(Cm); cs_dupl(finalSystem->array_C); cs_spfree(Cm); } return ( finalSystem ); }