29 #ifndef BASKER_DEF_HPP 
   30 #define BASKER_DEF_HPP 
   32 #include "basker_decl.hpp" 
   33 #include "basker_scalartraits.hpp" 
   45 namespace BaskerClassicNS{
 
   47   template <
class Int, 
class Entry>
 
   48   BaskerClassic<Int, Entry>::BaskerClassic()
 
   52     A = 
new basker_matrix<Int,Entry>;
 
   55     L = 
new basker_matrix<Int, Entry>;
 
   59     U = 
new basker_matrix<Int,Entry>;
 
   70   template <
class Int, 
class Entry>
 
   71   BaskerClassic<Int, Entry>::BaskerClassic(Int nnzL, Int nnzU)
 
   75     A = 
new basker_matrix<Int, Entry>;
 
   77     L = 
new basker_matrix<Int, Entry>;
 
   80     U = 
new basker_matrix<Int, Entry>;
 
   91   template <
class Int, 
class Entry>
 
   92   BaskerClassic<Int, Entry>::~BaskerClassic()
 
  114   template <
class Int, 
class Entry>
 
  115   int BaskerClassic<Int,Entry>:: basker_dfs
 
  131     Int start, end, done, *store ;
 
  136     bool has_elements = 
true;
 
  153             BASKERASSERT (color[j] == 1) ; 
 
  161             for ( i1 = start ; i1 < end ; i1++ )
 
  175             pattern[--*top] = j ;
 
  179                 has_elements = 
false;
 
  188     std::cout << 
"Out of DFS: " << j << std::endl;
 
  193   template <
class Int, 
class Entry>
 
  194   int BaskerClassic<Int,Entry>::factor(Int nrow, Int ncol , Int nnz, Int *col_ptr, Int *row_idx, Entry *val)
 
  200     BASKERASSERT(nrow > 0);
 
  201     BASKERASSERT(ncol > 0);
 
  202     BASKERASSERT(nnz > 0);
 
  209     A->col_ptr = col_ptr;
 
  210     A->row_idx = row_idx;
 
  222     L->col_ptr = 
new Int[ncol+1]();
 
  224     L->row_idx = 
new Int[L->nnz]();
 
  226     L->val =  
new Entry[L->nnz]();
 
  235     U->col_ptr = 
new Int[ncol+1]();
 
  237     U->row_idx = 
new Int[U->nnz]();
 
  239     U->val = 
new Entry[U->nnz]();
 
  241     if((L->col_ptr == NULL) || (L->row_idx == NULL) || (L->val == NULL) ||
 
  242        (U->col_ptr == NULL) || (U->row_idx == NULL) || (U->val == NULL))
 
  253     tptr = 
new Int[(ncol)+(4*nrow)]();
 
  255     X = 
new Entry[2*nrow]();
 
  257     pinv = 
new Int[ncol+1]();
 
  260     if( (tptr == NULL) || (X == NULL) || (pinv == NULL) )
 
  270     Int *color, *pattern, *stack; 
 
  271     Int top, top1, maxindex, t; 
 
  272     Int lnnz, unnz, xnnz, lcnt, ucnt;
 
  273     Int cu_ltop, cu_utop;
 
  276     Entry pivot, value, xj;
 
  295     for(k = 0 ; k < ncol; k++)
 
  301     for (k = 0; k < ncol; k++)
 
  305         cout << 
"k = " << k << endl;
 
  317         BASKERASSERT (top == ncol);
 
  319         for(i = 0; i < nrow; i++)
 
  321             BASKERASSERT(X[i] == (Entry)0);
 
  323         for(i = 0; i < ncol; i++)
 
  325             BASKERASSERT(color[i] == 0);
 
  329         for( i = col_ptr[k];  i < col_ptr[k+1]; i++)
 
  337                 basker_dfs(nrow, j, L->row_idx, L->col_ptr, color, pattern, &top, pinv, stack);
 
  346         cout << ncol << endl;
 
  347         cout << xnnz << endl;
 
  352         for(pp = 0; pp < xnnz; pp++)
 
  361                 p2 = L->col_ptr[t+1];
 
  362                 for(p = L->col_ptr[t]+1; p < p2; p++)
 
  364                     X[L->row_idx[p]] -= L->val[p] * xj;
 
  372         for(i = top; i < nrow; i++)
 
  379             absv = BASKER_ScalarTraits<Entry>::approxABS(value);
 
  384                 if( BASKER_ScalarTraits<Entry>::gt(absv , maxv))
 
  393         ucnt = nrow - top - lcnt + 1;
 
  395         if(maxindex == ncol || pivot == ((Entry)0))
 
  397             cout << 
"Matrix is singular at index: " << maxindex << 
" pivot: " << pivot << endl;
 
  406             cout << 
"Permuting pivot: " << k << 
" for row: " << maxindex << endl;
 
  410         if(lnnz + lcnt >= L->nnz)
 
  413             newsize = L->nnz * 1.1 + 2*nrow + 1;
 
  415             cout << 
"Out of memory -- Reallocating.  Old Size: " << L->nnz << 
" New Size: " << newsize << endl;
 
  418             L->row_idx = int_realloc(L->row_idx , L->nnz, newsize);
 
  421                 cout << 
"WARNING: Cannot Realloc Memory" << endl;
 
  426             L->val = entry_realloc(L->val, L->nnz, newsize);
 
  429                 cout << 
"WARNING: Cannot Realloc Memory" << endl;
 
  437         if(unnz + ucnt >= U->nnz)
 
  439             newsize = U->nnz*1.1 + 2*nrow + 1;
 
  441             cout << 
"Out of memory -- Reallocating.  Old Size: " << U->nnz << 
" New Size: " << newsize << endl;
 
  444             U->row_idx = int_realloc(U->row_idx, U->nnz, newsize);
 
  447                 cout << 
"WARNING: Cannot Realloc Memory" << endl;
 
  453             U->val = entry_realloc(U->val, U->nnz, newsize);
 
  456                 cout << 
"WARNING: Cannot Realloc Memory" << endl;
 
  464         L->row_idx[lnnz] = maxindex;
 
  468         Entry last_v_temp = 0;
 
  470         for(i = top; i < nrow; i++)
 
  478             if(X[j] != ((Entry)0))
 
  485                         cout << 
"BASKER: Insufficent memory for U" << endl;
 
  492                         U->row_idx[unnz] = pinv[j];
 
  508                         cout << 
"BASKER: Insufficent memory for L" << endl;
 
  513                     L->row_idx[lnnz]  = j;
 
  515                     L->val[lnnz] = BASKER_ScalarTraits<Entry>::divide(X[j],pivot);
 
  527         U->row_idx[unnz] = k;
 
  528         U->val[unnz] = last_v_temp;
 
  534         L->col_ptr[k] = cu_ltop;
 
  535         L->col_ptr[k+1] = lnnz;
 
  538         U->col_ptr[k] = cu_utop;
 
  539         U->col_ptr[k+1] = unnz;
 
  546     for(k = 0; k < lnnz; k++)
 
  548         printf(
"L[%d]=%g" , k , L->val[k]);
 
  551     for(k = 0; k < lnnz; k++)
 
  553         printf(
"Li[%d]=%d", k, L->row_idx[k]);
 
  556     for(k = 0; k < nrow; k++)
 
  558         printf(
"p[%d]=%d", k, pinv[k]);
 
  563     for(k = 0; k < ncol; k++)
 
  565         printf(
"Up[%d]=%d", k, U->col_ptr[k]);
 
  569     for(k = 0; k < unnz; k++)
 
  571         printf(
"U[%d]=%g" , k , U->val[k]);
 
  574     for(k = 0; k < unnz; k++)
 
  576         printf(
"Ui[%d]=%d", k, U->row_idx[k]);
 
  583     for( i = 0; i < ncol; i++)
 
  585         for(k = L->col_ptr[i]; k < L->col_ptr[i+1]; k++)
 
  595     cout << 
"After Permuting" << endl;
 
  596     for(k = 0; k < lnnz; k++)
 
  598         printf(
"Li[%d]=%d", k, L->row_idx[k]);
 
  614   template <
class Int, 
class Entry>
 
  615   Int BaskerClassic<Int, Entry>::get_NnzL()
 
  620   template <
class Int, 
class Entry>
 
  621   Int BaskerClassic<Int, Entry>::get_NnzU()
 
  626   template <
class Int, 
class Entry>
 
  627   Int BaskerClassic<Int, Entry>::get_NnzLU()
 
  629     return (actual_lnnz + actual_unnz);
 
  632   template <
class Int, 
class Entry>
 
  633   int BaskerClassic<Int, Entry>::returnL(Int *dim, Int *nnz, Int **col_ptr, Int **row_idx, Entry **val)
 
  642     *col_ptr = 
new Int[L->nrow+1];
 
  644     *row_idx = 
new Int[L->nnz];
 
  646     *val = 
new Entry[L->nnz];
 
  648     if( (*col_ptr == NULL) || (*row_idx == NULL) || (*val == NULL) )
 
  653     for(i = 0; i < L->nrow+1; i++)
 
  655         (*col_ptr)[i] = L->col_ptr[i];
 
  658     for(i = 0; i < actual_lnnz; i++)
 
  660         (*row_idx)[i] = pinv[L->row_idx[i]];
 
  661         (*val)[i]     = L->val[i];
 
  667   template <
class Int, 
class Entry>
 
  668   int BaskerClassic<Int, Entry>::returnU(Int *dim, Int *nnz, Int **col_ptr, Int **row_idx, Entry **val)
 
  675     *col_ptr = 
new Int[U->nrow+1];
 
  677     *row_idx = 
new Int[U->nnz];
 
  679     *val = 
new Entry[U->nnz];
 
  681     if( (*col_ptr == NULL) || (*row_idx == NULL) || (*val == NULL) )
 
  686     for(i = 0; i < U->nrow+1; i++)
 
  688         (*col_ptr)[i] = U->col_ptr[i];
 
  690     for(i = 0; i < actual_unnz; i++)
 
  692         (*row_idx)[i] = U->row_idx[i];
 
  693         (*val)[i]     = U->val[i];
 
  698   template <
class Int, 
class Entry>
 
  699   int BaskerClassic<Int, Entry>::returnP(Int** p)
 
  703     *p = 
new Int[A->nrow];
 
  710     for(i = 0; i < A->nrow; i++)
 
  717   template <
class Int, 
class Entry>
 
  718   void BaskerClassic<Int, Entry>::free_factor()
 
  737   template <
class Int, 
class Entry>
 
  738   void BaskerClassic<Int, Entry>::free_perm_matrix()
 
  745   template <
class Int, 
class Entry>
 
  746   int BaskerClassic<Int, Entry>::solveMultiple(Int nrhs, Entry *b, Entry *x)
 
  749     for(i = 0; i < nrhs; i++)
 
  752         int result = solve(&(b[k]), &(x[k]));
 
  755             cout << 
"Error in Solving \n";
 
  763   template <
class Int, 
class Entry>
 
  764   int BaskerClassic<Int, Entry>::solve(Entry* b, Entry* x)
 
  772     Entry* temp = 
new Entry[A->nrow]();
 
  775     for(i = 0 ; i < A->ncol; i++)
 
  781     result = low_tri_solve_csc(L->nrow, L->col_ptr, L->row_idx, L->val, temp, x);
 
  784         result = up_tri_solve_csc(U->nrow, U->col_ptr, U->row_idx, U->val, x, temp);
 
  793   template < 
class Int, 
class Entry>
 
  794   int BaskerClassic<Int, Entry>::low_tri_solve_csc( Int n, Int *col_ptr, Int *row_idx, Entry* val,   Entry *x, Entry *b)
 
  798     for(i = 0; i < n ; i++)
 
  801         BASKERASSERT(val[col_ptr[i]] != (Entry)0);
 
  803         if(val[col_ptr[i]] == (Entry) 0)
 
  808         x[i] = BASKER_ScalarTraits<Entry>::divide(b[i], val[col_ptr[i]]);
 
  810         for(j = col_ptr[i]+1; j < (col_ptr[i+1]); j++) 
 
  812             b[pinv[row_idx[j]]] = b[pinv[row_idx[j]]] - (val[j]*x[i]);
 
  818   template < 
class Int, 
class Entry>
 
  819   int BaskerClassic<Int, Entry>::up_tri_solve_csc( Int n, Int *col_ptr, Int *row_idx, Entry *val, Entry *x,  Entry *b)
 
  823     for(i = n; i > 1 ; i--)
 
  827         BASKERASSERT(val[col_ptr[i]-1] != (Entry)0);
 
  829         if(val[col_ptr[i]-1] == (Entry) 0)
 
  831             cout << 
"Dig(" << i << 
") = " << val[col_ptr[i]-1] << endl;
 
  836         x[ii] = BASKER_ScalarTraits<Entry>::divide(b[ii],val[col_ptr[i]-1]);
 
  838         for(j = (col_ptr[i]-2); j >= (col_ptr[ii]); j--)
 
  840             b[row_idx[j]] = b[row_idx[j]] - (val[j]*x[ii]);
 
  844     x[0] = BASKER_ScalarTraits<Entry>::divide(b[0],val[col_ptr[1]-1]);
 
  848   template <
class Int, 
class Entry>
 
  849   int BaskerClassic<Int, Entry>::preorder(Int *row_perm, Int *col_perm)
 
  852     basker_matrix <Int, Entry> *B;
 
  853     B = 
new basker_matrix<Int, Entry>;
 
  857     B->col_ptr = (Int *) BASKERCALLOC(A->ncol + 1, 
sizeof(Int));
 
  858     B->row_idx = (Int *) BASKERCALLOC(A->nnz, 
sizeof(Int));
 
  859     B->val     = (Entry *) BASKERCALLOC(A->val, 
sizeof(Int));
 
  861     if( (B->col_ptr == NULL) || (B->row_idx == NULL) || (B->val == NULL) )
 
  867      (void) permute_column(col_perm, B);
 
  868      (void) permute_row(row_perm, B);
 
  872     A->col_ptr = B->col_ptr;
 
  873     A->row_idx = B->row_idx;
 
  881   template <
class Int, 
class Entry>
 
  882   int BaskerClassic <Int, Entry>::permute_column(Int *p, basker_matrix<Int,Entry> *B)
 
  888     for(j=0; j < B->ncol; j++)
 
  891         B->col_ptr[i+1] = A->col_ptr[j+1] - A->col_ptr[j];
 
  895     for(j=0; j < B->ncol; j++)
 
  897         B->col_ptr[j+1] = B->col_ptr[j+1] + B->col_ptr[j];
 
  902     for(ii = 0 ; ii < B->ncol; ii++)
 
  904         ko = B->col_ptr(p[ii]);
 
  905         for(k = A->col_ptr[ii]; k < A->col_ptr[ii+1]; k++)
 
  907             B->row_index[ko] = A->row_index[k];
 
  908             B->val[ko] = A->val[ko];
 
  915   template <
class Int, 
class Entry>
 
  916   int BaskerClassic <Int, Entry>::permute_row(Int *p,  basker_matrix<Int,Entry> *B)
 
  919     for(k=0; k < A->nnz; k++)
 
  921         B->row_idx[k] = p[A->row_idx[k]];
 
  926   template <
class Int, 
class Entry>
 
  927   int BaskerClassic <Int, Entry>::sort_factors()
 
  934     for(i = 0 ; i < L->ncol; i++)
 
  939         for(j = L->col_ptr[i]+1; j < (L->col_ptr[i+1]); j++)
 
  941             if(L->row_idx[j] < val)
 
  947         Int temp_index = L->row_idx[L->col_ptr[i]];
 
  948         Entry temp_entry = L->val[L->col_ptr[i]];
 
  949         L->row_idx[L->col_ptr[i]] = val;
 
  950         L->val[L->col_ptr[i]] = L->val[p];
 
  951         L->row_idx[p] = temp_index;
 
  952         L->val[p] = temp_entry;
 
  957      for(i = 0 ; i < U->ncol; i++)
 
  959         p = U->col_ptr[i+1]-1;
 
  962         for(j = U->col_ptr[i]; j < (U->col_ptr[i+1]-1); j++)
 
  964             if(U->row_idx[j] > val)
 
  970         Int temp_index = U->row_idx[U->col_ptr[i+1]-1];
 
  971         Entry temp_entry = U->val[U->col_ptr[i+1]-1];
 
  972         U->row_idx[U->col_ptr[i+1]-1] = val;
 
  973         U->val[U->col_ptr[i+1]-1] = U->val[p];
 
  974         U->row_idx[p] = temp_index;
 
  975         U->val[p] = temp_entry;
 
  981   template <
class Int, 
class Entry>
 
  982   Entry*  BaskerClassic <Int, Entry>::entry_realloc(Entry *old , Int old_size, Int new_size)
 
  984     Entry *new_entry = 
new Entry[new_size];
 
  985     for(Int i = 0; i < old_size; i++)
 
  988         new_entry[i] = old[i];
 
  995   template <
class Int, 
class Entry>
 
  996   Int* BaskerClassic <Int, Entry>::int_realloc(Int *old, Int old_size, Int new_size)
 
  998     Int *new_int = 
new Int[new_size];
 
  999     for(Int i =0; i < old_size; i++)
 
 1002         new_int[i] = old[i];