/** * \brief used to check if bigint is large enough * Checks if the memory of a is large enough to hold min_size * words, and if this is not the case tries to increase the allocated memory * amount (conserving the memory content). * If the allocated memory insufficient and the buffer could not be enlarged * E_OOM is returned, otherwise 0 is returned. */ static int check_size(bigint_t *a, bigint_length_t min_size) { bigint_word_t *tmp; if (a->allocated_W >= min_size) { return 0; } tmp = int_realloc(a->wordv, min_size * sizeof(bigint_word_t)); if (!tmp) { return E_OOM; } a->wordv = tmp; a->allocated_W = min_size; return 0; }
uint8_t bigint_read_hex_echo(bigint_t *a, bigint_length_t length) { uint8_t shift4 = 0; uint16_t t, idx = 0; uint8_t *buf = NULL; memset(a, 0, sizeof(*a)); if (length && a->allocated_W < length) { uint8_t *p; p = int_realloc(buf, length * sizeof(bigint_word_t)); if (p == NULL) { cli_putstr("\r\nERROR: Out of memory!"); return 0xff; } memset((uint8_t*)p, 0, length * sizeof(bigint_word_t)); buf = p; a->allocated_W = length; } for (;;) { if (a->allocated_W - idx < 1) { uint8_t *p; if (length) { if (buf) { int_realloc(buf, 0); } return 0xfe; } p = int_realloc(buf, (a->allocated_W += BLOCKSIZE) * sizeof(bigint_word_t)); if (p == NULL) { cli_putstr("\r\nERROR: Out of memory!"); if (buf) { int_realloc(buf, 0); } return 0xff; } memset((uint8_t*)p + (a->allocated_W - BLOCKSIZE) * sizeof(bigint_word_t), 0, BLOCKSIZE * sizeof(bigint_word_t)); buf = p; } t = read_byte(); if (idx == 0) { if (t & 0x0400) { /* got minus */ a->info |= BIGINT_SIGN_MASK; continue; } else { if (t == 0x0100) { free(a->wordv); memset(a, 0, sizeof(*a)); return 1; } } } if (t <= 0x00ff) { buf[idx++] = (uint8_t)t; } else { if (t & 0x0200) { shift4 = 1; buf[idx++] = (uint8_t)((t & 0x0f) << 4); } break; } } /* we have to reverse the byte array */ uint8_t tmp; uint8_t *p, *q; a->length_W = (idx + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); p = buf; q = buf + idx - 1; while (q > p) { tmp = *p; *p = *q; *q = tmp; p++; q--; } a->wordv = (bigint_word_t*)buf; if (shift4) { bigint_shiftright_1bit(a); bigint_shiftright_1bit(a); bigint_shiftright_1bit(a); bigint_shiftright_1bit(a); } if(a->length_W == 1 && a->wordv[0] == 0){ a->length_W = 0; a->info = 0; } if (length) { a->length_W = length; } return 0; }
int Basker<Int,Entry>::factor(Int nrow, Int ncol , Int nnz, Int *col_ptr, Int *row_idx, Entry *val) { int ierr = 0; /*Initalize A basker matrix struc */ #ifdef BASKER_DEBUG ASSERT(nrow > 0); ASSERT(ncol > 0); ASSERT(nnz > 0); #endif A->nrow = nrow; A->ncol = ncol; A->nnz = nnz; A->col_ptr = col_ptr; A->row_idx = row_idx; A->val = val; /*End initalize A*/ /*Creating space for L and U*/ L->nrow = nrow; L->ncol = ncol; if(L->nnz == 0) { L->nnz = 2*A->nnz; } //L->col_ptr = (Int *) CALLOC(ncol+1, sizeof(Int)); L->col_ptr = new Int[ncol+1](); //L->row_idx = (Int *) CALLOC(L->nnz, sizeof(Int)); L->row_idx = new Int[L->nnz](); //L->val = (Entry *) CALLOC(L->nnz, sizeof(Entry)); L->val = new Entry[L->nnz](); U->nrow = nrow; U->ncol = ncol; if(U->nnz == 0) { U->nnz = 2*A->nnz; } //U->col_ptr = (Int *) CALLOC(ncol+1, sizeof(Int)); U->col_ptr = new Int[ncol+1](); //U->row_idx = (Int *) CALLOC(U->nnz, sizeof(Int)); U->row_idx = new Int[U->nnz](); //U->val = (Entry *) CALLOC(U->nnz, sizeof(Entry)); U->val = new Entry[U->nnz](); if((L->col_ptr == NULL) || (L->row_idx == NULL) || (L->val == NULL) || (U->col_ptr == NULL) || (U->row_idx == NULL) || (U->val == NULL)) { ierr = -1; return ierr; } /*End creating space for L and U*/ /*Creating working space*/ Int *tptr; Entry *X; //tptr = (Int *) CALLOC( (ncol)+(4*nrow), sizeof(Int)); tptr = new Int[(ncol)+(4*nrow)](); //X = (Entry *) CALLOC(2*nrow, sizeof(Entry)); X = new Entry[2*nrow](); //pinv = (Int * ) CALLOC(ncol+1, sizeof(Int)); //Note extra pad pinv = new Int[ncol+1](); if( (tptr == NULL) || (X == NULL) || (pinv == NULL) ) { ierr = -2; return ierr; } /*End creating working space */ /*Defining Variables Used*/ Int i, j, k; Int *color, *pattern, *stack; // pointers into the work space Int top, top1, maxindex, t; // j1, j2; Int lnnz, unnz, xnnz, lcnt, ucnt; Int cu_ltop, cu_utop; Int pp, p2, p; Int newsize; Entry pivot, value, xj; Entry absv, maxv; color = tptr; tptr += ncol; pattern = tptr; tptr += nrow; stack = tptr; tptr += 2*(nrow); cu_ltop = 0; cu_utop = 0; top = ncol; top1 = ncol; lnnz = 0; //real found lnnz unnz = 0; //real found unnz for(k = 0 ; k < ncol; k++) { pinv[k] = ncol; } /*For all columns in A .... */ for (k = 0; k < ncol; k++) { #ifdef BASKER_DEBUG cout << "k = " << k << endl; #endif value = 0.0; pivot = 0.0; maxindex = ncol; //j1 = 0; //j2 = 0; lcnt = 0; ucnt = 0; #ifdef BASKER_DEBUG ASSERT (top == ncol); for(i = 0; i < nrow; i++) { ASSERT(X[i] == (Entry)0); } for(i = 0; i < ncol; i++) { ASSERT(color[i] == 0); } #endif /* Reachability for every nonzero in Ak */ for( i = col_ptr[k]; i < col_ptr[k+1]; i++) { j = row_idx[i]; X[j] = val[i]; if(color[j] == 0) { //do dfs basker_dfs(nrow, j, L->row_idx, L->col_ptr, color, pattern, &top, pinv, stack); } }//end reachable xnnz = ncol - top; #ifdef BASKER_DEBUG cout << top << endl; cout << ncol << endl; cout << xnnz << endl; //ASSERT(xnnz <= nrow); #endif /*Lx = b where x will be the column k in L and U*/ top1 = top; for(pp = 0; pp < xnnz; pp++) { j = pattern[top1++]; color[j] = 0; t = pinv[j]; if(t!=ncol) //it has not been assigned { xj = X[j]; p2 = L->col_ptr[t+1]; for(p = L->col_ptr[t]+1; p < p2; p++) { X[L->row_idx[p]] -= L->val[p] * xj; }//over all rows } } /*get the pivot*/ maxv = 0.0; for(i = top; i < nrow; i++) { j = pattern[i]; t = pinv[j]; value = X[j]; /*note may want to change this to traits*/ //absv = (value < 0.0 ? -value : value); absv = BASKER_ScalarTraits<Entry>::approxABS(value); if(t == ncol) { lcnt++; if( BASKER_ScalarTraits<Entry>::gt(absv , maxv)) //if(absv > BASKER_ScalarTraits<Entry>::approxABS(maxv)) { maxv = absv; pivot = value; maxindex= j; } } } ucnt = nrow - top - lcnt + 1; if(maxindex == ncol || pivot == ((Entry)0)) { cout << "Matrix is singular at index: " << maxindex << " pivot: " << pivot << endl; ierr = maxindex; return ierr; } pinv[maxindex] = k; #ifdef BASKER_DEBUG if(maxindex != k ) { cout << "Permuting pivot: " << k << " for row: " << maxindex << endl; } #endif if(lnnz + lcnt >= L->nnz) { newsize = L->nnz * 1.1 + 2*nrow + 1; #ifdef BASKER_DEBUG cout << "Out of memory -- Reallocating. Old Size: " << L->nnz << " New Size: " << newsize << endl; #endif //L->row_idx = (Int *) REALLOC(L->row_idx, newsize*sizeof(Int)); L->row_idx = int_realloc(L->row_idx , L->nnz, newsize); if(!(L->row_idx)) { cout << "WARNING: Cannot Realloc Memory" << endl; ierr = -3; return ierr; } //L->val = (Entry *) REALLOC(L->val, newsize*sizeof(Entry)); L->val = entry_realloc(L->val, L->nnz, newsize); if(!(L->val)) { cout << "WARNING: Cannot Realloc Memory" << endl; ierr = -3; return ierr; } L->nnz = newsize; }//realloc if L is out of memory if(unnz + ucnt >= U->nnz) { newsize = U->nnz*1.1 + 2*nrow + 1; #ifdef BASKER_DEBUG cout << "Out of memory -- Reallocating. Old Size: " << U->nnz << " New Size: " << newsize << endl; #endif //U->row_idx = (Int *) REALLOC(U->row_idx, newsize*sizeof(Int)); U->row_idx = int_realloc(U->row_idx, U->nnz, newsize); if(!(U->row_idx)) { cout << "WARNING: Cannot Realloc Memory" << endl; ierr = -3; return ierr; } //U->val = (Entry *) REALLOC(U->val, newsize*sizeof(Entry)); U->val = entry_realloc(U->val, U->nnz, newsize); if(!(U->val)) { cout << "WARNING: Cannot Realloc Memory" << endl; ierr = -3; return ierr; } U->nnz = newsize; }//realloc if U is out of memory //L->col_ptr[lnnz] = maxindex; L->row_idx[lnnz] = maxindex; L->val[lnnz] = 1.0; lnnz++; Entry last_v_temp = 0; for(i = top; i < nrow; i++) { j = pattern[i]; t = pinv[j]; /* check for numerical cancellations */ if(X[j] != ((Entry)0)) { if(t != ncol) { if(unnz >= U->nnz) { cout << "BASKER: Insufficent memory for U" << endl; ierr = -3; return ierr; } if(t < k) //if(true) { U->row_idx[unnz] = pinv[j]; U->val[unnz] = X[j]; unnz++; } else { last_v_temp = X[j]; //cout << "Called. t: " << t << "Val: " << last_v_temp << endl; } } else if (t == ncol) { if(lnnz >= L->nnz) { cout << "BASKER: Insufficent memory for L" << endl; ierr = -3; return ierr; } L->row_idx[lnnz] = j; //L->val[lnnz] = X[j]/pivot; L->val[lnnz] = BASKER_ScalarTraits<Entry>::divide(X[j],pivot); lnnz++; } } X[j] = 0; } //cout << "Value added at end: " << last_v_temp << endl; U->row_idx[unnz] = k; U->val[unnz] = last_v_temp; unnz++; xnnz = 0; top = ncol; L->col_ptr[k] = cu_ltop; L->col_ptr[k+1] = lnnz; cu_ltop = lnnz; U->col_ptr[k] = cu_utop; U->col_ptr[k+1] = unnz; cu_utop = unnz; } //end for every column #ifdef BASKER_DEBUG /*Print out found L and U*/ for(k = 0; k < lnnz; k++) { printf("L[%d]=%g" , k , L->val[k]); } cout << endl; for(k = 0; k < lnnz; k++) { printf("Li[%d]=%d", k, L->row_idx[k]); } cout << endl; for(k = 0; k < nrow; k++) { printf("p[%d]=%d", k, pinv[k]); } cout << endl; cout << endl; for(k = 0; k < ncol; k++) { printf("Up[%d]=%d", k, U->col_ptr[k]); } cout << endl; for(k = 0; k < unnz; k++) { printf("U[%d]=%g" , k , U->val[k]); } cout << endl; for(k = 0; k < unnz; k++) { printf("Ui[%d]=%d", k, U->row_idx[k]); } cout << endl; #endif /* Repermute */ for( i = 0; i < ncol; i++) { for(k = L->col_ptr[i]; k < L->col_ptr[i+1]; k++) { //L->row_idx[k] = pinv[L->row_idx[k]]; } } //Max sure correct location of min in L and max in U for CSC format// //Speeds up tri-solve// //sort_factors(); #ifdef BASKER_DEBUG cout << "After Permuting" << endl; for(k = 0; k < lnnz; k++) { printf("Li[%d]=%d", k, L->row_idx[k]); } cout << endl; #endif //FREE(X); //FREE(tptr); been_fact = true; return 0; }//end factor