Ejemplo n.º 1
0
/* sizeLinearArray:
 * Determine sizes of rows and columns. The size of a column is the
 * maximum width of any cell in it. Similarly for rows.
 * A cell spanning columns contributes proportionately to each column
 * it is in.
 */
void sizeLinearArray(htmltbl_t * tbl)
{
    htmlcell_t *cp;
    htmlcell_t **cells;
    int wd, ht, i, x, y;

    tbl->heights = N_NEW(tbl->rc + 1, int);
    tbl->widths = N_NEW(tbl->cc + 1, int);

    for (cells = tbl->u.n.cells; *cells; cells++) {
	cp = *cells;
	if (cp->rspan == 1)
	    ht = cp->data.box.UR.y;
	else {
	    ht = SPLIT(cp->data.box.UR.y, cp->rspan, tbl->data.space);
	    ht = MAX(ht, 1);
	}
	if (cp->cspan == 1)
	    wd = cp->data.box.UR.x;
	else {
	    wd = SPLIT(cp->data.box.UR.x, cp->cspan, tbl->data.space);
	    wd = MAX(wd, 1);
	}
	for (i = cp->row; i < cp->row + cp->rspan; i++) {
	    y = tbl->heights[i];
	    tbl->heights[i] = MAX(y, ht);
	}
	for (i = cp->col; i < cp->col + cp->cspan; i++) {
	    x = tbl->widths[i];
	    tbl->widths[i] = MAX(x, wd);
	}
    }
}
Ejemplo n.º 2
0
static void fb_rdct_low(dig_t *c, dig_t *a, int fa) {
	int i, sh, lh, rh, sa, la, ra;
	dig_t d;

	SPLIT(rh, sh, FB_BITS, FB_DIG_LOG);
	sh++;
	lh = FB_DIGIT - rh;

	SPLIT(ra, sa, FB_BITS - fa, FB_DIG_LOG);
	sa++;
	la = FB_DIGIT - ra;

	for (i = 2 * FB_DIGS - 1; i >= sh; i--) {
		d = a[i];
		a[i] = 0;

		if (rh == 0) {
			a[i - sh + 1] ^= d;
		} else {
			a[i - sh + 1] ^= (d >> rh);
			a[i - sh] ^= (d << lh);
		}
		if (ra == 0) {
			a[i - sa + 1] ^= d;
		} else {
			a[i - sa + 1] ^= (d >> ra);
			a[i - sa] ^= (d << la);
		}
	}

	if (FB_BITS % FB_DIGIT == 0) {
		while (a[FB_DIGS] != 0) {

			d = a[sh - 1] >> rh;

			a[0] ^= d;
			d <<= rh;

			if (ra == 0) {
				a[sh - sa] ^= d;
			} else {
				a[sh - sa] ^= (d >> ra);
				if (sh > sa) {
					a[sh - sa - 1] ^= (d << la);
				}
			}
			a[sh - 1] ^= d;
		}
	} else {
Ejemplo n.º 3
0
void fp_lsh(fp_t c, const fp_t a, int bits) {
	int digits;

	SPLIT(bits, digits, bits, FP_DIG_LOG);

	if (digits) {
		fp_lshd_low(c, a, digits);
	} else {
		if (c != a) {
			fp_copy(c, a);
		}
	}

	switch (bits) {
		case 0:
			break;
		case 1:
			fp_lsh1_low(c, c);
			break;
		default:
			fp_lshb_low(c, c, bits);
			break;
	}

}
Ejemplo n.º 4
0
void bn_rsh(bn_t c, bn_t a, int bits) {
	int digits = 0;

	if (bits <= 0) {
		bn_copy(c, a);
		return;
	}

	SPLIT(bits, digits, bits, BN_DIG_LOG);

	if (digits > 0) {
		bn_rshd_low(c->dp, a->dp, a->used, digits);
	}
	c->used = a->used - digits;
	c->sign = a->sign;

	if (c->used > 0 && bits > 0) {
		if (digits == 0 && c != a) {
			bn_rshb_low(c->dp, a->dp + digits, a->used - digits, bits);
		} else {
			bn_rshb_low(c->dp, c->dp, c->used, bits);
		}
	}
	bn_trim(c);
}
Ejemplo n.º 5
0
void fb_rdc_basic(fb_t c, dv_t a) {
	int j, k;
	dig_t *tmpa;
	dv_t r;

	dv_null(r);

	TRY {
		dv_new(r);

		tmpa = a + FB_DIGS;

		/* First reduce the high part. */
		for (int i = fb_bits(tmpa) - 1; i >= 0; i--) {
			if (fb_get_bit(tmpa, i)) {
				SPLIT(k, j, i - FB_BITS, FB_DIG_LOG);
				if (k <= 0) {
					fb_addd_low(tmpa + j, tmpa + j, fb_poly_get(), FB_DIGS);
				} else {
					r[FB_DIGS] = fb_lshb_low(r, fb_poly_get(), k);
					fb_addd_low(tmpa + j, tmpa + j, r, FB_DIGS + 1);
				}
			}
		}
		for (int i = fb_bits(a) - 1; i >= FB_BITS; i--) {
			if (fb_get_bit(a, i)) {
				SPLIT(k, j, i - FB_BITS, FB_DIG_LOG);
				if (k == 0) {
					fb_addd_low(a + j, a + j, fb_poly_get(), FB_DIGS);
				} else {
					r[FB_DIGS] = fb_lshb_low(r, fb_poly_get(), k);
					fb_addd_low(a + j, a + j, r, FB_DIGS + 1);
				}
			}
		}

		fb_copy(c, a);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fb_free(r);
	}
}
Ejemplo n.º 6
0
int bn_get_bit(const bn_t a, int bit) {
	int d;

	SPLIT(bit, d, bit, BN_DIG_LOG);

	if (d >= a->used) {
		return 0;
	} else {
		return (a->dp[d] >> bit) & (dig_t)1;
	}
}
Ejemplo n.º 7
0
void bn_set_2b(bn_t a, int b) {
	int i, d;

	SPLIT(b, d, b, BN_DIG_LOG);

	bn_grow(a, d + 1);
	for (i = 0; i < d; i++)
		a->dp[i] = 0;
	a->used = d + 1;
	a->dp[d] = ((dig_t)1 << b);
	a->sign = BN_POS;
}
Ejemplo n.º 8
0
/**
 * Returns a maximum of eight contiguous bits from a multiple precision integer.
 *
 * @param[in] a				- the multiple precision integer.
 * @param[in] from			- the first bit position.
 * @param[in] to			- the last bit position, inclusive.
 * @return the bits in the chosen positions.
 */
static char get_bits(const bn_t a, int from, int to) {
	int f, t;
	dig_t mf, mt;

	SPLIT(from, f, from, BN_DIG_LOG);
	SPLIT(to, t, to, BN_DIG_LOG);

	if (f == t) {
		/* Same digit. */

		mf = MASK(from);
		mt = MASK(to + 1);

		if (to + 1 == BN_DIGIT) {
			mt = DMASK;
		}

		mf = mf ^ mt;

		return ((a->dp[f] & (mf)) >> from);
	} else {
Ejemplo n.º 9
0
void bn_set_bit(bn_t a, int bit, int value) {
	int d;

	SPLIT(bit, d, bit, BN_DIG_LOG);

	if (value == 1) {
		a->dp[d] |= ((dig_t)1 << bit);
		if ((d + 1) > a->used) {
			a->used = d + 1;
		}
	} else {
		a->dp[d] &= ~((dig_t)1 << bit);
		bn_trim(a);
	}
}
Ejemplo n.º 10
0
void bn_rand(bn_t a, int sign, int bits) {
	int digits;

	SPLIT(bits, digits, bits, BN_DIG_LOG);
	digits += (bits > 0 ? 1 : 0);

	bn_grow(a, digits);

	rand_bytes((uint8_t *)a->dp, digits * sizeof(dig_t));

	a->used = digits;
	a->sign = sign;
	if (bits > 0) {
		dig_t mask = ((dig_t)1 << (dig_t)bits) - 1;
		a->dp[a->used - 1] &= mask;
	}
	bn_trim(a);
}
Ejemplo n.º 11
0
void bn_lsh(bn_t c, bn_t a, int bits) {
	int digits;
	dig_t carry;

	bn_copy(c, a);
	if (bits <= 0) {
		return;
	}

	SPLIT(bits, digits, bits, BN_DIG_LOG);

	if (bits > 0) {
		if (bn_bits(c) + bits > c->used * (int)BN_DIGIT) {
			bn_grow(c, c->used + digits + 1);
		}
	} else {
		bn_grow(c, c->used + digits);
	}

	if (digits > 0) {
		bn_lshd_low(c->dp, a->dp, a->used, digits);
	}
	c->used = a->used + digits;
	c->sign = a->sign;

	if (bits > 0) {
		if (c != a) {
			carry = bn_lshb_low(c->dp + digits, a->dp, a->used, bits);
		} else {
			carry = bn_lshb_low(c->dp + digits, c->dp + digits, c->used, bits);
		}
		if (carry != 0) {
			c->dp[c->used] = carry;
			(c->used)++;
		}
	}
	bn_trim(c);
}
Ejemplo n.º 12
0
PRIVATE void print_value
(
    Int i,
    const double Xx [ ],
    const double Xz [ ],    /* used for complex case only */
    Int scalar		    /* if true, then print real part only */
)
{
    Entry xi ;
    /* if Xz is null, then X is in "merged" format (compatible with Entry, */
    /* and ANSI C99 double _Complex type). */
    PRINTF (("    "ID" :", INDEX (i))) ;
    if (scalar)
    {
	PRINT_SCALAR (Xx [i]) ;
    }
    else
    {
	ASSIGN (xi, Xx, Xz, i, SPLIT (Xz)) ;
	PRINT_ENTRY (xi) ;
    }
    PRINTF (("\n")) ;
}
Ejemplo n.º 13
0
GLOBAL Int UMFPACK_get_determinant
(
    double *Mx,
#ifdef COMPLEX
    double *Mz,
#endif
    double *Ex,
    void *NumericHandle,
    double User_Info [UMFPACK_INFO]
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry d_mantissa, d_tmp ;
    double d_exponent, Info2 [UMFPACK_INFO], one [2] = {1.0, 0.0}, d_sign ;
    Entry *D ;
    double *Info, *Rs ;
    NumericType *Numeric ;
    Int i, n, itmp, npiv, *Wi, *Rperm, *Cperm, do_scale ;

#ifndef NRECIPROCAL
    Int do_recip ;
#endif

    /* ---------------------------------------------------------------------- */
    /* check input parameters */
    /* ---------------------------------------------------------------------- */

    if (User_Info != (double *) NULL)
    {
	/* return Info in user's array */
	Info = User_Info ;
    }
    else
    {
	/* no Info array passed - use local one instead */
	Info = Info2 ;
	for (i = 0 ; i < UMFPACK_INFO ; i++)
	{
	    Info [i] = EMPTY ;
	}
    }

    Info [UMFPACK_STATUS] = UMFPACK_OK ;

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_Numeric_object ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    if (Numeric->n_row != Numeric->n_col)
    {
	/* only square systems can be handled */
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_system ;
	return (UMFPACK_ERROR_invalid_system) ;
    }

    if (Mx == (double *) NULL)
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_argument_missing ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    n = Numeric->n_row ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    Wi = (Int *) UMF_malloc (n, sizeof (Int)) ;

    if (!Wi)
    {
	DEBUGm4 (("out of memory: get determinant\n")) ;
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }

    /* ---------------------------------------------------------------------- */
    /* compute the determinant */
    /* ---------------------------------------------------------------------- */

    Rs = Numeric->Rs ;		/* row scale factors */
    do_scale = (Rs != (double *) NULL) ;

#ifndef NRECIPROCAL
    do_recip = Numeric->do_recip ;
#endif

    d_mantissa = ((Entry *) one) [0] ;
    d_exponent = 0.0 ;
    D = Numeric->D ;

    /* compute product of diagonal entries of U */
    for (i = 0 ; i < n ; i++)
    {
	MULT (d_tmp, d_mantissa, D [i]) ;
	d_mantissa = d_tmp ;

	if (!rescale_determinant (&d_mantissa, &d_exponent))
	{
	    /* the determinant is zero or NaN */
	    Info [UMFPACK_STATUS] = UMFPACK_WARNING_singular_matrix ;
	    /* no need to compute the determinant of R */
	    do_scale = FALSE ;
	    break ;
	}
    }

    /* compute product of diagonal entries of R (or its inverse) */
    if (do_scale)
    {
	for (i = 0 ; i < n ; i++)
	{
#ifndef NRECIPROCAL
	    if (do_recip)
	    {
		/* compute determinant of R inverse */
		SCALE_DIV (d_mantissa, Rs [i]) ;
	    }
	    else
#endif
	    {
		/* compute determinant of R */
		SCALE (d_mantissa, Rs [i]) ;
	    }
	    if (!rescale_determinant (&d_mantissa, &d_exponent))
	    {
		/* the determinant is zero or NaN.  This is very unlikey to
		 * occur here, since the scale factors for a tiny or zero row
		 * are set to 1. */
		Info [UMFPACK_STATUS] = UMFPACK_WARNING_singular_matrix ;
		break ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* determine if P and Q are odd or even permutations */
    /* ---------------------------------------------------------------------- */

    npiv = 0 ;
    Rperm = Numeric->Rperm ;

    for (i = 0 ; i < n ; i++)
    {
	Wi [i] = Rperm [i] ;
    }

    for (i = 0 ; i < n ; i++)
    {
	while (Wi [i] != i)
	{
	    itmp = Wi [Wi [i]] ;
	    Wi [Wi [i]] = Wi [i] ;
	    Wi [i] = itmp ;
	    npiv++ ;
	}
    }

    Cperm = Numeric->Cperm ;

    for (i = 0 ; i < n ; i++)
    {
	Wi [i] = Cperm [i] ;
    }

    for (i = 0 ; i < n ; i++)
    {
	while (Wi [i] != i)
	{
	    itmp = Wi [Wi [i]] ;
	    Wi [Wi [i]] = Wi [i] ;
	    Wi [i] = itmp ;
	    npiv++ ;
	}
    }

    /* if npiv is odd, the sign is -1.  if it is even, the sign is +1 */
    d_sign = (npiv % 2) ? -1. : 1. ;

    /* ---------------------------------------------------------------------- */
    /* free workspace */
    /* ---------------------------------------------------------------------- */

    (void) UMF_free ((void *) Wi) ;

    /* ---------------------------------------------------------------------- */
    /* compute the magnitude and exponent of the determinant */
    /* ---------------------------------------------------------------------- */

    if (Ex == (double *) NULL)
    {
	/* Ex is not provided, so return the entire determinant in d_mantissa */
	SCALE (d_mantissa, pow (10.0, d_exponent)) ;
    }
    else
    {
	Ex [0] = d_exponent ;
    }

    Mx [0] = d_sign * REAL_COMPONENT (d_mantissa) ;

#ifdef COMPLEX
    if (SPLIT (Mz))
    {
	Mz [0] = d_sign * IMAG_COMPONENT (d_mantissa) ;
    }
    else
    {
	Mx [1] = d_sign * IMAG_COMPONENT (d_mantissa) ;
    }
#endif

    /* determine if the determinant has (or will) overflow or underflow */
    if (d_exponent + 1.0 > log10 (DBL_MAX))
    {
	Info [UMFPACK_STATUS] = UMFPACK_WARNING_determinant_overflow ;
    }
    else if (d_exponent - 1.0 < log10 (DBL_MIN))
    {
	Info [UMFPACK_STATUS] = UMFPACK_WARNING_determinant_underflow ;
    }

    return (UMFPACK_OK) ;
}
Ejemplo n.º 14
0
void fp_rdcs_low(dig_t *c, dig_t *a, dig_t *m) {
	align dig_t q[2 * FP_DIGS], _q[2 * FP_DIGS];
	align dig_t _r[2 * FP_DIGS], r[2 * FP_DIGS], t[2 * FP_DIGS];
	int *sform, len;
	int first, i, j, b0, d0, b1, d1;
	dig_t carry;

	sform = fp_prime_get_sps(&len);

	SPLIT(b0, d0, FP_BITS, FP_DIG_LOG);
	first = (d0) + (b0 == 0 ? 0 : 1);

	/* q = floor(a/b^k) */
	dv_zero(q, 2 * FP_DIGS);
	bn_rshd_low(q, a, 2 * FP_DIGS, d0);
	if (b0 > 0) {
		bn_rshb_low(q, q, 2 * FP_DIGS, b0);
	}

	/* r = a - qb^k. */
	dv_copy(r, a, first);
	if (b0 > 0) {
		r[first - 1] &= MASK(b0);
	}

	carry = 0;
	while (!fp_is_zero(q)) {
		dv_zero(_q, 2 * FP_DIGS);
		for (i = len - 1; i > 0; i--) {
			j = (sform[i] < 0 ? -sform[i] : sform[i]);
			SPLIT(b1, d1, j, FP_DIG_LOG);
			dv_zero(t, 2 * FP_DIGS);
			bn_lshd_low(t, q, FP_DIGS, d1);
			if (b1 > 0) {
				bn_lshb_low(t, t, 2 * FP_DIGS, b1);
			}
			if (sform[i] > 0) {
				bn_subn_low(_q, _q, t, 2 * FP_DIGS);
			} else {
				bn_addn_low(_q, _q, t, 2 * FP_DIGS);
			}
		}
		if (sform[0] > 0) {
			bn_subn_low(_q, _q, q, 2 * FP_DIGS);
		} else {
			bn_addn_low(_q, _q, q, 2 * FP_DIGS);
		}
		bn_rshd_low(q, _q, 2 * FP_DIGS, d0);
		if (b0 > 0) {
			bn_rshb_low(q, q, 2 * FP_DIGS, b0);
		}

		dv_copy(_r, _q, first);
		if (b0 > 0) {
			_r[first - 1] &= MASK(b0);
		}
		fp_add(r, r, _r);
	}
	while (fp_cmpn_low(r, m) != CMP_LT) {
		fp_subn_low(r, r, m);
	}
	fp_copy(c, r);
}
Ejemplo n.º 15
0
GLOBAL Int UMFPACK_scale
(
    double Xx [ ],
#ifdef COMPLEX
    double Xz [ ],
#endif
    const double Bx [ ],
#ifdef COMPLEX
    const double Bz [ ],
#endif
    void *NumericHandle
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    NumericType *Numeric ;
    Int n, i ;
    double *Rs ;
#ifdef COMPLEX
    Int split = SPLIT (Xz) && SPLIT (Bz) ;
#endif

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    n = Numeric->n_row ;
    Rs = Numeric->Rs ;

    if (!Xx || !Bx)
    {
	return (UMFPACK_ERROR_argument_missing) ;
    }

    /* ---------------------------------------------------------------------- */
    /* X = R*B or R\B */
    /* ---------------------------------------------------------------------- */

    if (Rs != (double *) NULL)
    {
#ifndef NRECIPROCAL
	if (Numeric->do_recip)
	{
	    /* multiply by the scale factors */
#ifdef COMPLEX
	    if (split)
	    {
		for (i = 0 ; i < n ; i++)
		{
		    Xx [i] = Bx [i] * Rs [i] ;
		    Xz [i] = Bz [i] * Rs [i] ;
		}
	    }
	    else
	    {
		for (i = 0 ; i < n ; i++)
		{
		    Xx [2*i  ] = Bx [2*i  ] * Rs [i] ;
		    Xx [2*i+1] = Bx [2*i+1] * Rs [i] ;
		}
	    }
#else
	    for (i = 0 ; i < n ; i++)
	    {
		Xx [i] = Bx [i] * Rs [i] ;
	    }
#endif
	}
	else
#endif
	{
	    /* divide by the scale factors */
#ifdef COMPLEX
	    if (split)
	    {
		for (i = 0 ; i < n ; i++)
		{
		    Xx [i] = Bx [i] / Rs [i] ;
		    Xz [i] = Bz [i] / Rs [i] ;
		}
	    }
	    else
	    {
		for (i = 0 ; i < n ; i++)
		{
		    Xx [2*i  ] = Bx [2*i  ] / Rs [i] ;
		    Xx [2*i+1] = Bx [2*i+1] / Rs [i] ;
		}
	    }
#else
	    for (i = 0 ; i < n ; i++)
	    {
		Xx [i] = Bx [i] / Rs [i] ;
	    }
#endif
	}
    }
    else
    {
	/* no scale factors, just copy B into X */
#ifdef COMPLEX
        if (split)
	{
	    for (i = 0 ; i < n ; i++)
	    {
		Xx [i] = Bx [i] ;
		Xz [i] = Bz [i] ;
	    }
	}
	else
	{
	    for (i = 0 ; i < n ; i++)
	    {
		Xx [2*i  ] = Bx [2*i  ] ;
		Xx [2*i+1] = Bx [2*i+1] ;
	    }
	}
#else
	for (i = 0 ; i < n ; i++)
	{
	    Xx [i] = Bx [i] ;
	}
#endif
    }

    return (UMFPACK_OK) ;
}
Ejemplo n.º 16
0
/*
******** echoListSplit()
**
** returns a echoObjectSplit to point to the same things as pointed
** to by the given echoObjectList
*/
echoObject *
echoListSplit(echoScene *scene, echoObject *list, int axis) {
  echoPos_t lo[3], hi[3], loest0[3], hiest0[3],
    loest1[3], hiest1[3];
  double *mids;
  echoObject *o, *split, *list0, *list1;
  int i, splitIdx, len;

  if (!( echoTypeList == list->type ||
         echoTypeAABBox == list->type )) {
    return list;
  }

  len = LIST(list)->objArr->len;
  if (len <= ECHO_LEN_SMALL_ENOUGH) {
    /* there is nothing or only one object */
    return list;
  }

  split = echoObjectNew(scene, echoTypeSplit);
  list0 = echoObjectNew(scene, echoTypeList);
  list1 = echoObjectNew(scene, echoTypeList);
  SPLIT(split)->axis = axis;
  SPLIT(split)->obj0 = list0;
  SPLIT(split)->obj1 = list1;

  mids = (double *)malloc(2 * len * sizeof(double));
  for (i=0; i<len; i++) {
    o = LIST(list)->obj[i];
    echoBoundsGet(lo, hi, o);
    mids[0 + 2*i] = (lo[axis] + hi[axis])/2;
    *((unsigned int *)(mids + 1 + 2*i)) = i;
  }
  /* overkill, I know, I know */
  qsort(mids, len, 2*sizeof(double),
        (int (*)(const void *, const void *))_echoPosCompare);
  /*
  for (i=0; i<len; i++) {
    printf("%d -> %g\n", i, mids[0 + 2*i]);
  }
  */
  
  splitIdx = len/2;
  /* printf("splitIdx = %d\n", splitIdx); */
  ELL_3V_SET(loest0, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX);
  ELL_3V_SET(loest1, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX);
  ELL_3V_SET(hiest0, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN);
  ELL_3V_SET(hiest1, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN);
  airArrayLenSet(LIST(list0)->objArr, splitIdx);
  for (i=0; i<splitIdx; i++) {
    o = LIST(list)->obj[*((unsigned int *)(mids + 1 + 2*i))];
    LIST(list0)->obj[i] = o;
    echoBoundsGet(lo, hi, o);
    /*
    printf("000 lo = (%g,%g,%g), hi = (%g,%g,%g)\n",
           lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]);
    */
    ELL_3V_MIN(loest0, loest0, lo);
    ELL_3V_MAX(hiest0, hiest0, hi);
  }
  airArrayLenSet(LIST(list1)->objArr, len-splitIdx);
  for (i=splitIdx; i<len; i++) {
    o = LIST(list)->obj[*((unsigned int *)(mids + 1 + 2*i))];
    LIST(list1)->obj[i-splitIdx] = o;
    echoBoundsGet(lo, hi, o);
    /*
    printf("111 lo = (%g,%g,%g), hi = (%g,%g,%g)\n",
           lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]);
    */
    ELL_3V_MIN(loest1, loest1, lo);
    ELL_3V_MAX(hiest1, hiest1, hi);
  }
  /*
  printf("0: loest = (%g,%g,%g); hiest = (%g,%g,%g)\n",
         loest0[0], loest0[1], loest0[2], 
         hiest0[0], hiest0[1], hiest0[2]);
  printf("1: loest = (%g,%g,%g); hiest = (%g,%g,%g)\n",
         loest1[0], loest1[1], loest1[2], 
         hiest1[0], hiest1[1], hiest1[2]);
  */
  ELL_3V_COPY(SPLIT(split)->min0, loest0);
  ELL_3V_COPY(SPLIT(split)->max0, hiest0);
  ELL_3V_COPY(SPLIT(split)->min1, loest1);
  ELL_3V_COPY(SPLIT(split)->max1, hiest1);

  /* we can't delete the list object here, we just gut it so 
     that there's nothing substantial left of it */
  airArrayLenSet(LIST(list)->objArr, 0);
  mids = (double *)airFree(mids);
  return split;
}
Ejemplo n.º 17
0
echoObject *
echoListSplit3(echoScene *scene, echoObject *list, int depth) {
  echoObject *ret, *tmp0, *tmp1;

  if (!( echoTypeList == list->type ||
         echoTypeAABBox == list->type )) 
    return NULL;

  if (!depth)
    return list;

  ret = echoListSplit(scene, list, 0);

#define DOIT(obj, ax) ((obj) = echoListSplit(scene, (obj), (ax)))
#define MORE(obj) echoTypeSplit == (obj)->type

  if (MORE(ret)) {
    tmp0 = DOIT(SPLIT(ret)->obj0, 1);
    if (MORE(tmp0)) {
      tmp1 = DOIT(SPLIT(tmp0)->obj0, 2);
      if (MORE(tmp1)) {
        SPLIT(tmp1)->obj0 = echoListSplit3(scene, SPLIT(tmp1)->obj0, depth-1);
        SPLIT(tmp1)->obj1 = echoListSplit3(scene, SPLIT(tmp1)->obj1, depth-1);
      }
      tmp1 = DOIT(SPLIT(tmp0)->obj1, 2);
      if (MORE(tmp1)) {
        SPLIT(tmp1)->obj0 = echoListSplit3(scene, SPLIT(tmp1)->obj0, depth-1);
        SPLIT(tmp1)->obj1 = echoListSplit3(scene, SPLIT(tmp1)->obj1, depth-1);
      }
    }
    tmp0 = DOIT(SPLIT(ret)->obj1, 1);
    if (MORE(tmp0)) {
      tmp1 = DOIT(SPLIT(tmp0)->obj0, 2);
      if (MORE(tmp1)) {
        SPLIT(tmp1)->obj0 = echoListSplit3(scene, SPLIT(tmp1)->obj0, depth-1);
        SPLIT(tmp1)->obj1 = echoListSplit3(scene, SPLIT(tmp1)->obj1, depth-1);
      }
      tmp1 = DOIT(SPLIT(tmp0)->obj1, 2);
      if (MORE(tmp1)) {
        SPLIT(tmp1)->obj0 = echoListSplit3(scene, SPLIT(tmp1)->obj0, depth-1);
        SPLIT(tmp1)->obj1 = echoListSplit3(scene, SPLIT(tmp1)->obj1, depth-1);
      }
    }
  }
  return ret;
}
Ejemplo n.º 18
0
Archivo: proj.c Proyecto: bitursa/maos
void proj_rect_grid(rmap_t *mapin, double thetax, double thetay,
		    const loc_t *locout,const double ratiox, const double ratioy,
		    const double *ampout, double* phiout, 
		    double sc, double hs, double ht,
		    double betax, double betay){
    /*
      input parameters:
      mapin: M3 surface map, NOT OPD. 
      thetax, thetay: tilt of surface map along x or y. one has to be pi/2
      locout: Pupil plan opd grid.
      ratio: scaling of pupil plan to exit pupil plane.
      sc: scaling of opd. don't include projection
      hs: distance from exit pupil to m3.
      betax,betay: beam angle from exit pupil to focal plane.
     */
    const double (*phiin)[mapin->nx]=(void*)mapin->p;
    const int wrapx1 = mapin->nx;
    const int wrapy1 = mapin->ny;
    const int wrapx = wrapx1-1;
    const int wrapy = wrapy1-1;
    double offx=hs*betax;
    double offy=hs*betay;
    if(ratiox<0) offx=-offx;
    if(ratioy<0) offy=-offy;
    const double dx_in1 = 1./mapin->dx;
    const double dy_in1 = 1./mapin->dy;
    double a0x=(-offx/sin(thetax)-mapin->ox)*dx_in1;
    double a0y=(-offy/sin(thetay)-mapin->oy)*dy_in1;
    double ddx=(hs-ht)*dx_in1;
    double ddy=(hs-ht)*dy_in1;
  
    int nplocx,nplocy,nplocx1,nplocy1;
    if(fabs(thetax-M_PI*0.5)>M_PI*.45 || fabs(thetay-M_PI*0.5)>M_PI*0.45){
	info2("Tilting angle is too much\n");
	return;
    }
    
    double vm3[3];
    vm3[0]=-sin(M_PI/2-thetax);
    vm3[1]=-sin(M_PI/2-thetay);
    vm3[2]=-sqrt(1.-vm3[0]*vm3[0]-vm3[1]*vm3[1]);
    double vi[3];
    vi[2]=-hs;
    double sc2;
    for(int iloc=0; iloc<locout->nloc; iloc++){
	if(ampout && fabs(ampout[iloc])<1.e-10)
	    continue;/*skip points that has zero amplitude */
	double alx=atan2(locout->locx[iloc]*ratiox+offx,hs);
	double aly=atan2(locout->locy[iloc]*ratioy+offy,hs);
	double btx=thetax-alx;
	double bty=thetay-aly;
	double dplocx=ddx*sin(alx)/sin(btx)+a0x;
	double dplocy=ddy*sin(aly)/sin(bty)+a0y;
	vi[0]=locout->locx[iloc]*ratiox+offx;
	vi[1]=locout->locy[iloc]*ratioy+offy;
	SPLIT(dplocx,dplocx,nplocx);
	SPLIT(dplocy,dplocy,nplocy);
	if(nplocx<0||nplocx>=wrapx||nplocy<0||nplocy>=wrapy){
	    continue;
	}else{
	    nplocx1=nplocx+1;
	    nplocy1=nplocy+1;
	}
	sc2=sc*cosangle(vi,vm3);
	/*sc2=sc*0.707; */
	phiout[iloc]+=sc2*(phiin[nplocy][nplocx]*(1.-dplocx)*(1.-dplocy)
			  +phiin[nplocy][nplocx1]*(dplocx)*(1.-dplocy)
			  +phiin[nplocy1][nplocx]*(1.-dplocx)*(dplocy)
			  +phiin[nplocy1][nplocx1]*(dplocx)*(dplocy));
    }
}
Ejemplo n.º 19
0
GLOBAL Int UMFPACK_get_numeric
(
    Int Lp [ ],
    Int Lj [ ],
    double Lx [ ],
#ifdef COMPLEX
    double Lz [ ],
#endif
    Int Up [ ],
    Int Ui [ ],
    double Ux [ ],
#ifdef COMPLEX
    double Uz [ ],
#endif
    Int P [ ],
    Int Q [ ],
    double Dx [ ],
#ifdef COMPLEX
    double Dz [ ],
#endif
    Int *p_do_recip,
    double Rs [ ],
    void *NumericHandle
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    NumericType *Numeric ;
    Int getL, getU, *Rperm, *Cperm, k, nn, n_row, n_col, *Wi, *Pattern,
	n_inner ;
    double *Rs1 ;
    Entry *D ;

#ifndef NDEBUG
    init_count = UMF_malloc_count ;
#endif

    Wi = (Int *) NULL ;
    Pattern = (Int *) NULL ;

    /* ---------------------------------------------------------------------- */
    /* check input parameters */
    /* ---------------------------------------------------------------------- */

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    n_row = Numeric->n_row ;
    n_col = Numeric->n_col ;
    nn = MAX (n_row, n_col) ;
    n_inner = MIN (n_row, n_col) ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    getL = Lp && Lj && Lx ;
    getU = Up && Ui && Ux ;

    if (getL || getU)
    {
	Wi = (Int *) UMF_malloc (nn, sizeof (Int)) ;
	Pattern = (Int *) UMF_malloc (nn, sizeof (Int)) ;
	if (!Wi || !Pattern)
	{
	    (void) UMF_free ((void *) Wi) ;
	    (void) UMF_free ((void *) Pattern) ;
	    ASSERT (UMF_malloc_count == init_count) ;
	    DEBUGm4 (("out of memory: get numeric\n")) ;
	    return (UMFPACK_ERROR_out_of_memory) ;
	}
	ASSERT (UMF_malloc_count == init_count + 2) ;
    }

    /* ---------------------------------------------------------------------- */
    /* get contents of Numeric */
    /* ---------------------------------------------------------------------- */

    if (P != (Int *) NULL)
    {
	Rperm = Numeric->Rperm ;
	for (k = 0 ; k < n_row ; k++)
	{
	    P [k] = Rperm [k] ;
	}
    }

    if (Q != (Int *) NULL)
    {
	Cperm = Numeric->Cperm ;
	for (k = 0 ; k < n_col ; k++)
	{
	    Q [k] = Cperm [k] ;
	}
    }

    if (getL)
    {
	get_L (Lp, Lj, Lx,
#ifdef COMPLEX
	    Lz,
#endif
	    Numeric, Pattern, Wi) ;
    }

    if (getU)
    {
	get_U (Up, Ui, Ux,
#ifdef COMPLEX
	    Uz,
#endif
	    Numeric, Pattern, Wi) ;
    }

    if (Dx != (double *) NULL)
    {
	D = Numeric->D ;
#ifdef COMPLEX
	if (SPLIT (Dz))
	{
	    for (k = 0 ; k < n_inner ; k++)
	    {
		Dx [k] = REAL_COMPONENT (D [k]) ;
		Dz [k] = IMAG_COMPONENT (D [k]) ;
	    }
	}
	else
	{
	    for (k = 0 ; k < n_inner ; k++)
	    {
	        Dx [2*k  ] =  REAL_COMPONENT (D [k]) ;
	        Dx [2*k+1] =  IMAG_COMPONENT (D [k]) ;
	    }
	}
#else
	{
	    D = Numeric->D ;
	    for (k = 0 ; k < n_inner ; k++)
	    {
		Dx [k] = D [k] ;
	    }
	}
#endif
    }

    /* return the flag stating whether the scale factors are to be multiplied,
     * or divided.   If do_recip is TRUE, multiply.  Otherwise, divided.
     * If NRECIPROCAL is defined at compile time, the scale factors are always
     * to be used by dividing.
     */
    if (p_do_recip != (Int *) NULL)
    {
#ifndef NRECIPROCAL
	*p_do_recip = Numeric->do_recip ;
#else
	*p_do_recip = FALSE ;
#endif
    }

    if (Rs != (double *) NULL)
    {
	Rs1 = Numeric->Rs ;
	if (Rs1 == (double *) NULL)
	{
	    /* R is the identity matrix.  */
	    for (k = 0 ; k < n_row ; k++)
	    {
		Rs [k] = 1.0 ;
	    }
	}
	else
	{
	    for (k = 0 ; k < n_row ; k++)
	    {
		Rs [k] = Rs1 [k] ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* free the workspace */
    /* ---------------------------------------------------------------------- */

    (void) UMF_free ((void *) Wi) ;
    (void) UMF_free ((void *) Pattern) ;
    ASSERT (UMF_malloc_count == init_count) ;

    return (UMFPACK_OK) ;
}
Ejemplo n.º 20
0
void Reassign_Weight() {
  int i,j;
  int is,id;
  double sumprob,maxprob,minprob;

  for (i=1;i<(nbin+1);i++) {
    if (tmpnpar[i]!=0) {
      sumprob=0;
      for (j=1;j<(tmpnpar[i]+1);j++) {
        sumprob+=tmppar[i][j].prob;
      }
      if (sumprob!=0) {
        maxprob=sumprob/npar[i]*sqrt(mmratio);
        minprob=sumprob/npar[i]/sqrt(mmratio);
        Min1(i);
        while (tmppar[i][tmpnpar[i]].prob<minprob) {
          Min2(i);
          COMB(i);
          Min1(i);
        }
        Max(i);
        while (tmppar[i][1].prob>maxprob) {
          SPLIT(i);
          Max(i);
        }
        while (tmpnpar[i]>npar[i]) {
          Min1(i);
          Min2(i);
          COMB(i);
        }
        while (tmpnpar[i]<npar[i]) {
          Max(i);
          SPLIT(i);
        }
        for (j=1;j<(npar[i]+1);j++) {
          par[i][j].prob=tmppar[i][j].prob;
          par[i][j].coord=tmppar[i][j].coord;
          par[i][j].numb=tmppar[i][j].numb;
          par[i][j].tb0=tmppar[i][j].tb0;
          par[i][j].distA=tmppar[i][j].distA;
          par[i][j].distB=tmppar[i][j].distB;
        }
      }
    }
    else {
      for (j=1;j<(npar[i]+1);j++) {
        if (Fava[0]!=0) {
          par[i][j].numb=Fava[Fava[0]];
          Fava[0]-=1;
        }
        else {
          Fexc[0].i+=1;
          Fexc[0].j+=1;
          Fexc[Fexc[0].i].i=i;
          Fexc[Fexc[0].i].j=j;
          par[i][j].numb=Fexc[0].i+nallpar;
        }
       }
      Make_Ghost(i);
    }
  }

  while(Fexc[0].i!=0) {
    if (Fexc[0].i!=Fava[0]) {
      printf("Fava=%d\tFexc=%d!\n",Fava[0],Fexc[0].i);
      for (j=1;j<(Fava[0]+1);j++) {
        printf("Fava[%d]=%d\n",j,Fava[j]);
      }
      printf("Something is wrong!\n");
      exit(1);
    }
    is=Fexc[0].i;
    id=Fava[is];
    par[Fexc[is].i][Fexc[is].j].numb=id;
    is+=nallpar;
    free(rx_states[id-1]);
    rx_states[id-1]=(int *)malloc(nspecies*sizeof(int));
    memcpy(rx_states[id-1],rx_states[is-1],nspecies*sizeof(int));
    free(rx_states[is-1]);
    rx_states[is-1]=(int *)malloc(nspecies*sizeof(int));

    Fexc[0].i-=1;
    Fexc[0].j-=1;
    Fava[0]-=1;
  }
  return;
}
Ejemplo n.º 21
0
GLOBAL Int UMF_transpose
(
    Int n_row,			/* A is n_row-by-n_col */
    Int n_col,
    const Int Ap [ ],		/* size n_col+1 */
    const Int Ai [ ],		/* size nz = Ap [n_col] */
    const double Ax [ ],	/* size nz if present */

    const Int P [ ],	/* P [k] = i means original row i is kth row in A(P,Q)*/
			/* P is identity if not present */
			/* size n_row, if present */

    const Int Q [ ],	/* Q [k] = j means original col j is kth col in A(P,Q)*/
			/* Q is identity if not present */
			/* size nq, if present */
    Int nq,		/* size of Q, ignored if Q is (Int *) NULL */

			/* output matrix: Rp, Ri, Rx, and Rz: */
    Int Rp [ ],		/* size n_row+1 */
    Int Ri [ ],		/* size nz */
    double Rx [ ],	/* size nz, if present */

    Int W [ ],		/* size max (n_row,n_col) workspace */

    Int check		/* if true, then check inputs */
#ifdef COMPLEX
    , const double Az [ ]	/* size nz */
    , double Rz [ ]		/* size nz */
    , Int do_conjugate		/* if true, then do conjugate transpose */
				/* otherwise, do array transpose */
#endif
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int i, j, k, p, bp, newj, do_values ;
#ifdef COMPLEX
    Int split ;
#endif

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    Int nz ;
    ASSERT (n_col >= 0) ;
    nz = (Ap != (Int *) NULL) ? Ap [n_col] : 0 ;
    DEBUG2 (("UMF_transpose: "ID"-by-"ID" nz "ID"\n", n_row, n_col, nz)) ;
#endif

    if (check)
    {
	/* UMFPACK_symbolic skips this check */
	/* UMFPACK_transpose always does this check */
	if (!Ai || !Ap || !Ri || !Rp || !W)
	{
	    return (UMFPACK_ERROR_argument_missing) ;
	}
	if (n_row <= 0 || n_col <= 0)		/* n_row,n_col must be > 0 */
	{
	    return (UMFPACK_ERROR_n_nonpositive) ;
	}
	if (!UMF_is_permutation (P, W, n_row, n_row) ||
	    !UMF_is_permutation (Q, W, nq, nq))
	{
	    return (UMFPACK_ERROR_invalid_permutation) ;
	}
	if (!AMD_valid (n_row, n_col, Ap, Ai))
	{
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

#ifndef NDEBUG
    DEBUG2 (("UMF_transpose, input matrix:\n")) ;
    UMF_dump_col_matrix (Ax,
#ifdef COMPLEX
	Az,
#endif
	Ai, Ap, n_row, n_col, nz) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* count the entries in each row of A */
    /* ---------------------------------------------------------------------- */

    /* use W as workspace for RowCount */

    for (i = 0 ; i < n_row ; i++)
    {
	W [i] = 0 ;
	Rp [i] = 0 ;
    }

    if (Q != (Int *) NULL)
    {
	for (newj = 0 ; newj < nq ; newj++)
	{
	    j = Q [newj] ;
	    ASSERT (j >= 0 && j < n_col) ;
	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
	    {
		i = Ai [p] ;
		ASSERT (i >= 0 && i < n_row) ;
		W [i]++ ;
	    }
	}
    }
    else
    {
	for (j = 0 ; j < n_col ; j++)
	{
	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
	    {
		i = Ai [p] ;
		ASSERT (i >= 0 && i < n_row) ;
		W [i]++ ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* compute the row pointers for R = A (P,Q) */
    /* ---------------------------------------------------------------------- */

    if (P != (Int *) NULL)
    {
	Rp [0] = 0 ;
	for (k = 0 ; k < n_row ; k++)
	{
	    i = P [k] ;
	    ASSERT (i >= 0 && i < n_row) ;
	    Rp [k+1] = Rp [k] + W [i] ;
	}
	for (k = 0 ; k < n_row ; k++)
	{
	    i = P [k] ;
	    ASSERT (i >= 0 && i < n_row) ;
	    W [i] = Rp [k] ;
	}
    }
    else
    {
	Rp [0] = 0 ;
	for (i = 0 ; i < n_row ; i++)
	{
	    Rp [i+1] = Rp [i] + W [i] ;
	}
	for (i = 0 ; i < n_row ; i++)
	{
	    W [i] = Rp [i] ;
	}
    }
    ASSERT (Rp [n_row] <= Ap [n_col]) ;

    /* at this point, W holds the permuted row pointers */

    /* ---------------------------------------------------------------------- */
    /* construct the row form of B */
    /* ---------------------------------------------------------------------- */

    do_values = Ax && Rx ;

#ifdef COMPLEX
    split = SPLIT (Az) && SPLIT (Rz) ;

    if (do_conjugate && do_values)
    {
	if (Q != (Int *) NULL)
	{
	    if (split)
	    {
		/* R = A (P,Q)' */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = newj ;
			Rx [bp] = Ax [p] ;
			Rz [bp] = -Az [p] ;
		    }
		}
	    }
	    else
	    {
		/* R = A (P,Q)' (merged complex values) */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = newj ;
			Rx [2*bp] = Ax [2*p] ;
			Rx [2*bp+1] = -Ax [2*p+1] ;
		    }
		}
	    }
	}
	else
	{
	    if (split)
	    {
		/* R = A (P,:)' */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = j ;
			Rx [bp] = Ax [p] ;
			Rz [bp] = -Az [p] ;
		    }
		}
	    }
	    else
	    {
		/* R = A (P,:)' (merged complex values) */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = j ;
			Rx [2*bp] = Ax [2*p] ;
			Rx [2*bp+1] = -Ax [2*p+1] ;
		    }
		}
	    }
	}
    }
    else
#endif
    {
	if (Q != (Int *) NULL)
	{
	    if (do_values)
	    {
#ifdef COMPLEX
		if (split)
#endif
		{
		    /* R = A (P,Q).' */
		    for (newj = 0 ; newj < nq ; newj++)
		    {
			j = Q [newj] ;
			ASSERT (j >= 0 && j < n_col) ;
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = newj ;
			    Rx [bp] = Ax [p] ;
#ifdef COMPLEX
			    Rz [bp] = Az [p] ;
#endif
			}
		    }
		}
#ifdef COMPLEX
		else
		{
		    /* R = A (P,Q).' (merged complex values) */
		    for (newj = 0 ; newj < nq ; newj++)
		    {
			j = Q [newj] ;
			ASSERT (j >= 0 && j < n_col) ;
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = newj ;
			    Rx [2*bp] = Ax [2*p] ;
			    Rx [2*bp+1] = Ax [2*p+1] ;
			}
		    }
		}
#endif
	    }
	    else
	    {
		/* R = pattern of A (P,Q).' */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			Ri [W [Ai [p]]++] = newj ;
		    }
		}
	    }
	}
	else
	{
	    if (do_values)
	    {
#ifdef COMPLEX
		if (split)
#endif
		{
		    /* R = A (P,:).' */
		    for (j = 0 ; j < n_col ; j++)
		    {
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = j ;
			    Rx [bp] = Ax [p] ;
#ifdef COMPLEX
			    Rz [bp] = Az [p] ;
#endif
			}
		    }
		}
#ifdef COMPLEX
		else
		{
		    /* R = A (P,:).' (merged complex values) */
		    for (j = 0 ; j < n_col ; j++)
		    {
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = j ;
			    Rx [2*bp] = Ax [2*p] ;
			    Rx [2*bp+1] = Ax [2*p+1] ;
			}
		    }
		}
#endif
	    }
	    else
	    {
		/* R = pattern of A (P,:).' */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			Ri [W [Ai [p]]++] = j ;
		    }
		}
	    }
	}
    }

#ifndef NDEBUG
    for (k = 0 ; k < n_row ; k++)
    {
	if (P != (Int *) NULL)
	{
	    i = P [k] ;
	}
	else
	{
	    i = k ;
	}
	DEBUG3 ((ID":  W[i] "ID" Rp[k+1] "ID"\n", i, W [i], Rp [k+1])) ;
	ASSERT (W [i] == Rp [k+1]) ;
    }
    DEBUG2 (("UMF_transpose, output matrix:\n")) ;
    UMF_dump_col_matrix (Rx,
#ifdef COMPLEX
	Rz,
#endif
	Ri, Rp, n_col, n_row, Rp [n_row]) ;
    ASSERT (AMD_valid (n_col, n_row, Rp, Ri)) ;
#endif

    return (UMFPACK_OK) ;
}
Ejemplo n.º 22
0
void fb_rdc1_low(dig_t *c, dig_t *a) {
	int fa, fb, fc;
	int sh, lh, rh, sa, la, ra, sb, lb, rb, sc, lc, rc;
	dig_t d;

	fb_poly_get_rdc(&fa, &fb, &fc);

	sh = lh = rh = sa = la = ra = sb = lb = rb = sc = lc = rc = 0;

	SPLIT(rh, sh, FB_BITS, FB_DIG_LOG);
	sh++;
	lh = FB_DIGIT - rh;

	SPLIT(ra, sa, FB_BITS - fa, FB_DIG_LOG);
	sa++;
	la = FB_DIGIT - ra;

	if (fb != -1) {
		SPLIT(rb, sb, FB_BITS - fb, FB_DIG_LOG);
		sb++;
		lb = FB_DIGIT - rb;

		SPLIT(rc, sc, FB_BITS - fc, FB_DIG_LOG);
		sc++;
		lc = FB_DIGIT - rc;
	}

	d = a[FB_DIGS];
	a[FB_DIGS] = 0;

	if (rh == 0) {
		a[FB_DIGS - sh + 1] ^= d;
	} else {
		a[FB_DIGS - sh + 1] ^= (d >> rh);
		a[FB_DIGS - sh] ^= (d << lh);
	}
	if (ra == 0) {
		a[FB_DIGS - sa + 1] ^= d;
	} else {
		a[FB_DIGS - sa + 1] ^= (d >> ra);
		a[FB_DIGS - sa] ^= (d << la);
	}

	if (fb != -1) {
		if (rb == 0) {
			a[FB_DIGS - sb + 1] ^= d;
		} else {
			a[FB_DIGS - sb + 1] ^= (d >> rb);
			a[FB_DIGS - sb] ^= (d << lb);
		}
		if (rc == 0) {
			a[FB_DIGS - sc + 1] ^= d;
		} else {
			a[FB_DIGS - sc + 1] ^= (d >> rc);
			a[FB_DIGS - sc] ^= (d << lc);
		}
	}

	d = a[sh - 1] >> rh;

	if (d != 0) {
		a[0] ^= d;
		d <<= rh;

		if (ra == 0) {
			a[sh - sa] ^= d;
		} else {
			a[sh - sa] ^= (d >> ra);
			if (sh > sa) {
				a[sh - sa - 1] ^= (d << la);
			}
		}
		if (fb != -1) {
			if (rb == 0) {
				a[sh - sb] ^= d;
			} else {
				a[sh - sb] ^= (d >> rb);
				if (sh > sb) {
					a[sh - sb - 1] ^= (d << lb);
				}
			}
			if (rc == 0) {
				a[sh - sc] ^= d;
			} else {
				a[sh - sc] ^= (d >> rc);
				if (sh > sc) {
					a[sh - sc - 1] ^= (d << lc);
				}
			}
		}
		a[sh - 1] ^= d;
	}
Ejemplo n.º 23
0
PRIVATE void get_L
(
    Int Lp [ ],		/* of size n_row+1 */
    Int Lj [ ],		/* of size lnz, where lnz = Lp [n_row] */
    double Lx [ ],	/* of size lnz */
#ifdef COMPLEX
    double Lz [ ],	/* of size lnz */
#endif
    NumericType *Numeric,
    Int Pattern [ ],	/* workspace of size n_row */
    Int Wi [ ]		/* workspace of size n_row */
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry value ;
    Entry *xp, *Lval ;
    Int deg, *ip, j, row, n_row, n_col, n_inner, *Lpos, *Lilen, *Lip, p, llen,
        lnz2, lp, newLchain, k, pos, npiv, *Li, n1 ;
#ifdef COMPLEX
    Int split = SPLIT (Lz) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    DEBUG4 (("get_L start:\n")) ;
    n_row = Numeric->n_row ;
    n_col = Numeric->n_col ;
    n_inner = MIN (n_row, n_col) ;
    npiv = Numeric->npiv ;
    n1 = Numeric->n1 ;
    Lpos = Numeric->Lpos ;
    Lilen = Numeric->Lilen ;
    Lip = Numeric->Lip ;
    deg = 0 ;

    /* ---------------------------------------------------------------------- */
    /* count the nonzeros in each row of L */
    /* ---------------------------------------------------------------------- */

#pragma ivdep
    for (row = 0 ; row < n_inner ; row++)
    {
	/* include the diagonal entry in the row counts */
	Wi [row] = 1 ;
    }
#pragma ivdep
    for (row = n_inner ; row < n_row ; row++)
    {
	Wi [row] = 0 ;
    }

    /* singletons */
    for (k = 0 ; k < n1 ; k++)
    {
	DEBUG4 (("Singleton k "ID"\n", k)) ;
	deg = Lilen [k] ;
	if (deg > 0)
	{
	    lp = Lip [k] ;
	    Li = (Int *) (Numeric->Memory + lp) ;
	    lp += UNITS (Int, deg) ;
	    Lval = (Entry *) (Numeric->Memory + lp) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		row = Li [j] ;
		value = Lval [j] ;
		DEBUG4 (("  row "ID"  k "ID" value", row, k)) ;
		EDEBUG4 (value) ;
		DEBUG4 (("\n")) ;
		if (IS_NONZERO (value))
		{
		    Wi [row]++ ;
		}
	    }
	}
    }

    /* non-singletons */
    for (k = n1 ; k < npiv ; k++)
    {

	/* ------------------------------------------------------------------ */
	/* make column of L in Pattern [0..deg-1] */
	/* ------------------------------------------------------------------ */

	lp = Lip [k] ;
	newLchain = (lp < 0) ;
	if (newLchain)
	{
	    lp = -lp ;
	    deg = 0 ;
	    DEBUG4 (("start of chain for column of L\n")) ;
	}

	/* remove pivot row */
	pos = Lpos [k] ;
	if (pos != EMPTY)
	{
	    DEBUG4 (("  k "ID" removing row "ID" at position "ID"\n",
	    k, Pattern [pos], pos)) ;
	    ASSERT (!newLchain) ;
	    ASSERT (deg > 0) ;
	    ASSERT (pos >= 0 && pos < deg) ;
	    ASSERT (Pattern [pos] == k) ;
	    Pattern [pos] = Pattern [--deg] ;
	}

	/* concatenate the pattern */
	ip = (Int *) (Numeric->Memory + lp) ;
	llen = Lilen [k] ;
	for (j = 0 ; j < llen ; j++)
	{
	    row = *ip++ ;
	    DEBUG4 (("  row "ID"  k "ID"\n", row, k)) ;
	    ASSERT (row > k && row < n_row) ;
	    Pattern [deg++] = row ;
	}

	xp = (Entry *) (Numeric->Memory + lp + UNITS (Int, llen)) ;

	for (j = 0 ; j < deg ; j++)
	{
	    DEBUG4 (("  row "ID"  k "ID" value", Pattern [j], k)) ;
	    row = Pattern [j] ;
	    value = *xp++ ;
	    EDEBUG4 (value) ;
	    DEBUG4 (("\n")) ;
	    if (IS_NONZERO (value))
	    {
		Wi [row]++ ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* construct the final row form of L */
    /* ---------------------------------------------------------------------- */

    /* create the row pointers */
    lnz2 = 0 ;
    for (row = 0 ; row < n_row ; row++)
    {
	Lp [row] = lnz2 ;
	lnz2 += Wi [row] ;
	Wi [row] = Lp [row] ;
    }
    Lp [n_row] = lnz2 ;
    ASSERT (Numeric->lnz + n_inner == lnz2) ;

    /* add entries from the rows of L (singletons) */
    for (k = 0 ; k < n1 ; k++)
    {
	DEBUG4 (("Singleton k "ID"\n", k)) ;
	deg = Lilen [k] ;
	if (deg > 0)
	{
	    lp = Lip [k] ;
	    Li = (Int *) (Numeric->Memory + lp) ;
	    lp += UNITS (Int, deg) ;
	    Lval = (Entry *) (Numeric->Memory + lp) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		row = Li [j] ;
		value = Lval [j] ;
		DEBUG4 (("  row "ID"  k "ID" value", row, k)) ;
		EDEBUG4 (value) ;
		DEBUG4 (("\n")) ;
		if (IS_NONZERO (value))
		{
		    p = Wi [row]++ ;
		    Lj [p] = k ;
#ifdef COMPLEX
		    if (split)
		    {

		        Lx [p] = REAL_COMPONENT (value) ;
			Lz [p] = IMAG_COMPONENT (value) ;
		    }
		    else
		    {
			Lx [2*p  ] = REAL_COMPONENT (value) ;
			Lx [2*p+1] = IMAG_COMPONENT (value) ;
		    }
#else
		    Lx [p] = value ;
#endif
		}
	    }
	}
    }

    /* add entries from the rows of L (non-singletons) */
    for (k = n1 ; k < npiv ; k++)
    {

	/* ------------------------------------------------------------------ */
	/* make column of L in Pattern [0..deg-1] */
	/* ------------------------------------------------------------------ */

	lp = Lip [k] ;
	newLchain = (lp < 0) ;
	if (newLchain)
	{
	    lp = -lp ;
	    deg = 0 ;
	    DEBUG4 (("start of chain for column of L\n")) ;
	}

	/* remove pivot row */
	pos = Lpos [k] ;
	if (pos != EMPTY)
	{
	    DEBUG4 (("  k "ID" removing row "ID" at position "ID"\n",
	    k, Pattern [pos], pos)) ;
	    ASSERT (!newLchain) ;
	    ASSERT (deg > 0) ;
	    ASSERT (pos >= 0 && pos < deg) ;
	    ASSERT (Pattern [pos] == k) ;
	    Pattern [pos] = Pattern [--deg] ;
	}

	/* concatenate the pattern */
	ip = (Int *) (Numeric->Memory + lp) ;
	llen = Lilen [k] ;
	for (j = 0 ; j < llen ; j++)
	{
	    row = *ip++ ;
	    DEBUG4 (("  row "ID"  k "ID"\n", row, k)) ;
	    ASSERT (row > k) ;
	    Pattern [deg++] = row ;
	}

	xp = (Entry *) (Numeric->Memory + lp + UNITS (Int, llen)) ;

	for (j = 0 ; j < deg ; j++)
	{
	    DEBUG4 (("  row "ID"  k "ID" value", Pattern [j], k)) ;
	    row = Pattern [j] ;
	    value = *xp++ ;
	    EDEBUG4 (value) ;
	    DEBUG4 (("\n")) ;
	    if (IS_NONZERO (value))
	    {
		p = Wi [row]++ ;
		Lj [p] = k ;
#ifdef COMPLEX
		if (split)
		{
		    Lx [p] = REAL_COMPONENT (value) ;
		    Lz [p] = IMAG_COMPONENT (value) ;
		}
		else
		{
		    Lx [2*p  ] = REAL_COMPONENT (value) ;
		    Lx [2*p+1] = IMAG_COMPONENT (value) ;
		}
#else
		Lx [p] = value ;
#endif
	    }
	}
    }

    /* add all of the diagonal entries (L is unit diagonal) */
    for (row = 0 ; row < n_inner ; row++)
    {
	p = Wi [row]++ ;
	Lj [p] = row ;

#ifdef COMPLEX
	if (split)
	{
	    Lx [p] = 1. ;
	    Lz [p] = 0. ;
	}
	else
	{
	    Lx [2*p  ] = 1. ;
	    Lx [2*p+1] = 0. ;
	}
#else
	Lx [p] = 1. ;
#endif

	ASSERT (Wi [row] == Lp [row+1]) ;
    }

#ifndef NDEBUG
    DEBUG6 (("L matrix (stored by rows):")) ;
    UMF_dump_col_matrix (Lx,
#ifdef COMPLEX
	Lz,
#endif
	Lj, Lp, n_inner, n_row, Numeric->lnz+n_inner) ;
#endif

    DEBUG4 (("get_L done:\n")) ;
}
Ejemplo n.º 24
0
std::vector<std::string> SPLIT(const std::string &s, char delim) {
	std::vector<std::string> elems;
	SPLIT(s, delim, elems);
	return elems;
}
Ejemplo n.º 25
0
GLOBAL void UMF_2by2
(
    /* input, not modified: */
    Int n,		    /* A is n-by-n */
    const Int Ap [ ],	    /* size n+1 */
    const Int Ai [ ],	    /* size nz = Ap [n] */
    const double Ax [ ],    /* size nz if present */
#ifdef COMPLEX
    const double Az [ ],    /* size nz if present */
#endif
    double tol,		/* tolerance for determining whether or not an
			 * entry is numerically acceptable.  If tol <= 0
			 * then all numerical values ignored. */
    Int scale,		/* scaling to perform (none, sum, or max) */
    Int Cperm1 [ ],	/* singleton permutations */
#ifndef NDEBUG
    Int Rperm1 [ ],	/* not needed, since Rperm1 = Cperm1 for submatrix S */
#endif
    Int InvRperm1 [ ],	/* inverse of Rperm1 */
    Int n1,		/* number of singletons */
    Int nempty,		/* number of empty rows/cols */

    /* input, contents undefined on output: */
    Int Degree [ ],	/* Degree [j] is the number of off-diagonal
			 * entries in row/column j of S+S', where
			 * where S = A (Cperm1 [n1..], Rperm1 [n1..]).
			 * Note that S is not used, nor formed. */

    /* output: */
    Int P [ ],		/* P [k] = i means original row i is kth row in S(P,:)
			 * where S = A (Cperm1 [n1..], Rperm1 [n1..]) */
    Int *p_nweak,
    Int *p_unmatched,

    /* workspace (not defined on input or output): */
    Int Ri [ ],		/* of size >= max (nz, n) */
    Int Rp [ ],		/* of size n+1 */
    double Rs [ ],	/* of size n if present.  Rs = sum (abs (A),2) or
			 * max (abs (A),2), the sum or max of each row.  Unused
			 * if scale is equal to UMFPACK_SCALE_NONE. */
    Int Head [ ],	/* of size n.  Head pointers for bucket sort */
    Int Next [ ],	/* of size n.  Next pointers for bucket sort */
    Int Ci [ ],		/* size nz */
    Int Cp [ ]		/* size n+1 */
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry aij ;
    double cmax, value, rs, ctol, dvalue ;
    Int k, p, row, col, do_values, do_sum, do_max, do_scale, nweak, weak,
	p1, p2, dfound, unmatched, n2, oldrow, newrow, oldcol, newcol, pp ;
#ifdef COMPLEX
    Int split = SPLIT (Az) ;
#endif
#ifndef NRECIPROCAL
    Int do_recip = FALSE ;
#endif

#ifndef NDEBUG
    /* UMF_debug += 99 ; */
    DEBUGm3 (("\n ==================================UMF_2by2: tol %g\n", tol)) ;
    ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ;
    for (k = n1 ; k < n - nempty ; k++)
    {
	ASSERT (Cperm1 [k] == Rperm1 [k]) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* determine scaling options */
    /* ---------------------------------------------------------------------- */

    /* use the values, but only if they are present */
    /* ignore the values if tol <= 0 */
    do_values = (tol > 0) && (Ax != (double *) NULL) ;
    if (do_values && (Rs != (double *) NULL))
    {
	do_sum = (scale == UMFPACK_SCALE_SUM) ;
	do_max = (scale == UMFPACK_SCALE_MAX) ;
    }
    else
    {
	/* no scaling */
	do_sum = FALSE ;
	do_max = FALSE ;
    }
    do_scale = do_max || do_sum ;
    DEBUGm3 (("do_values "ID" do_sum "ID" do_max "ID" do_scale "ID"\n",
	do_values, do_sum, do_max, do_scale)) ;

    /* ---------------------------------------------------------------------- */
    /* compute the row scaling, if requested */
    /* ---------------------------------------------------------------------- */

    /* see also umf_kernel_init */

    if (do_scale)
    {
#ifndef NRECIPROCAL
	double rsmin ;
#endif
	for (row = 0 ; row < n ; row++)
	{
	    Rs [row] = 0.0 ;
	}
	for (col = 0 ; col < n ; col++)
	{
	    p2 = Ap [col+1] ;
	    for (p = Ap [col] ; p < p2 ; p++)
	    {
		row = Ai [p] ;
		ASSIGN (aij, Ax, Az, p, split) ;
		APPROX_ABS (value, aij) ;
		rs = Rs [row] ;
		if (!SCALAR_IS_NAN (rs))
		{
		    if (SCALAR_IS_NAN (value))
		    {
			/* if any entry in a row is NaN, then the scale factor
			 * for the row is NaN.  It will be set to 1 later. */
			Rs [row] = value ;
		    }
		    else if (do_max)
		    {
			Rs [row] = MAX (rs, value) ;
		    }
		    else
		    {
			Rs [row] += value ;
		    }
		}
	    }
	}
#ifndef NRECIPROCAL
	rsmin = Rs [0] ;
	if (SCALAR_IS_ZERO (rsmin) || SCALAR_IS_NAN (rsmin))
	{
	    rsmin = 1.0 ;
	}
#endif
	for (row = 0 ; row < n ; row++)
	{
	    /* do not scale an empty row, or a row with a NaN */
	    rs = Rs [row] ;
	    if (SCALAR_IS_ZERO (rs) || SCALAR_IS_NAN (rs))
	    {
		Rs [row] = 1.0 ;
	    }
#ifndef NRECIPROCAL
	    rsmin = MIN (rsmin, Rs [row]) ;
#endif
	}

#ifndef NRECIPROCAL
	/* multiply by the reciprocal if Rs is not too small */
	do_recip = (rsmin >= RECIPROCAL_TOLERANCE) ;
	if (do_recip)
	{
	    /* invert the scale factors */
	    for (row = 0 ; row < n ; row++)
	    {
		Rs [row] = 1.0 / Rs [row] ;
	    }
	}
#endif
    }

    /* ---------------------------------------------------------------------- */
    /* compute the max in each column and find diagonal */
    /* ---------------------------------------------------------------------- */

    nweak = 0 ;

#ifndef NDEBUG
    for (k = 0 ; k < n ; k++)
    {
	ASSERT (Rperm1 [k] >= 0 && Rperm1 [k] < n) ;
	ASSERT (InvRperm1 [Rperm1 [k]] == k) ;
    }
#endif

    n2 = n - n1 - nempty ;

    /* use Ri to count the number of strong entries in each row */
    for (row = 0 ; row < n2 ; row++)
    {
	Ri [row] = 0 ;
    }

    pp = 0 ;
    ctol = 0 ;
    dvalue = 1 ;

    /* construct C = pruned submatrix, strong values only, column form */

    for (k = n1 ; k < n - nempty ; k++)
    {
	oldcol = Cperm1 [k] ;
	newcol = k - n1 ;
	Next [newcol] = EMPTY ;
	DEBUGm1 (("Column "ID" newcol "ID" oldcol "ID"\n", k, newcol, oldcol)) ;

	Cp [newcol] = pp ;

	dfound = FALSE ;
	p1 = Ap [oldcol] ;
	p2 = Ap [oldcol+1] ;
	if (do_values)
	{
	    cmax = 0 ;
	    dvalue = 0 ;

	    if (!do_scale)
	    {
		/* no scaling */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    ASSERT (oldrow >= 0 && oldrow < n) ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    ASSERT (newrow >= -n1 && newrow < n2) ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    /* if either cmax or value is NaN, define cmax as NaN */
		    if (!SCALAR_IS_NAN (cmax))
		    {
			if (SCALAR_IS_NAN (value))
			{
			    cmax = value ;
			}
			else
			{
			    cmax = MAX (cmax, value) ;
			}
		    }
		    if (oldrow == oldcol)
		    {
			/* we found the diagonal entry in this column */
			dvalue = value ;
			dfound = TRUE ;
			ASSERT (newrow == newcol) ;
		    }
		}
	    }
#ifndef NRECIPROCAL
	    else if (do_recip)
	    {
		/* multiply by the reciprocal */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    ASSERT (oldrow >= 0 && oldrow < n) ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    ASSERT (newrow >= -n1 && newrow < n2) ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    value *= Rs [oldrow] ;
		    /* if either cmax or value is NaN, define cmax as NaN */
		    if (!SCALAR_IS_NAN (cmax))
		    {
			if (SCALAR_IS_NAN (value))
			{
			    cmax = value ;
			}
			else
			{
			    cmax = MAX (cmax, value) ;
			}
		    }
		    if (oldrow == oldcol)
		    {
			/* we found the diagonal entry in this column */
			dvalue = value ;
			dfound = TRUE ;
			ASSERT (newrow == newcol) ;
		    }
		}
	    }
#endif
	    else
	    {
		/* divide instead */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    ASSERT (oldrow >= 0 && oldrow < n) ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    ASSERT (newrow >= -n1 && newrow < n2) ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    value /= Rs [oldrow] ;
		    /* if either cmax or value is NaN, define cmax as NaN */
		    if (!SCALAR_IS_NAN (cmax))
		    {
			if (SCALAR_IS_NAN (value))
			{
			    cmax = value ;
			}
			else
			{
			    cmax = MAX (cmax, value) ;
			}
		    }
		    if (oldrow == oldcol)
		    {
			/* we found the diagonal entry in this column */
			dvalue = value ;
			dfound = TRUE ;
			ASSERT (newrow == newcol) ;
		    }
		}
	    }

	    ctol = tol * cmax ;
	    DEBUGm1 (("    cmax col "ID" %g  ctol %g\n", oldcol, cmax, ctol)) ;
	}
	else
	{
	    for (p = p1 ; p < p2 ; p++)
	    {
		oldrow = Ai [p] ;
		ASSERT (oldrow >= 0 && oldrow < n) ;
		newrow = InvRperm1 [oldrow] - n1 ;
		ASSERT (newrow >= -n1 && newrow < n2) ;
		if (newrow < 0) continue ;
		Ci [pp++] = newrow ;
		if (oldrow == oldcol)
		{
		    /* we found the diagonal entry in this column */
		    ASSERT (newrow == newcol) ;
		    dfound = TRUE ;
		}
		/* count the entries in each column */
		Ri [newrow]++ ;
	    }
	}

	/* ------------------------------------------------------------------ */
	/* flag the weak diagonals */
	/* ------------------------------------------------------------------ */

	if (!dfound)
	{
	    /* no diagonal entry present */
	    weak = TRUE ;
	}
	else
	{
	    /* diagonal entry is present, check its value */
	    weak = (do_values) ?  WEAK (dvalue, ctol) : FALSE ;
	}
	if (weak)
	{
	    /* flag this column as weak */
	    DEBUG0 (("Weak!\n")) ;
	    Next [newcol] = IS_WEAK ;
	    nweak++ ;
	}

	/* ------------------------------------------------------------------ */
	/* count entries in each row that are not numerically weak */
	/* ------------------------------------------------------------------ */

	if (do_values)
	{
	    if (!do_scale)
	    {
		/* no scaling */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    weak = WEAK (value, ctol) ;
		    if (!weak)
		    {
			DEBUG0 (("    strong: row "ID": %g\n", oldrow, value)) ;
			Ci [pp++] = newrow ;
			Ri [newrow]++ ;
		    }
		}
	    }
#ifndef NRECIPROCAL
	    else if (do_recip)
	    {
		/* multiply by the reciprocal */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    value *= Rs [oldrow] ;
		    weak = WEAK (value, ctol) ;
		    if (!weak)
		    {
			DEBUG0 (("    strong: row "ID": %g\n", oldrow, value)) ;
			Ci [pp++] = newrow ;
			Ri [newrow]++ ;
		    }
		}
	    }
#endif
	    else
	    {
		/* divide instead */
		for (p = p1 ; p < p2 ; p++)
		{
		    oldrow = Ai [p] ;
		    newrow = InvRperm1 [oldrow] - n1 ;
		    if (newrow < 0) continue ;
		    ASSIGN (aij, Ax, Az, p, split) ;
		    APPROX_ABS (value, aij) ;
		    value /= Rs [oldrow] ;
		    weak = WEAK (value, ctol) ;
		    if (!weak)
		    {
			DEBUG0 (("    strong: row "ID": %g\n", oldrow, value)) ;
			Ci [pp++] = newrow ;
			Ri [newrow]++ ;
		    }
		}
	    }
	}
    }
    Cp [n2] = pp ;
    ASSERT (AMD_valid (n2, n2, Cp, Ci) == AMD_OK) ;

    if (nweak == 0)
    {
	/* nothing to do, quick return */
	DEBUGm2 (("\n =============================UMF_2by2: quick return\n")) ;
	for (k = 0 ; k < n ; k++)
	{
	    P [k] = k ;
	}
	*p_nweak = 0 ;
	*p_unmatched = 0 ;
	return ;
    }

#ifndef NDEBUG
    for (k = 0 ; k < n2 ; k++)
    {
	P [k] = EMPTY ;
    }
    for (k = 0 ; k < n2 ; k++)
    {
	ASSERT (Degree [k] >= 0 && Degree [k] < n2) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* find the 2-by-2 permutation */
    /* ---------------------------------------------------------------------- */

    /* The matrix S is now mapped to the index range 0 to n2-1.  We have
     * S = A (Rperm [n1 .. n-nempty-1], Cperm [n1 .. n-nempty-1]), and then
     * C = pattern of strong entries in S.  A weak diagonal k in S is marked
     * with Next [k] = IS_WEAK. */

    unmatched = two_by_two (n2, Cp, Ci, Degree, Next, Ri, P, Rp, Head) ;

    /* ---------------------------------------------------------------------- */

    *p_nweak = nweak ;
    *p_unmatched = unmatched ;

#ifndef NDEBUG
    DEBUGm4 (("UMF_2by2: weak "ID"  unmatched "ID"\n", nweak, unmatched)) ;
    for (row = 0 ; row < n ; row++)
    {
	DEBUGm2 (("P ["ID"] = "ID"\n", row, P [row])) ;
    }
    DEBUGm2 (("\n =============================UMF_2by2: done\n\n")) ;
#endif
}
Ejemplo n.º 26
0
PRIVATE void get_U
(
    Int Up [ ],		/* of size n_col+1 */
    Int Ui [ ],		/* of size unz, where unz = Up [n_col] */
    double Ux [ ],	/* of size unz */
#ifdef COMPLEX
    double Uz [ ],	/* of size unz */
#endif
    NumericType *Numeric,
    Int Pattern [ ],	/* workspace of size n_col */
    Int Wi [ ]		/* workspace of size n_col */
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry value ;
    Entry *xp, *D, *Uval ;
    Int deg, j, *ip, col, *Upos, *Uilen, *Uip, n_col, ulen, *Usi,
        unz2, p, k, up, newUchain, pos, npiv, n1 ;
#ifdef COMPLEX
    Int split = SPLIT (Uz) ;
#endif
#ifndef NDEBUG
    Int nnzpiv = 0 ;
#endif

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    DEBUG4 (("get_U start:\n")) ;
    n_col = Numeric->n_col ;
    n1 = Numeric->n1 ;
    npiv = Numeric->npiv ;
    Upos = Numeric->Upos ;
    Uilen = Numeric->Uilen ;
    Uip = Numeric->Uip ;
    D = Numeric->D ;

    /* ---------------------------------------------------------------------- */
    /* count the nonzeros in each column of U */
    /* ---------------------------------------------------------------------- */

    for (col = 0 ; col < npiv ; col++)
    {
	/* include the diagonal entry in the column counts */
	DEBUG4 (("D ["ID"] = ", col)) ;
	EDEBUG4 (D [col]) ;
	Wi [col] = IS_NONZERO (D [col]) ;
	DEBUG4 ((" is nonzero: "ID"\n", Wi [col])) ;
#ifndef NDEBUG
	nnzpiv += IS_NONZERO (D [col]) ;
#endif
    }
    DEBUG4 (("nnzpiv "ID" "ID"\n", nnzpiv, Numeric->nnzpiv)) ;
    ASSERT (nnzpiv == Numeric->nnzpiv) ;
    for (col = npiv ; col < n_col ; col++)
    {
	/* diagonal entries are zero for structurally singular part */
	Wi [col] = 0 ;
    }

    deg = Numeric->ulen ;
    if (deg > 0)
    {
	/* make last pivot row of U (singular matrices only) */
	DEBUG0 (("Last pivot row of U: ulen "ID"\n", deg)) ;
	for (j = 0 ; j < deg ; j++)
	{
	    Pattern [j] = Numeric->Upattern [j] ;
	    DEBUG0 (("    column "ID"\n", Pattern [j])) ;
	}
    }

    /* non-singletons */
    for (k = npiv-1 ; k >= n1 ; k--)
    {

	/* ------------------------------------------------------------------ */
	/* use row k of U */
	/* ------------------------------------------------------------------ */

	up = Uip [k] ;
	ulen = Uilen [k] ;
	newUchain = (up < 0) ;
	if (newUchain)
	{
	    up = -up ;
	    xp = (Entry *) (Numeric->Memory + up + UNITS (Int, ulen)) ;
	}
	else
	{
	    xp = (Entry *) (Numeric->Memory + up) ;
	}

	for (j = 0 ; j < deg ; j++)
	{
	    DEBUG4 (("  k "ID" col "ID" value\n", k, Pattern [j])) ;
	    col = Pattern [j] ;
	    ASSERT (col >= 0 && col < n_col) ;
	    value = *xp++ ;
	    EDEBUG4 (value) ;
	    DEBUG4 (("\n")) ;
	    if (IS_NONZERO (value))
	    {
		Wi [col]++ ;
	    }
	}

	/* ------------------------------------------------------------------ */
	/* make row k-1 of U in Pattern [0..deg-1] */
	/* ------------------------------------------------------------------ */

	if (k == n1) break ;

	if (newUchain)
	{
	    /* next row is a new Uchain */
	    deg = ulen ;
	    DEBUG4 (("end of chain for row of U "ID" deg "ID"\n", k-1, deg)) ;
	    ip = (Int *) (Numeric->Memory + up) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		col = *ip++ ;
		DEBUG4 (("  k "ID" col "ID"\n", k-1, col)) ;
		ASSERT (k <= col) ;
		Pattern [j] = col ;
	    }
	}
	else
	{
	    deg -= ulen ;
	    DEBUG4 (("middle of chain for row of U "ID" deg "ID"\n", k-1, deg));
	    ASSERT (deg >= 0) ;
	    pos = Upos [k] ;
	    if (pos != EMPTY)
	    {
		/* add the pivot column */
		DEBUG4 (("k "ID" add pivot entry at position "ID"\n", k, pos)) ;
		ASSERT (pos >= 0 && pos <= deg) ;
		Pattern [deg++] = Pattern [pos] ;
		Pattern [pos] = k ;
	    }
	}
    }

    /* singletons */
    for (k = n1 - 1 ; k >= 0 ; k--)
    {
	deg = Uilen [k] ;
	DEBUG4 (("Singleton k "ID"\n", k)) ;
	if (deg > 0)
	{
	    up = Uip [k] ;
	    Usi = (Int *) (Numeric->Memory + up) ;
	    up += UNITS (Int, deg) ;
	    Uval = (Entry *) (Numeric->Memory + up) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		col = Usi [j] ;
		value = Uval [j] ;
		DEBUG4 (("  k "ID" col "ID" value", k, col)) ;
		EDEBUG4 (value) ;
		DEBUG4 (("\n")) ;
		if (IS_NONZERO (value))
		{
		    Wi [col]++ ;
		}
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* construct the final column form of U */
    /* ---------------------------------------------------------------------- */

    /* create the column pointers */
    unz2 = 0 ;
    for (col = 0 ; col < n_col ; col++)
    {
	Up [col] = unz2 ;
	unz2 += Wi [col] ;
    }
    Up [n_col] = unz2 ;
    DEBUG1 (("Numeric->unz "ID"  npiv "ID" nnzpiv "ID" unz2 "ID"\n",
	Numeric->unz, npiv, Numeric->nnzpiv, unz2)) ;
    ASSERT (Numeric->unz + Numeric->nnzpiv == unz2) ;

    for (col = 0 ; col < n_col ; col++)
    {
	Wi [col] = Up [col+1] ;
    }

    /* add all of the diagonal entries */
    for (col = 0 ; col < npiv ; col++)
    {
	if (IS_NONZERO (D [col]))
	{
	    p = --(Wi [col]) ;
	    Ui [p] = col ;
#ifdef COMPLEX
	    if (split)
	    {

	        Ux [p] = REAL_COMPONENT (D [col]) ;
		Uz [p] = IMAG_COMPONENT (D [col]) ;
	    }
	    else
	    {
		Ux [2*p  ] = REAL_COMPONENT (D [col]) ;
		Ux [2*p+1] = IMAG_COMPONENT (D [col]) ;
	    }
#else
	    Ux [p] = D [col] ;
#endif
	}
    }

    /* add all the entries from the rows of U */

    deg = Numeric->ulen ;
    if (deg > 0)
    {
	/* make last pivot row of U (singular matrices only) */
	for (j = 0 ; j < deg ; j++)
	{
	    Pattern [j] = Numeric->Upattern [j] ;
	}
    }

    /* non-singletons */
    for (k = npiv-1 ; k >= n1 ; k--)
    {

	/* ------------------------------------------------------------------ */
	/* use row k of U */
	/* ------------------------------------------------------------------ */

	up = Uip [k] ;
	ulen = Uilen [k] ;
	newUchain = (up < 0) ;
	if (newUchain)
	{
	    up = -up ;
	    xp = (Entry *) (Numeric->Memory + up + UNITS (Int, ulen)) ;
	}
	else
	{
	    xp = (Entry *) (Numeric->Memory + up) ;
	}

	xp += deg ;
	for (j = deg-1 ; j >= 0 ; j--)
	{
	    DEBUG4 (("  k "ID" col "ID" value", k, Pattern [j])) ;
	    col = Pattern [j] ;
	    ASSERT (col >= 0 && col < n_col) ;
	    value = *(--xp) ;
	    EDEBUG4 (value) ;
	    DEBUG4 (("\n")) ;
	    if (IS_NONZERO (value))
	    {
		p = --(Wi [col]) ;
		Ui [p] = k ;
#ifdef COMPLEX
		if (split)
		{
		    Ux [p] = REAL_COMPONENT (value) ;
		    Uz [p] = IMAG_COMPONENT (value) ;
		}
		else
		{
		    Ux [2*p  ] = REAL_COMPONENT (value) ;
		    Ux [2*p+1] = IMAG_COMPONENT (value) ;
		}
#else
		Ux [p] = value ;
#endif

	    }
	}

	/* ------------------------------------------------------------------ */
	/* make row k-1 of U in Pattern [0..deg-1] */
	/* ------------------------------------------------------------------ */

	if (newUchain)
	{
	    /* next row is a new Uchain */
	    deg = ulen ;
	    DEBUG4 (("end of chain for row of U "ID" deg "ID"\n", k-1, deg)) ;
	    ip = (Int *) (Numeric->Memory + up) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		col = *ip++ ;
		DEBUG4 (("  k "ID" col "ID"\n", k-1, col)) ;
		ASSERT (k <= col) ;
		Pattern [j] = col ;
	    }
	}
	else
	{
	    deg -= ulen ;
	    DEBUG4 (("middle of chain for row of U "ID" deg "ID"\n", k-1, deg));
	    ASSERT (deg >= 0) ;
	    pos = Upos [k] ;
	    if (pos != EMPTY)
	    {
		/* add the pivot column */
		DEBUG4 (("k "ID" add pivot entry at position "ID"\n", k, pos)) ;
		ASSERT (pos >= 0 && pos <= deg) ;
		Pattern [deg++] = Pattern [pos] ;
		Pattern [pos] = k ;
	    }
	}
    }

    /* singletons */
    for (k = n1 - 1 ; k >= 0 ; k--)
    {
	deg = Uilen [k] ;
	DEBUG4 (("Singleton k "ID"\n", k)) ;
	if (deg > 0)
	{
	    up = Uip [k] ;
	    Usi = (Int *) (Numeric->Memory + up) ;
	    up += UNITS (Int, deg) ;
	    Uval = (Entry *) (Numeric->Memory + up) ;
	    for (j = 0 ; j < deg ; j++)
	    {
		col = Usi [j] ;
		value = Uval [j] ;
		DEBUG4 (("  k "ID" col "ID" value", k, col)) ;
		EDEBUG4 (value) ;
		DEBUG4 (("\n")) ;
		if (IS_NONZERO (value))
		{
		    p = --(Wi [col]) ;
		    Ui [p] = k ;
#ifdef COMPLEX
		    if (split)
		    {
			Ux [p] = REAL_COMPONENT (value) ;
			Uz [p] = IMAG_COMPONENT (value) ;
		    }
		    else
		    {
			Ux [2*p  ] = REAL_COMPONENT (value) ;
			Ux [2*p+1] = IMAG_COMPONENT (value) ;
		    }
#else
		    Ux [p] = value ;
#endif
		}
	    }
	}
    }

#ifndef NDEBUG
    DEBUG6 (("U matrix:")) ;
    UMF_dump_col_matrix (Ux,
#ifdef COMPLEX
	Uz,
#endif
	Ui, Up, Numeric->n_row, n_col, Numeric->unz + Numeric->nnzpiv) ;
#endif

}
Ejemplo n.º 27
0
GLOBAL Int UMFPACK_report_matrix
(
    Int n_row,
    Int n_col,
    const Int Ap [ ],
    const Int Ai [ ],
    const double Ax [ ],
#ifdef COMPLEX
    const double Az [ ],
#endif
    Int col_form,		/* 1: column form, 0: row form */
    const double Control [UMFPACK_CONTROL]
)
{
    Entry a ;
    Int prl, i, k, length, ilast, p, nz, prl1, p1, p2, n, n_i, do_values ;
    char *vector_kind, *index_kind ;
#ifdef COMPLEX
    Int split = SPLIT (Az) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* determine the form, and check if inputs exist */
    /* ---------------------------------------------------------------------- */

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    if (col_form)
    {
	vector_kind = "column" ;	/* column vectors */
	index_kind = "row" ;		/* with row indices */
	n = n_col ;
	n_i = n_row ;
    }
    else
    {
	vector_kind = "row" ;	/* row vectors */
	index_kind = "column" ;	/* with column indices */
	n = n_row ;
	n_i = n_col ;
    }

    PRINTF (("%s-form matrix, n_row "ID" n_col "ID", ",
        vector_kind, n_row, n_col)) ;

    if (n_row <= 0 || n_col <= 0)
    {
	PRINTF (("ERROR: n_row <= 0 or n_col <= 0\n\n")) ;
	return (UMFPACK_ERROR_n_nonpositive) ;
    }

    if (!Ap)
    {
	PRINTF (("ERROR: Ap missing\n\n")) ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    nz = Ap [n] ;
    PRINTF (("nz = "ID". ", nz)) ;
    if (nz < 0)
    {
	PRINTF (("ERROR: number of entries < 0\n\n")) ;
	return (UMFPACK_ERROR_invalid_matrix) ;
    }

    if (Ap [0] != 0)
    {
	PRINTF (("ERROR: Ap ["ID"] = "ID" must be "ID"\n\n",
	    (Int) INDEX (0), INDEX (Ap [0]), (Int) INDEX (0))) ;
	return (UMFPACK_ERROR_invalid_matrix) ;
    }

    if (!Ai)
    {
	PRINTF (("ERROR: Ai missing\n\n")) ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    do_values = Ax != (double *) NULL ;

    PRINTF4 (("\n")) ;

    /* ---------------------------------------------------------------------- */
    /* check the row/column pointers, Ap */
    /* ---------------------------------------------------------------------- */

    for (k = 0 ; k < n ; k++)
    {
	if (Ap [k] < 0)
	{
	    PRINTF (("ERROR: Ap ["ID"] < 0\n\n", INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
	if (Ap [k] > nz)
	{
	    PRINTF (("ERROR: Ap ["ID"] > size of Ai\n\n", INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

    for (k = 0 ; k < n ; k++)
    {
	length = Ap [k+1] - Ap [k] ;
	if (length < 0)
	{
	    PRINTF (("ERROR: # entries in %s "ID" is < 0\n\n",
		vector_kind, INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* print each vector */
    /* ---------------------------------------------------------------------- */

    prl1 = prl ;

    for (k = 0 ; k < n ; k++)
    {
	/* if prl is 4, print the first 10 entries of the first 10 vectors */
	if (k < 10)
	{
	    prl = prl1 ;
	}
	/* get the vector pointers */
	p1 = Ap [k] ;
	p2 = Ap [k+1] ;
	length = p2 - p1 ;
	PRINTF4 (("\n    %s "ID": start: "ID" end: "ID" entries: "ID"\n",
	    vector_kind, INDEX (k), p1, p2-1, length)) ;
	ilast = EMPTY ;
	for (p = p1 ; p < p2 ; p++)
	{
	    i = Ai [p] ;
	    PRINTF4 (("\t%s "ID" ", index_kind, INDEX (i))) ;
	    if (do_values && prl >= 4)
	    {
		PRINTF ((":")) ;
		ASSIGN (a, Ax, Az, p, split) ;
		PRINT_ENTRY (a) ;
	    }
	    if (i < 0 || i >= n_i)
	    {
		PRINTF ((" ERROR: %s index "ID" out of range in %s "ID"\n\n",
		    index_kind, INDEX (i), vector_kind, INDEX (k))) ;
		return (UMFPACK_ERROR_invalid_matrix) ;
	    }
	    if (i <= ilast)
	    {
		PRINTF ((" ERROR: %s index "ID" out of order (or duplicate) in "
		    "%s "ID"\n\n", index_kind, INDEX (i),
                    vector_kind, INDEX (k))) ;
		return (UMFPACK_ERROR_invalid_matrix) ;
	    }
	    PRINTF4 (("\n")) ;
	    /* truncate printout, but continue to check matrix */
	    if (prl == 4 && (p - p1) == 9 && length > 10)
	    {
		PRINTF4 (("\t...\n")) ;
		prl-- ;
	    }
	    ilast = i ;
	}
	/* truncate printout, but continue to check matrix */
	if (prl == 4 && k == 9 && n > 10)
	{
	    PRINTF4 (("\n    ...\n")) ;
	    prl-- ;
	}
    }
    prl = prl1 ;

    /* ---------------------------------------------------------------------- */
    /* return the status of the matrix */
    /* ---------------------------------------------------------------------- */

    PRINTF4 (("    %s-form matrix ", vector_kind)) ;
    PRINTF (("OK\n\n")) ;

    return (UMFPACK_OK) ;
}
Ejemplo n.º 28
0
GLOBAL Int UMF_triplet_map_x
#else
GLOBAL Int UMF_triplet_map_nox
#endif
#else
#ifdef DO_VALUES
GLOBAL Int UMF_triplet_nomap_x
#else
GLOBAL Int UMF_triplet_nomap_nox
#endif
#endif
(
    Int n_row,
    Int n_col,
    Int nz,
    const Int Ti [ ],		/* size nz */
    const Int Tj [ ],		/* size nz */
    Int Ap [ ],			/* size n_col + 1 */
    Int Ai [ ],			/* size nz */
    Int Rp [ ],			/* size n_row + 1 */
    Int Rj [ ],			/* size nz */
    Int W [ ],			/* size max (n_row, n_col) */
    Int RowCount [ ]		/* size n_row */
#ifdef DO_VALUES
    , const double Tx [ ]	/* size nz */
    , double Ax [ ]		/* size nz */
    , double Rx [ ]		/* size nz */
#ifdef COMPLEX
    , const double Tz [ ]	/* size nz */
    , double Az [ ]		/* size nz */
    , double Rz [ ]		/* size nz */
#endif
#endif
#ifdef DO_MAP
    , Int Map [ ]		/* size nz */
    , Int Map2 [ ]		/* size nz */
#endif
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int i, j, k, p, cp, p1, p2, pdest, pj ;
#ifdef DO_MAP
    Int duplicates ;
#endif
#ifdef DO_VALUES
#ifdef COMPLEX
    Int split = SPLIT (Tz) && SPLIT (Az) && SPLIT (Rz) ;
#endif
#endif

    /* ---------------------------------------------------------------------- */
    /* count the entries in each row (also counting duplicates) */
    /* ---------------------------------------------------------------------- */

    /* use W as workspace for row counts (including duplicates) */
    for (i = 0 ; i < n_row ; i++)
    {
	W [i] = 0 ;
    }

    for (k = 0 ; k < nz ; k++)
    {
	i = Ti [k] ;
	j = Tj [k] ;
	if (i < 0 || i >= n_row || j < 0 || j >= n_col)
	{
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
	W [i]++ ;
#ifndef NDEBUG
	DEBUG1 ((ID " triplet: "ID" "ID" ", k, i, j)) ;
#ifdef DO_VALUES
	{
	    Entry tt ;
	    ASSIGN (tt, Tx, Tz, k, split) ;
	    EDEBUG2 (tt) ;
	    DEBUG1 (("\n")) ;
	}
#endif
#endif
    }

    /* ---------------------------------------------------------------------- */
    /* compute the row pointers */
    /* ---------------------------------------------------------------------- */

    Rp [0] = 0 ;
    for (i = 0 ; i < n_row ; i++)
    {
	Rp [i+1] = Rp [i] + W [i] ;
	W [i] = Rp [i] ;
    }

    /* W is now equal to the row pointers */

    /* ---------------------------------------------------------------------- */
    /* construct the row form */
    /* ---------------------------------------------------------------------- */

    for (k = 0 ; k < nz ; k++)
    {
	p = W [Ti [k]]++ ;
#ifdef DO_MAP
	Map [k] = p ;
#endif
	Rj [p] = Tj [k] ;
#ifdef DO_VALUES
#ifdef COMPLEX
	if (split)
	{
	    Rx [p] = Tx [k] ;
	    Rz [p] = Tz [k] ;
	}
	else
	{
	    Rx [2*p  ] = Tx [2*k  ] ;
	    Rx [2*p+1] = Tx [2*k+1] ;
	}
#else
	Rx [p] = Tx [k] ;
#endif
#endif
    }

    /* Rp stays the same, but W [i] is advanced to the start of row i+1 */

#ifndef NDEBUG
    for (i = 0 ; i < n_row ; i++)
    {
	ASSERT (W [i] == Rp [i+1]) ;
    }
#ifdef DO_MAP
    for (k = 0 ; k < nz ; k++)
    {
	/* make sure that kth triplet is mapped correctly */
	p = Map [k] ;
	DEBUG1 (("First row map: Map ["ID"] = "ID"\n", k, p)) ;
	i = Ti [k] ;
	j = Tj [k] ;
	ASSERT (j == Rj [p]) ;
	ASSERT (Rp [i] <= p && p < Rp [i+1]) ;
    }
#endif
#endif

    /* ---------------------------------------------------------------------- */
    /* sum up duplicates */
    /* ---------------------------------------------------------------------- */

    /* use W [j] to hold position in Ri/Rx/Rz of a_ij, for row i [ */

    for (j = 0 ; j < n_col ; j++)
    {
	W [j] = EMPTY ;
    }

#ifdef DO_MAP
    duplicates = FALSE ;
#endif

    for (i = 0 ; i < n_row ; i++)
    {
	p1 = Rp [i] ;
	p2 = Rp [i+1] ;
	pdest = p1 ;
	/* At this point, W [j] < p1 holds true for all columns j, */
	/* because Ri/Rx/Rz is stored in row oriented order. */
#ifndef NDEBUG
	if (UMF_debug >= -2)
	{
	    for (j = 0 ; j < n_col ; j++)
	    {
		ASSERT (W [j] < p1) ;
	    }
	}
#endif
	for (p = p1 ; p < p2 ; p++)
	{
	    j = Rj [p] ;
	    ASSERT (j >= 0 && j < n_col) ;
	    pj = W [j] ;
	    if (pj >= p1)
	    {
		/* this column index, j, is already in row i, at position pj */
		ASSERT (pj < p) ;
		ASSERT (Rj [pj] == j) ;
#ifdef DO_MAP
		Map2 [p] = pj ;
		duplicates = TRUE ;
#endif
#ifdef DO_VALUES
		/* sum the entry */
#ifdef COMPLEX
		if (split)
		{
		    Rx [pj] += Rx [p] ;
		    Rz [pj] += Rz [p] ;
		}
		else
		{
		    Rx[2*pj  ] += Rx[2*p  ] ;
		    Rx[2*pj+1] += Rx[2*p+1] ;
		}
#else
		Rx [pj] += Rx [p] ;
#endif
#endif
	    }
	    else
	    {
		/* keep the entry */
		/* also keep track in W[j] of position of a_ij for case above */
		W [j] = pdest ;
#ifdef DO_MAP
		Map2 [p] = pdest ;
#endif
		/* no need to move the entry if pdest is equal to p */
		if (pdest != p)
		{
		    Rj [pdest] = j ;
#ifdef DO_VALUES
#ifdef COMPLEX
		    if (split)
		    {
			Rx [pdest] = Rx [p] ;
			Rz [pdest] = Rz [p] ;
		    }
		    else
		    {
			Rx [2*pdest  ] = Rx [2*p  ] ;
			Rx [2*pdest+1] = Rx [2*p+1] ;
		    }
#else
		    Rx [pdest] = Rx [p] ;
#endif
#endif
		}
		pdest++ ;
	    }
	}
	RowCount [i] = pdest - p1 ;
    }

    /* done using W for position of a_ij ] */

    /* ---------------------------------------------------------------------- */
    /* merge Map and Map2 into a single Map */
    /* ---------------------------------------------------------------------- */

#ifdef DO_MAP
    if (duplicates)
    {
	for (k = 0 ; k < nz ; k++)
	{
	    Map [k] = Map2 [Map [k]] ;
	}
    }
#ifndef NDEBUG
    else
    {
	/* no duplicates, so no need to recompute Map */
	for (k = 0 ; k < nz ; k++)
	{
	    ASSERT (Map2 [k] == k) ;
	}
    }
    for (k = 0 ; k < nz ; k++)
    {
	/* make sure that kth triplet is mapped correctly */
	p = Map [k] ;
	DEBUG1 (("Second row map: Map ["ID"] = "ID"\n", k, p)) ;
	i = Ti [k] ;
	j = Tj [k] ;
	ASSERT (j == Rj [p]) ;
	ASSERT (Rp [i] <= p && p < Rp [i+1]) ;
    }
#endif
#endif

    /* now the kth triplet maps to p = Map [k], and thus to Rj/Rx [p] */

    /* ---------------------------------------------------------------------- */
    /* count the entries in each column */
    /* ---------------------------------------------------------------------- */

    /* [ use W as work space for column counts of A */
    for (j = 0 ; j < n_col ; j++)
    {
	W [j] = 0 ;
    }

    for (i = 0 ; i < n_row ; i++)
    {
	for (p = Rp [i] ; p < Rp [i] + RowCount [i] ; p++)
	{
	    j = Rj [p] ;
	    ASSERT (j >= 0 && j < n_col) ;
	    W [j]++ ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* create the column pointers */
    /* ---------------------------------------------------------------------- */

    Ap [0] = 0 ;
    for (j = 0 ; j < n_col ; j++)
    {
	Ap [j+1] = Ap [j] + W [j] ;
    }
    /* done using W as workspace for column counts of A ] */

    for (j = 0 ; j < n_col ; j++)
    {
	W [j] = Ap [j] ;
    }

    /* ---------------------------------------------------------------------- */
    /* construct the column form */
    /* ---------------------------------------------------------------------- */

    for (i = 0 ; i < n_row ; i++)
    {
	for (p = Rp [i] ; p < Rp [i] + RowCount [i] ; p++)
	{
	    cp = W [Rj [p]]++ ;
#ifdef DO_MAP
	    Map2 [p] = cp ;
#endif
	    Ai [cp] = i ;
#ifdef DO_VALUES
#ifdef COMPLEX
	    if (split)
	    {
		Ax [cp] = Rx [p] ;
		Az [cp] = Rz [p] ;
	    }
	    else
	    {
		Ax [2*cp  ] = Rx [2*p  ] ;
		Ax [2*cp+1] = Rx [2*p+1] ;
	    }
#else
	    Ax [cp] = Rx [p] ;
#endif
#endif
	}
    }

    /* ---------------------------------------------------------------------- */
    /* merge Map and Map2 into a single Map */
    /* ---------------------------------------------------------------------- */

#ifdef DO_MAP
    for (k = 0 ; k < nz ; k++)
    {
	Map [k] = Map2 [Map [k]] ;
    }
#endif

    /* now the kth triplet maps to p = Map [k], and thus to Ai/Ax [p] */

#ifndef NDEBUG
    for (j = 0 ; j < n_col ; j++)
    {
	ASSERT (W [j] == Ap [j+1]) ;
    }

    UMF_dump_col_matrix (
#ifdef DO_VALUES
	Ax,
#ifdef COMPLEX
	Az,
#endif
#else
	(double *) NULL,
#ifdef COMPLEX
	(double *) NULL,
#endif
#endif
	Ai, Ap, n_row, n_col, nz) ;

#ifdef DO_MAP
    for (k = 0 ; k < nz ; k++)
    {
	/* make sure that kth triplet is mapped correctly */
	p = Map [k] ;
	DEBUG1 (("Col map: Map ["ID"] = "ID"\t", k, p)) ;
	i = Ti [k] ;
	j = Tj [k] ;
	ASSERT (i == Ai [p]) ;
	DEBUG1 (("   i "ID" j "ID" Ap[j] "ID" p "ID" Ap[j+1] "ID"\n",
		i, j, Ap [j], p, Ap [j+1])) ;
	ASSERT (Ap [j] <= p && p < Ap [j+1]) ;
    }
#endif
#endif

    return (UMFPACK_OK) ;
}
Ejemplo n.º 29
0
void fb_invn_low(dig_t *c, const dig_t *a) {
	int j, d, lu, lv, lt, l1, l2, bu, bv;
	align dig_t _u[2 * FB_DIGS], _v[2 * FB_DIGS];
	align dig_t _g1[2 * FB_DIGS], _g2[2 * FB_DIGS];
	dig_t *t = NULL, *u = NULL, *v = NULL, *g1 = NULL, *g2 = NULL, carry;

	dv_zero(_g1, FB_DIGS + 1);
	dv_zero(_g2, FB_DIGS + 1);

	u = _u;
	v = _v;
	g1 = _g1;
	g2 = _g2;

	/* u = a, v = f, g1 = 1, g2 = 0. */
	dv_copy(u, a, FB_DIGS);
	dv_copy(v, fb_poly_get(), FB_DIGS);
	g1[0] = 1;

	lu = lv = FB_DIGS;
	l1 = l2 = 1;

	bu = fb_bits(u);
	bv = FB_BITS + 1;
	j = bu - bv;

	/* While (u != 1). */
	while (1) {
		/* If j < 0 then swap(u, v), swap(g1, g2), j = -j. */
		if (j < 0) {
			t = u;
			u = v;
			v = t;

			lt = lu;
			lu = lv;
			lv = lt;

			t = g1;
			g1 = g2;
			g2 = t;

			lt = l1;
			l1 = l2;
			l2 = lt;

			j = -j;
		}

		SPLIT(j, d, j, FB_DIG_LOG);

		/* u = u + v * z^j. */
		if (j > 0) {
			carry = fb_lsha_low(u + d, v, j, lv);
			u[d + lv] ^= carry;
		} else {
			fb_addd_low(u + d, u + d, v, lv);
		}

		/* g1 = g1 + g2 * z^j. */
		if (j > 0) {
			carry = fb_lsha_low(g1 + d, g2, j, l2);
			l1 = (l2 + d >= l1 ? l2 + d : l1);
			if (carry) {
				g1[d + l2] ^= carry;
				l1 = (l2 + d >= l1 ? l1 + 1 : l1);
			}
		} else {
			fb_addd_low(g1 + d, g1 + d, g2, l2);
			l1 = (l2 + d > l1 ? l2 + d : l1);
		}

		while (u[lu - 1] == 0)
			lu--;
		while (v[lv - 1] == 0)
			lv--;

		if (lu == 1 && u[0] == 1)
			break;

		/* j = deg(u) - deg(v). */
		lt = util_bits_dig(u[lu - 1]) - util_bits_dig(v[lv - 1]);
		j = ((lu - lv) << FB_DIG_LOG) + lt;
	}
	/* Return g1. */
	fb_copy(c, g1);
}
Ejemplo n.º 30
0
void GMService::executeCommand(Player* gm, Packet& chatCommand) {
	std::string msg = std::string(chatCommand.getString(0x03)); //ClientID + char '/'
	if (msg.length() == 0)
		return;
	std::string command = msg.substr(0, msg.find(" "));
	std::string curValue = msg.substr(0, (msg.find(" ") == -1 ? msg.length() : msg.find(" ")));

#define WANTED_COMMAND(c2) (_stricmp(command.c_str(), c2)==0)
#define SPLIT() \
	msg = (msg.find(" ") == -1 ? "" : msg.substr(msg.find(" ")+1)); \
	curValue = msg.length() > 0 ? msg.substr(0, msg.find(" ")) : msg;

	SPLIT();
	if (WANTED_COMMAND("mon")) {
		dword_t monType = atoi(curValue.c_str());
		SPLIT();
		dword_t amount = atoi(curValue.c_str());
		for (unsigned int i = 0; i < amount; i++) {
			new Monster(mainServer->getNPCData(monType), mainServer->getAIData(monType), gm->getMapId(), gm->getPositionCurrent().calcNewPositionWithinRadius(amount * 20.0f));
		}
		ChatService::sendWhisper("Server", gm, "%i %s's were spawned.\n", amount, mainServer->getNPCData(monType)->getName().c_str());
	}
	else if (WANTED_COMMAND("debugmsg")) {
		if (curValue.length() == 0 || _stricmp(curValue.c_str(), "off")==0) {
			gm->setDebugMode(false);
			ChatService::sendWhisper("Server", gm, "Debug-Mode was disabled.\n");
		} 
		if (_stricmp(curValue.c_str(), "on") == 0) {
			gm->setDebugMode(true);
			ChatService::sendWhisper("Server", gm, "Debug-Mode was enabled.\n");
		}
	}
	else if (WANTED_COMMAND("where")) {
		ChatService::sendWhisper("Server", gm, "You are at %4.2f, %4.2f", gm->getPositionCurrent().x, gm->getPositionCurrent().y);
		ChatService::sendWhisper("Server", gm, "and heading towards %4.2f, %4.2f (%im per second)", gm->getPositionDest().x, gm->getPositionDest().y, gm->getMovementSpeed() / 100);
	}
	else if (WANTED_COMMAND("tele")) {
		word_t mapId = atoi(curValue.c_str()); SPLIT();
		if (mapId == 0 || mapId >= mainServer->mapData.size())
			return;
		float coordX = atoi(curValue.c_str()) * 100.0f; SPLIT();
		float coordY = atoi(curValue.c_str()) * 100.0f;

		gm->pakTelegate(mapId, position_t(coordX, coordY));
	} else if(WANTED_COMMAND("stats")) {
		ChatService::sendWhisper("Server", gm, "HP: %i/%i\n", gm->getCurrentHP(), gm->getMaxHP());
		ChatService::sendWhisper("Server", gm, "AtkPower: %i\n", gm->getAttackPower());
		ChatService::sendWhisper("Server", gm, "Defense: %i\n", gm->getDefensePhysical());
		ChatService::sendWhisper("Server", gm, "Hitrate: %i\n", gm->getHitrate());
		ChatService::sendWhisper("Server", gm, "AttackSpeed: %i\n", gm->getAttackSpeed());
		ChatService::sendWhisper("Server", gm, "AttackRange: %f\n", gm->getAttackRange());
	}
	else if (WANTED_COMMAND("level")) {
		byte_t newLevel = static_cast<BYTE>(atoi(curValue.c_str()) & 0xFF);
		if (newLevel == 0)
			newLevel = 1;
		gm->setLevel(newLevel);
	}
	else if(WANTED_COMMAND("heal")) {
		gm->setCurrentHP(gm->getMaxHP());
		gm->setCurrentMP(gm->getMaxMP());
		gm->pakUpdateLifeStats();
		ChatService::sendWhisper("Server", gm, "You were successfully healed: %i HP/ %i MP", gm->getCurrentHP(), gm->getCurrentMP());
	} else if(WANTED_COMMAND("equip")) {
		word_t itemType = atoi(curValue.c_str()); 
		if(itemType == 0 && curValue.length() > 0) {
			curValue = msg;
			for(unsigned int k=ItemType::FACE;k<=ItemType::SHIELD;k++) {
				STBFile* file = mainServer->getEquipmentSTB(k);
				for(unsigned int m=0;m<file->getRowCount();m++) {
					STBEntry& entry = file->getRow(m);
					std::string name = entry.getColumn(0x00);
					if(name.find(curValue.c_str()) != -1) {
						Item item(k, m);

						//In case the wanted item is valid (should always apply)
						if (mainServer->isValidItem(k, m)) {
							gm->addItemToInventory(item, PlayerInventory::fromItemType(item.type));
						}
						return;
					}
				}
			}
		}
		SPLIT();
	}
	else if (WANTED_COMMAND("eq_at")) {
		byte_t slot = static_cast<byte_t>(atoi(curValue.c_str())); 
		if (slot <= ItemType::PAT) {
			STBFile *file = mainServer->getEquipmentSTB(slot);
			for (word_t i = 0; i < file->getRowCount(); i++) {
				if (mainServer->isValidItem(slot, i)) {
					STBEntry& entry = file->getRow(i);
					gm->addItemToInventory(Item(slot, i), PlayerInventory::fromItemType(slot));
					ChatService::sendWhisper("Server", gm, "Equipped '%s' (Name: '%s', Type %i) in slot %i", ItemType::toString(slot), entry.getColumn(0x00).c_str(), i, PlayerInventory::fromItemType(slot));
					break;
				}
			}
		}
	}
	else if (WANTED_COMMAND("goto")) {
		bool success = false;
		if (curValue.length() > 2) {
			Player *player = nullptr;
			for (int i = 0; i < mainServer->getPlayerAmount();i++) {
				Player* p = mainServer->getGlobalPlayer(i);
				if (p != nullptr && p->getName().find(curValue) >= 0) {
					success = gm->pakTelegate(player->getMapId(), player->getPositionCurrent());
					
				}
			}
		}
		if (!success) {
			ChatService::sendWhisper("Server", gm, "Player '%s' cannot be found across the server.", curValue.c_str());
		}
	}
	else if(WANTED_COMMAND("drop")) {
		unsigned long itemType = static_cast<unsigned long>(atoi(curValue.c_str())); SPLIT();
		if(curValue.length() == 0) {
			//Drop money
			new Drop(gm, itemType, false);
		} else {
			//Drop item
			word_t itemNum = atoi(curValue.c_str()); SPLIT();
			if(itemNum == 0)
				return;
			word_t amount = curValue.length() == 0 ? 0x01 : atoi(curValue.c_str());

			Item item(static_cast<byte_t>(itemType), itemNum, 120, amount);
			if(mainServer->isValidItem(item.type, item.id))
				new Drop(gm, item, false);
		}
	}
#undef WANTED_COMMAND
#undef SPLIT
}