Exemplo n.º 1
0
/**
 * \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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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