Пример #1
0
  bool CGPenaltyLSAcceptor::InitializeImpl(const OptionsList& options,
      const std::string& prefix)
  {
    options.GetBoolValue("never_use_piecewise_penalty_ls",
                         never_use_piecewise_penalty_ls_, prefix);
    options.GetNumericValue("eta_penalty", eta_penalty_, prefix);
    options.GetNumericValue("penalty_update_infeasibility_tol",
                            penalty_update_infeasibility_tol_, prefix);
    options.GetNumericValue("eta_min", eta_min_, prefix);
    options.GetNumericValue("penalty_update_compl_tol",
                            penalty_update_compl_tol_, prefix);
    options.GetNumericValue("chi_hat", chi_hat_, prefix);
    options.GetNumericValue("chi_tilde", chi_tilde_, prefix);
    options.GetNumericValue("chi_cup", chi_cup_, prefix);
    options.GetNumericValue("gamma_hat", gamma_hat_, prefix);
    options.GetNumericValue("gamma_tilde", gamma_tilde_, prefix);
    options.GetNumericValue("epsilon_c", epsilon_c_, prefix);
    options.GetNumericValue("piecewisepenalty_gamma_obj",
                            piecewisepenalty_gamma_obj_, prefix);
    options.GetNumericValue("piecewisepenalty_gamma_infeasi",
                            piecewisepenalty_gamma_infeasi_, prefix);
    options.GetNumericValue("pen_theta_max_fact", pen_theta_max_fact_, prefix);
    options.GetNumericValue("min_alpha_primal", min_alpha_primal_, prefix);
    options.GetNumericValue("theta_min", theta_min_, prefix);
    options.GetNumericValue("mult_diverg_feasibility_tol", mult_diverg_feasibility_tol_, prefix);
    options.GetNumericValue("mult_diverg_y_tol", mult_diverg_y_tol_, prefix);
    // The following option has been registered by FilterLSAcceptor
    options.GetIntegerValue("max_soc", max_soc_, prefix);
    // The following option has been registered by CGSearhDirCalc
    options.GetNumericValue("penalty_max", penalty_max_, prefix);

    if (max_soc_>0) {
      ASSERT_EXCEPTION(IsValid(pd_solver_), OPTION_INVALID,
                       "Option \"max_soc\": This option is non-negative, but no linear solver for computing the SOC given to FilterLSAcceptor object.");
    }
    options.GetNumericValue("kappa_soc", kappa_soc_, prefix);

    pen_theta_max_ = -1.;
    pen_curr_mu_ = IpData().curr_mu();
    counter_first_type_penalty_updates_ = 0;
    counter_second_type_penalty_updates_ = 0;
    curr_eta_ = -1.;
    CGPenData().SetPenaltyUninitialized();
    ls_counter_ = 0;
    best_KKT_error_ = -1.;
    accepted_by_Armijo_ = true;
    //never_do_restor_ = true;
    jump_for_tiny_step_ = 0;

    return true;
  }
Пример #2
0
  bool WsmpSolverInterface::InitializeImpl(const OptionsList& options,
      const std::string& prefix)
  {
    options.GetIntegerValue("wsmp_num_threads", wsmp_num_threads_, prefix);
    Index wsmp_ordering_option;
    options.GetIntegerValue("wsmp_ordering_option", wsmp_ordering_option,
                            prefix);
    Index wsmp_ordering_option2;
    options.GetIntegerValue("wsmp_ordering_option2", wsmp_ordering_option2,
                            prefix);
    options.GetNumericValue("wsmp_pivtol", wsmp_pivtol_, prefix);
    if (options.GetNumericValue("wsmp_pivtolmax", wsmp_pivtolmax_, prefix)) {
      ASSERT_EXCEPTION(wsmp_pivtolmax_>=wsmp_pivtol_, OPTION_INVALID,
                       "Option \"wsmp_pivtolmax\": This value must be between "
                       "wsmp_pivtol and 1.");
    }
    else {
      wsmp_pivtolmax_ = Max(wsmp_pivtolmax_, wsmp_pivtol_);
    }
    options.GetNumericValue("wsmp_singularity_threshold",
                            wsmp_singularity_threshold_, prefix);
    options.GetIntegerValue("wsmp_scaling", wsmp_scaling_, prefix);
    options.GetIntegerValue("wsmp_write_matrix_iteration",
                            wsmp_write_matrix_iteration_, prefix);
    options.GetBoolValue("wsmp_skip_inertia_check",
                         skip_inertia_check_, prefix);
    options.GetBoolValue("wsmp_no_pivoting",
                         wsmp_no_pivoting_, prefix);

    // Reset all private data
    dim_=0;
    initialized_=false;
    printed_num_threads_ = false;
    pivtol_changed_ = false;
    have_symbolic_factorization_ = false;
    factorizations_since_recomputed_ordering_ = -1;
    delete[] a_;
    a_ = NULL;
    delete[] PERM_;
    PERM_ = NULL;
    delete[] INVP_;
    INVP_ = NULL;
    delete[] MRP_;
    MRP_ = NULL;

#ifdef PARDISO_MATCHING_PREPROCESS
    delete[] ia2;
    ia2 = NULL;

    delete[] ja2;
    ja2 = NULL;

    delete[] a2_;
    a2_ = NULL;

    delete[] perm2;
    perm2 = NULL;

    delete[] scale2;
    scale2 = NULL;
#endif

    // Set the number of threads
    ipfint NTHREADS = wsmp_num_threads_;
    F77_FUNC(wsetmaxthrds,WSETMAXTHRDS)(&NTHREADS);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "WSMP will use %d threads.\n", wsmp_num_threads_);

    // Get WSMP's default parameters and set the ones we want differently
    IPARM_[0] = 0;
    IPARM_[1] = 0;
    IPARM_[2] = 0;
    ipfint idmy;
    double ddmy;
    F77_FUNC(wssmp,WSSMP)(&idmy, &idmy, &idmy, &ddmy, &ddmy, &idmy,
                          &idmy, &ddmy, &idmy, &idmy, &ddmy, &idmy,
                          &idmy, IPARM_, DPARM_);
    IPARM_[15] = wsmp_ordering_option; // ordering option
    IPARM_[17] = 0; // use local minimum fill-in ordering
    IPARM_[19] = wsmp_ordering_option2; // for ordering in IP methods?
    if (wsmp_no_pivoting_) {
      IPARM_[30] = 1; // want L D L^T factorization with diagonal no pivoting
      IPARM_[26] = 1;
    }
    else {
      IPARM_[30] = 2; // want L D L^T factorization with diagonal with pivoting
    }
    // pivoting (Bunch/Kaufman)
    //IPARM_[31] = 1; // need D to see where first negative eigenvalue occurs
    //                   if we change this, we need DIAG arguments below!

    IPARM_[10] = 2; // Mark bad pivots

    // Set WSMP's scaling option
    IPARM_[9] = wsmp_scaling_;

    DPARM_[9] = wsmp_singularity_threshold_;

    matrix_file_number_ = 0;

    // Check for SPINLOOPTIME and YIELDLOOPTIME?

    return true;
  }
Пример #3
0
bool Ma57TSolverInterface::InitializeImpl(const OptionsList&  options,
        const std::string&    prefix)
{
    // Obtain the options settings
    options.GetNumericValue("ma57_pivtol", pivtol_, prefix);
    if (options.GetNumericValue("ma57_pivtolmax", pivtolmax_, prefix)) {
        ASSERT_EXCEPTION(pivtolmax_>=pivtol_, OPTION_INVALID,
                         "Option \"pivtolmax\": This value must be between "
                         "pivtol and 1.");
    }
    else {
        pivtolmax_ = Max(pivtolmax_, pivtol_);
    }

    options.GetNumericValue("ma57_pre_alloc", ma57_pre_alloc_, prefix);
    Index ma57_pivot_order;
    options.GetIntegerValue("ma57_pivot_order", ma57_pivot_order, prefix);

    // The following option is registered by OrigIpoptNLP
    options.GetBoolValue("warm_start_same_structure",
                         warm_start_same_structure_, prefix);
    DBG_ASSERT(!warm_start_same_structure_ && "warm_start_same_structure not yet implemented");

    bool ma57_automatic_scaling;
    options.GetBoolValue("ma57_automatic_scaling", ma57_automatic_scaling, prefix);

    // CET 04-29-2010
    Index ma57_block_size;
    options.GetIntegerValue("ma57_block_size", ma57_block_size, prefix);

    Index ma57_node_amalgamation;
    options.GetIntegerValue("ma57_node_amalgamation", ma57_node_amalgamation, prefix);

    Index ma57_small_pivot_flag;
    options.GetIntegerValue("ma57_small_pivot_flag", ma57_small_pivot_flag, prefix);
    // CET 04-29-2010


    /* Initialize. */
    F77_FUNC (ma57id, MA57ID) (wd_cntl_, wd_icntl_);

    /* Custom settings for MA57. */
    wd_icntl_[1-1] = 0;      /* Error stream */
    wd_icntl_[2-1] = 0;      /* Warning stream. */

    wd_icntl_[4-1] = 1;      /* Print statistics.  NOT Used. */
    wd_icntl_[5-1] = 0;      /* Print error. */

    wd_icntl_[6-1] = ma57_pivot_order;       /* Pivoting order. */

    wd_cntl_[1-1]  = pivtol_;    /* Pivot threshold. */
    wd_icntl_[7-1] = 1;      /* Pivoting strategy. */

    // CET: Added 04-29-2010 at suggestion of Jonathan Hogg of HSL
    wd_icntl_[11-1] = ma57_block_size;   /* Block size used by Level 3 BLAS in MA57BD - should be a multiple of 8.  Default is 16. */
    wd_icntl_[12-1] = ma57_node_amalgamation; /* Two nodes of the assembly tree are merged only if both involve less than ICNTL(12) eliminations.  Default is 16. */
    // CET: 04-29-2010


    if (ma57_automatic_scaling) {
        wd_icntl_[15-1] = 1;
    }
    else {
        wd_icntl_[15-1] = 0;
    }


    // CET: Added 04-29-2010 at suggestion of Jonathan Hogg of HSL
    wd_icntl_[16-1] = ma57_small_pivot_flag;    /* If set to 1, small entries are removed and corresponding pivots are placed at the end of factorization.  May be useful for highly rank deficient matrices.  Default is 0. */
    // CET: 04-29-2010


    // wd_icntl[8-1] = 0;       /* Retry factorization. */

    if (!warm_start_same_structure_) {
        dim_=0;
        nonzeros_=0;
        delete [] a_;
        a_ = NULL;
        delete [] wd_fact_;
        wd_fact_ = NULL;
        delete [] wd_ifact_;
        wd_ifact_ = NULL;
        delete [] wd_iwork_;
        wd_iwork_ = NULL;
        delete [] wd_keep_;
        wd_keep_ = NULL;
    }
    else {
        ASSERT_EXCEPTION(dim_>0 && nonzeros_>0, INVALID_WARMSTART,
                         "Ma57TSolverInterface called with warm_start_same_structure, "
                         "but the problem is solved for the first time.");
    }

    return true;
}
  bool WarmStartIterateInitializer::InitializeImpl(const OptionsList& options,
      const std::string& prefix)
  {
    if (!options.GetNumericValue("warm_start_bound_push",
                                 warm_start_bound_push_, prefix)) {
      options.GetNumericValue("bound_push",
                              warm_start_bound_push_, prefix);
    }
    if (!options.GetNumericValue("warm_start_bound_frac",
                                 warm_start_bound_frac_, prefix)) {
      options.GetNumericValue("bound_frac",
                              warm_start_bound_frac_, prefix);
    }
    if (!options.GetNumericValue("warm_start_slack_bound_push",
                                 warm_start_slack_bound_push_, prefix)) {
      if (!options.GetNumericValue("bound_push",
                                   warm_start_slack_bound_push_, prefix)) {
        if (!options.GetNumericValue("warm_start_slack_bound_push",
                                     warm_start_slack_bound_push_, prefix)) {
          options.GetNumericValue("bound_push",
                                  warm_start_slack_bound_push_, prefix);
        }
      }
    }
    if (!options.GetNumericValue("warm_start_slack_bound_frac",
                                 warm_start_slack_bound_frac_, prefix)) {
      if (!options.GetNumericValue("bound_frac",
                                   warm_start_slack_bound_frac_, prefix)) {
        if (!options.GetNumericValue("warm_start_slack_bound_frac",
                                     warm_start_slack_bound_frac_, prefix)) {
          options.GetNumericValue("bound_frac",
                                  warm_start_slack_bound_frac_, prefix);
        }
      }
    }
    options.GetNumericValue("warm_start_mult_bound_push",
                            warm_start_mult_bound_push_, prefix);
    options.GetNumericValue("warm_start_mult_init_max",
                            warm_start_mult_init_max_, prefix);
    options.GetNumericValue("warm_start_target_mu",
                            warm_start_target_mu_, prefix);
    options.GetBoolValue("warm_start_entire_iterate",
                         warm_start_entire_iterate_, prefix);

    return true;
  }
  bool PardisoSolverInterface::InitializeImpl(const OptionsList& options,
      const std::string& prefix)
  {
    Index enum_int;
    options.GetEnumValue("pardiso_matching_strategy", enum_int, prefix);
    match_strat_ = PardisoMatchingStrategy(enum_int);
    options.GetBoolValue("pardiso_redo_symbolic_fact_only_if_inertia_wrong",
                         pardiso_redo_symbolic_fact_only_if_inertia_wrong_,
                         prefix);
    options.GetBoolValue("pardiso_repeated_perturbation_means_singular",
                         pardiso_repeated_perturbation_means_singular_,
                         prefix);
    //Index pardiso_out_of_core_power;
    //options.GetIntegerValue("pardiso_out_of_core_power",
    //                        pardiso_out_of_core_power, prefix);
    options.GetBoolValue("pardiso_skip_inertia_check",
                         skip_inertia_check_, prefix);
    int pardiso_msglvl;
    options.GetIntegerValue("pardiso_msglvl", pardiso_msglvl, prefix);
    int max_iterref_steps;
    options.GetIntegerValue("pardiso_max_iterative_refinement_steps", max_iterref_steps, prefix);
    int order;
    options.GetEnumValue("pardiso_order", order, prefix);
#if !defined(HAVE_PARDISO_OLDINTERFACE) && !defined(HAVE_PARDISO_MKL)
    options.GetBoolValue("pardiso_iterative", pardiso_iterative_, prefix);
    int pardiso_max_iter;
    options.GetIntegerValue("pardiso_max_iter", pardiso_max_iter, prefix);
    Number pardiso_iter_relative_tol;
    options.GetNumericValue("pardiso_iter_relative_tol",
                            pardiso_iter_relative_tol, prefix);
    Index pardiso_iter_coarse_size;
    options.GetIntegerValue("pardiso_iter_coarse_size",
                            pardiso_iter_coarse_size, prefix);
    Index pardiso_iter_max_levels;
    options.GetIntegerValue("pardiso_iter_max_levels",
                            pardiso_iter_max_levels, prefix);
    Number pardiso_iter_dropping_factor;
    options.GetNumericValue("pardiso_iter_dropping_factor",
                            pardiso_iter_dropping_factor, prefix);
    Number pardiso_iter_dropping_schur;
    options.GetNumericValue("pardiso_iter_dropping_schur",
                            pardiso_iter_dropping_schur, prefix);
    Index pardiso_iter_max_row_fill;
    options.GetIntegerValue("pardiso_iter_max_row_fill",
                            pardiso_iter_max_row_fill, prefix);
    Number pardiso_iter_inverse_norm_factor;
    options.GetNumericValue("pardiso_iter_inverse_norm_factor",
                            pardiso_iter_inverse_norm_factor, prefix);
    options.GetIntegerValue("pardiso_max_droptol_corrections",
                            pardiso_max_droptol_corrections_, prefix);
#else
    pardiso_iterative_ = false;
#endif

    // Number value = 0.0;

    // Tell Pardiso to release all memory if it had been used before
    if (initialized_) {
      ipfint PHASE = -1;
      ipfint N = dim_;
      ipfint NRHS = 0;
      ipfint ERROR;
      ipfint idmy;
      double ddmy;
      PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N,
                   &ddmy, &idmy, &idmy, &idmy, &NRHS, IPARM_,
                   &MSGLVL_, &ddmy, &ddmy, &ERROR, DPARM_);
      DBG_ASSERT(ERROR==0);
    }

    // Reset all private data
    dim_=0;
    nonzeros_=0;
    have_symbolic_factorization_=false;
    initialized_=false;
    delete[] a_;
    a_ = NULL;

#ifdef PARDISO_MATCHING_PREPROCESS
    delete[] ia2;
    ia2 = NULL;

    delete[] ja2;
    ja2 = NULL;

    delete[] a2_;
    a2_ = NULL;

    delete[] perm2;
    perm2 = NULL;

    delete[] scale2;
    scale2 = NULL;
#endif

    // Call Pardiso's initialization routine
    IPARM_[0] = 0;  // Tell it to fill IPARM with default values(?)

#if ! defined(HAVE_PARDISO_OLDINTERFACE) && ! defined(HAVE_PARDISO_MKL)
    ipfint ERROR = 0;
    ipfint SOLVER = 0; // initialize only direct solver

    PARDISOINIT_FUNC(PT_, &MTYPE_, &SOLVER, IPARM_, DPARM_, &ERROR);
#else
    PARDISOINIT_FUNC(PT_, &MTYPE_, IPARM_);
#endif

    // Set some parameters for Pardiso
    IPARM_[0] = 1;  // Don't use the default values

    int num_procs = 1;
#if defined(HAVE_PARDISO_PARALLEL) || ! defined(HAVE_PARDISO)
    // Obtain the numbers of processors from the value of OMP_NUM_THREADS
    char* var = getenv("OMP_NUM_THREADS");
    if (var != NULL) {
      sscanf( var, "%d", &num_procs );
      if (num_procs < 1) {
        Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                       "Invalid value for OMP_NUM_THREADS (\"%s\").\n", var);
        return false;
      }
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "Using environment OMP_NUM_THREADS = %d as the number of processors for PARDISO.\n", num_procs);
    }
#if defined(HAVE_PARDISO) && ! defined(HAVE_PARDISO_MKL)
    // If we run Pardiso through the linear solver loader,
    // we do not know whether it is the parallel version, so we do not report a warning if OMP_NUM_THREADS is not set.
    // If we run Pardiso from MKL, then OMP_NUM_THREADS does not need to be set, so no warning.
    else {
      Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA,
                     "You should set the environment variable OMP_NUM_THREADS to the number of processors used in Pardiso (e.g., 1).\n\n");
    }
#endif
#endif

#ifdef HAVE_PARDISO_MKL
    IPARM_[1] = order;
    // For MKL PARDSIO, the documentation says, "iparm(3) Reserved. Set to zero.", so we don't set IPARM_[2]
    IPARM_[5] = 1;  // Overwrite right-hand side
    IPARM_[7] = max_iterref_steps;
    IPARM_[9] = 12; // pivot perturbation (as higher as less perturbation)
    IPARM_[10] = 2; // enable scaling (recommended for interior-point indefinite matrices)
    IPARM_[12] = (int)match_strat_; // enable matching (recommended, as above)
    IPARM_[20] = 3; // bunch-kaufman pivoting
    IPARM_[23] = 1; // parallel fac
    IPARM_[24] = 1; // parallel solve
    //IPARM_[26] = 1; // matrix checker
#else
    IPARM_[1] = order;
    IPARM_[2] = num_procs; // Set the number of processors
    IPARM_[5] = 1;  // Overwrite right-hand side
    IPARM_[7] = max_iterref_steps;

    // Options suggested by Olaf Schenk
    IPARM_[9] = 12;
    IPARM_[10] = 2; // Results in better scaling
    // Matching information:  IPARM_[12] = 1 seems ok, but results in a
    // large number of pivot perturbation
    // Matching information:  IPARM_[12] = 2 robust,  but more  expensive method
    IPARM_[12] = (int)match_strat_;

    IPARM_[20] = 3; // Results in better accuracy
    IPARM_[23] = 1; // parallel fac
    IPARM_[24] = 1; // parallel solve
    IPARM_[28] = 0; // 32-bit factorization
    IPARM_[29] = 1; //we need this for IPOPT interface
    //IPARM_[33] = 1; // bit-by-bit identical results in parallel run
#endif

    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "Pardiso matrix ordering     (IPARM(2)): %d\n", IPARM_[1]);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "Pardiso max. iterref. steps (IPARM(8)): %d\n", IPARM_[7]);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "Pardiso matching strategy  (IPARM(13)): %d\n", IPARM_[12]);

    if (pardiso_iterative_) {
#if defined(HAVE_PARDISO_OLDINTERFACE) || defined(HAVE_PARDISO_MKL)
      THROW_EXCEPTION(OPTION_INVALID,
                      "You chose to use the iterative version of Pardiso, but you need to use a Pardiso version of at least 4.0.");
#else
      IPARM_[31] = 1 ;  // active direct solver

      DPARM_[ 0] = pardiso_max_iter; // maximum number of Krylov-Subspace Iteration
      // Default is 300
      // 1 <= value <= e.g. 1000
      DPARM_[ 1] = pardiso_iter_relative_tol; // Relative Residual Convergence
      // e.g.  pardiso_iter_tol
      // Default is 1e-6
      // 1e-16 <= value < 1
      DPARM_[ 2] = pardiso_iter_coarse_size; // Maximum Size of Coarse Grid Matrix
      // e.g.  pardiso_coarse_grid
      // Default is 5000
      // 1 <= value < number of equations
      DPARM_[ 3] = pardiso_iter_max_levels; // Maximum Number of Grid Levels
      // e.g.  pardiso_max_grid
      // Default is 10000
      // 1 <= value < number of equations
      DPARM_[ 4] = pardiso_iter_dropping_factor;  // dropping value for incomplete factor
      // e.g.  pardiso_dropping_factor
      // Default is 0.5
      // 1e-16 <= value < 1
      DPARM_[ 5] = pardiso_iter_dropping_schur;  // dropping value for sparsify schur complementfactor
      // e.g.  pardiso_dropping_schur
      // Default is 0.1
      // 1e-16 <= value < 1
      DPARM_[ 6] = pardiso_iter_max_row_fill;  // max fill for each row
      // e.g.  pardiso_max_fill
      // Default is 1000
      // 1 <= value < 100000
      DPARM_[ 7] = pardiso_iter_inverse_norm_factor;  // dropping value for sparsify schur complementfactor
      // e.g.  pardiso_inverse_norm_factor
      // Default is 500
      // 2 <= value < 50000
      DPARM_[ 8] = 25; // maximum number of non-improvement steps
#endif
    }

    MSGLVL_ = pardiso_msglvl;

    // Option for the out of core variant
    //IPARM_[49] = pardiso_out_of_core_power;

    return true;
  }
Пример #6
0
 bool StandardScalingBase::InitializeImpl(const OptionsList& options,
     const std::string& prefix)
 {
   options.GetNumericValue("obj_scaling_factor", obj_scaling_factor_, prefix);
   return true;
 }
Пример #7
0
 bool GradientScaling::InitializeImpl(const OptionsList& options,
                                      const std::string& prefix)
 {
   options.GetNumericValue("nlp_scaling_max_gradient", scaling_max_gradient_, prefix);
   return StandardScalingBase::InitializeImpl(options, prefix);
 }
Пример #8
0
  bool WsmpSolverInterface::InitializeImpl(const OptionsList& options,
      const std::string& prefix)
  {
    options.GetIntegerValue("wsmp_num_threads", wsmp_num_threads_, prefix);
    options.GetIntegerValue("wsmp_ordering_option", wsmp_ordering_option_,
                            prefix);
    options.GetNumericValue("wsmp_pivtol", wsmp_pivtol_, prefix);
    if(options.GetNumericValue("wsmp_pivtolmax", wsmp_pivtolmax_, prefix)) {
      ASSERT_EXCEPTION(wsmp_pivtolmax_>=wsmp_pivtol_, OPTION_INVALID,
                       "Option \"wsmp_pivtolmax\": This value must be between "
                       "wsmp_pivtol and 1.");
    }
    else {
      wsmp_pivtolmax_ = Max(wsmp_pivtolmax_, wsmp_pivtol_);
    }
    options.GetNumericValue("wsmp_singularity_threshold",
                            wsmp_singularity_threshold_, prefix);
    options.GetIntegerValue("wsmp_scaling", wsmp_scaling_, prefix);
    options.GetIntegerValue("wsmp_write_matrix_iteration",
                            wsmp_write_matrix_iteration_, prefix);

    // Reset all private data
    dim_=0;
    initialized_=false;
    pivtol_changed_ = false;
    have_symbolic_factorization_ = false;
    delete[] a_;
    delete[] PERM_;
    delete[] INVP_;

    // Set the number of threads
    ipfint NTHREADS = wsmp_num_threads_;
    F77_FUNC(wsetmaxthrds,WSETMAXTHRDS)(&NTHREADS);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "WSMP will use %d threads.\n", wsmp_num_threads_);

    // Get WSMP's default parameters and set the ones we want differently
    IPARM_[0] = 0;
    IPARM_[1] = 0;
    IPARM_[2] = 0;
    ipfint idmy;
    double ddmy;
    F77_FUNC(wssmp,WSSMP)(&idmy, &idmy, &idmy, &ddmy, &ddmy, &idmy,
                          &idmy, &ddmy, &idmy, &idmy, &ddmy, &idmy,
                          &idmy, IPARM_, DPARM_);
    IPARM_[14] = 0; // no restrictions on pivoting (ignored for
    // Bunch-Kaufman)
    IPARM_[15] = wsmp_ordering_option_; // ordering option
    IPARM_[17] = 1; // use local minimum fill-in ordering
    IPARM_[19] = 1; // for ordering in IP methods?
    IPARM_[30] = 2; // want L D L^T factorization with diagonal
    // pivoting (Bunch/Kaufman)
    //IPARM_[31] = 1; // need D to see where first negative eigenvalue occurs
    //                   if we change this, we need DIAG arguments below!

    IPARM_[10] = 1; // THis is not used by Bunch/Kaufman, but for L D
    // L^T without pivoting it is the value we used
    // before

    // Set WSMP's scaling option
    IPARM_[9] = wsmp_scaling_;

    DPARM_[9] = wsmp_singularity_threshold_;

    matrix_file_number_ = 0;

    // Check for SPINLOOPTIME and YIELDLOOPTIME?

    return true;
  }