Ejemplo n.º 1
0
/*
 * ***************************************************************************
 * Routine:  Slu_lnDet
 *
 * Purpose:  Calculate the log of the determinant of a factored matrix.
 *
 * Notes:    UMFPACK has a built-in routine to compute the determinant,
 *           which returns both the mantissa and the exponent separately.
 *           This avoids most overflow and underflow problems.
 *
 * Author:   Stephen Bond
 * ***************************************************************************
 */
VPUBLIC double Slu_lnDet(Slu *thee)
{
    int status;
    double Mx, Ex, lndet;
    void *Numeric = thee->work;

    VASSERT( thee != VNULL );
    VASSERT( thee->statLU );

    /* Determinant = Mx * 10^Ex */
    status = umfpack_di_get_determinant( &Mx, &Ex, Numeric, VNULL );

    /* LOG(DET) = LOG(Mantissa) + Exponent*LOG(10) */
    lndet = VLOG(VABS(Mx)) + Ex*VLOG(10);

    if (UMFPACK_OK == status) {
        Vnm_print(0, "Slu_lnDet:  ln(det(A)) = %g\n", lndet);
        return lndet;
    } else {
        Vnm_print(0, "Slu_lnDet:  Failed!  Returning 1.0\n");
        return 1.0;
    }
}
Ejemplo n.º 2
0
dbl_vector solve_linear_system(dbl_matrix lhs, dbl_vector rhs)
{
  // Assume lhs is square.
  unsigned long num_rows = lhs.size1();
  
   // Convert lhs matrix into the format used in UMFPACK.
  int* ap;
  int* ai;
  double* ax;
  double* x;
  double* b;
  
  ap = new int[num_rows + 1];
  ELOG("ap memory allocated...");

  ai = new int[num_rows * num_rows];
  ELOG("ai memory allocated...");

  ax = new double[num_rows * num_rows];
  ELOG("ax memory allocated...");

  x = new double[num_rows];
  ELOG("x memory allocated...");

  b = new double[num_rows];
  ELOG("b memory allocated...");
 
  ap[0] = 0;
  for(unsigned long i_col = 1;
      i_col < num_rows + 1; ++i_col) {
    ap[i_col] = num_rows * i_col;
    ELOG("ap[", i_col, "] = ", ap[i_col]);
    for(unsigned long i_row = 0;
	i_row < num_rows; ++i_row) {
      ai[ap[i_col-1] + i_row] = i_row;
      ax[ap[i_col-1] + i_row] =
	lhs(i_row, i_col - 1);
    }
  }

  ELOG("Define right hand side...");
  // Set right hand side equal to portfolio.
  for(unsigned long i = 0; i < num_rows; ++i)
    b[i] = rhs(i);
  
  ELOG("Rhs to solve = ", rhs);

#ifdef DEBUG
  for(unsigned long i = 0; i < num_rows + 1; ++i)
    ELOG("ap[", i, "] = ", ap[i]);
  for(unsigned long i_row = 0;
      i_row < num_rows; ++i_row) {
    for(unsigned long i_col = 0;
	i_col < num_rows; ++i_col) {
      ELOG("A(", i_row, ",", i_col, ") = ", ax[ap[i_col] + i_row]);
    }
    ELOG("b(", i_row, ") = ", b[i_row]);
  }
#endif
  
  // Multiply inverted matrix and the transformed first_moment via lu
  // factorization and substitution.
  void *symbolic, *numeric;
  umfpack_di_symbolic(num_rows, num_rows,
		      ap, ai, ax,
		      &symbolic, null_double, null_double);
  umfpack_di_numeric(ap, ai, ax,
		     symbolic, &numeric, null_double, null_double);
  umfpack_di_free_symbolic(&symbolic);
  umfpack_di_solve(UMFPACK_A, ap, ai, ax, x, b,
		   numeric, null_double, null_double);
  
#ifdef DEBUG
  // Calculate determinant for diagnostics.
  double *det = new double[2];
  umfpack_di_get_determinant(det, null_double, numeric, null_double);
  ELOG("Determinant of second moment = ", det[0]);
  delete[] det;
#endif

  umfpack_di_free_numeric(&numeric);
  
  // Store solution in rhs.
  for(unsigned long i = 0; i < num_rows; ++i)
    rhs(i) = x[i];

  // Free memory.
  delete[] ap;
  delete[] ai;
  delete[] ax;
  delete[] x;
  delete[] b;

  return rhs;
}
Ejemplo n.º 3
0
void solve_linear_system(const int_vector& lhs_row_index,
			 const int_vector& lhs_col_index,
			 const dbl_vector& lhs_values,
			 dbl_vector rhs,
			 dbl_vector& out_solution,
			 void* numeric)
{
  // Assume lhs is square.
  unsigned long num_nonzero = lhs_values.size();
  unsigned long num_rows = rhs.size();
  
   // Convert lhs matrix into the format used in UMFPACK.
  int* ti;
  int* tj;
  double* tx;  
  int* ap;
  int* ai;
  double* ax;
  double* x;
  double* b;

  ti = new int[num_nonzero];
  ELOG("ti memory allocated...");
  tj = new int[num_nonzero];
  ELOG("tj memory allocated...");
  tx = new double[num_nonzero];
  ELOG("tx memory allocated...");

  // Copy to input data.
  for(unsigned long i = 0; i < num_nonzero; i++) {
    ti[i] = lhs_row_index(i);
    tj[i] = lhs_col_index(i);
    tx[i] = lhs_values(i);
    ELOG("ti, tj, tx (", i, ") = ",
	 ti[i], ", ", tj[i], ", ", tx[i], ", ");
  }
  
  ap = new int[num_rows + 1];
  ELOG("ap memory allocated...");
  ai = new int[num_rows * num_rows];
  ELOG("ai memory allocated...");
  ax = new double[num_rows * num_rows];
  ELOG("ax memory allocated...");

  umfpack_di_triplet_to_col(num_rows, num_rows, num_nonzero,
			    ti, tj, tx,
			    ap, ai, ax,
			    null_int);

  delete [] ti;
  delete [] tj;
  delete [] tx;

  x = new double[num_rows];
  ELOG("x memory allocated...");
  b = new double[num_rows];
  ELOG("b memory allocated...");
  
  ELOG("Define right hand side...");
  // Set right hand side equal to portfolio.
  for(unsigned long i = 0; i < num_rows; ++i)
    b[i] = rhs(i);
  
  ELOG("Rhs to solve = ", rhs);

#ifdef DEBUG
  for(unsigned long i = 0; i < num_rows + 1; ++i)
    ELOG("ap[", i, "] = ", ap[i]);
  for(unsigned long i_row = 0;
      i_row < num_rows; ++i_row) {
    for(unsigned long i_col = 0;
	i_col < num_rows; ++i_col) {
      ELOG("A(", i_row, ",", i_col, ") = ", ax[ap[i_col] + i_row]);
    }
    ELOG("b(", i_row, ") = ", b[i_row]);
  }
#endif
  
  // Sovle system by LU factorization.
  void *symbolic;

  // If the numeric pointer is void then we need to perform the
  // factorization.
  if(numeric == null_void) {
  umfpack_di_symbolic(num_rows, num_rows,
		      ap, ai, ax,
		      &symbolic, null_double, null_double);
  umfpack_di_numeric(ap, ai, ax,
		     symbolic, &numeric, null_double, null_double);
  umfpack_di_free_symbolic(&symbolic);
  }

  umfpack_di_solve(UMFPACK_A, ap, ai, ax, x, b,
		   numeric, null_double, null_double);
  
#ifdef DEBUG
  // Calculate determinant for diagnostics.
  double *det = new double[2];
  umfpack_di_get_determinant(det, null_double, numeric, null_double);
  ELOG("Determinant of second moment = ", det[0]);
  delete[] det;
#endif

  // Do not free the numeric pointer because this function does not own it.
  
  // Store the solution in the output argument.
  for(unsigned long i = 0; i < num_rows; ++i)
    out_solution(i) = x[i];

  // Free memory.
  delete[] ap;
  delete[] ai;
  delete[] ax;
  delete[] x;
  delete[] b;
}