Ejemplo n.º 1
0
void QP
( const SparseMatrix<Real>& A, 
  const Matrix<Real>& B, 
        Matrix<Real>& X, 
  const qp::direct::Ctrl<Real>& ctrl )
{
    DEBUG_CSE

    const Int n = A.Width();
    const Int k = B.Width();
    SparseMatrix<Real> Q, AHat;
    Matrix<Real> bHat, c;

    Herk( LOWER, ADJOINT, Real(1), A, Q );
    MakeHermitian( LOWER, Q );
    Zeros( AHat, 0, n );
    Zeros( bHat, 0, 1 );
    Zeros( X,    n, k );

    Matrix<Real> y, z;
    for( Int j=0; j<k; ++j )
    {
        auto x = X( ALL, IR(j) );
        auto b = B( ALL, IR(j) );

        Zeros( c, n, 1 );
        Multiply( ADJOINT, Real(-1), A, b, Real(0), c );

        El::QP( Q, AHat, bHat, c, x, y, z, ctrl );
    }
}
Ejemplo n.º 2
0
void ShiftDiagonal
( SparseMatrix<T>& A, S alphaPre, Int offset, bool existingDiag )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    const T alpha = T(alphaPre);
    if( existingDiag )
    {
        T* valBuf = A.ValueBuffer();
        for( Int i=Max(0,-offset); i<Min(m,n-offset); ++i )
        {
            const Int e = A.Offset( i, i+offset );
            valBuf[e] += alpha;
        } 
    }
    else
    {
        const Int diagLength = Min(m,n-offset) - Max(0,-offset);
        A.Reserve( diagLength );
        for( Int i=Max(0,-offset); i<Min(m,n-offset); ++i )
            A.QueueUpdate( i, i+offset, alpha );
        A.ProcessQueues();
    }
}
Ejemplo n.º 3
0
T OneNorm(const SparseMatrix<T>& A)
{
    // compute the max absolute column sum
    const unsigned int* cols_a = A.LockedColBuffer();
    const T*            data_a = A.LockedDataBuffer();
    const unsigned int width_a = A.Width();

    T max_col_sum = T(0), col_sum;
    for (unsigned int c=0; c != width_a; ++c)
    {
        unsigned int start = cols_a[c];
        unsigned int   end = cols_a[c+1];
        col_sum = T(0);
        for (unsigned int offset=start; offset != end; ++offset)
        {
            T val = fabs(data_a[offset]);
            col_sum += val;
        }

        if (col_sum > max_col_sum)
            max_col_sum = col_sum;
    }

    return max_col_sum;
}
Ejemplo n.º 4
0
bool WriteMatrixMarketFile(const std::string& file_path,
                           const SparseMatrix<T>& A,
                           const unsigned int precision)
{
    // Write a MatrixMarket file with no comments.  Note that the
    // MatrixMarket format uses 1-based indexing for rows and columns.

    std::ofstream outfile(file_path);
    if (!outfile)
        return false;

    unsigned int height = A.Height();
    unsigned int width  = A.Width();
    unsigned int nnz    = A.Size();
    
    // write the 'banner'
    outfile << MM_BANNER << " matrix coordinate real general" << std::endl;

    // write matrix dimensions and number of nonzeros
    outfile << height << " " << width << " " << nnz << std::endl;

    outfile << std::fixed;
    outfile.precision(precision);
    
    const unsigned int* cols_a = A.LockedColBuffer();
    const unsigned int* rows_a = A.LockedRowBuffer();
    const T*            data_a = A.LockedDataBuffer();
    unsigned int width_a = A.Width();

    for (unsigned int c=0; c != width_a; ++c)
    {
        unsigned int start = cols_a[c];
        unsigned int end   = cols_a[c+1];
        for (unsigned int offset=start; offset != end; ++offset)
        {
            unsigned int r = rows_a[offset];
            T val = data_a[offset];
            outfile << r+1 << " " << c+1 << " " << val << std::endl;
        }
    }

    outfile.close();
    return true;
}
Ejemplo n.º 5
0
void LAV
( const SparseMatrix<Real>& A,
  const Matrix<Real>& b,
        Matrix<Real>& x,
  const lp::affine::Ctrl<Real>& ctrl )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    const Range<Int> xInd(0,n), uInd(n,n+m), vInd(n+m,n+2*m);
    SparseMatrix<Real> AHat, G;
    Matrix<Real> c, h;

    // c := [0;1;1]
    // ============
    Zeros( c, n+2*m, 1 );
    auto cuv = c( IR(n,n+2*m), ALL );
    Fill( cuv, Real(1) );

    // \hat A := [A, I, -I]
    // ====================
    Zeros( AHat, m, n+2*m );
    const Int numEntriesA = A.NumEntries();
    AHat.Reserve( numEntriesA + 2*m );
    for( Int e=0; e<numEntriesA; ++e )
        AHat.QueueUpdate( A.Row(e), A.Col(e), A.Value(e) );
    for( Int i=0; i<m; ++i )
    {
        AHat.QueueUpdate( i, i+n,   Real( 1) );
        AHat.QueueUpdate( i, i+n+m, Real(-1) );
    }
    AHat.ProcessQueues();

    // G := | 0 -I  0 |
    //      | 0  0 -I |
    // ================
    Zeros( G, 2*m, n+2*m );
    G.Reserve( G.Height() );
    for( Int i=0; i<2*m; ++i )
        G.QueueUpdate( i, i+n, Real(-1) );
    G.ProcessQueues();

    // h := | 0 |
    //      | 0 |
    // ==========
    Zeros( h, 2*m, 1 );

    // Solve the affine linear program
    // ===============================
    Matrix<Real> xHat, y, z, s;
    LP( AHat, G, b, c, h, xHat, y, z, s, ctrl );

    // Extract x
    // =========
    x = xHat( xInd, ALL );
}
Ejemplo n.º 6
0
void Print(const SparseMatrix<T>& M)
{
    // Print a SparseMatrix to the screen.

    const unsigned int* col_buf = M.LockedColBuffer();
    const unsigned int* row_buf = M.LockedRowBuffer();
    const T*                buf = M.LockedDataBuffer();

    if (0 == M.Size())
    {
        std::cout << "Matrix is empty." << std::endl;
        return;
    }

    for (unsigned int c=0; c != M.Width(); ++c)
    {
        unsigned int start = col_buf[c];
        unsigned int end   = col_buf[c+1];
        for (unsigned int offset=start; offset != end; ++offset)
        {
            assert(offset >= 0);
            assert(offset < M.Size());
            unsigned int row_index = row_buf[offset];
            T                 data = buf[offset];
            std::cout << "(" << row_index << ", " << c << "): " << data << std::endl;
        }
    }

    std::cout << "Col indices: "; std::cout.flush();
    for (unsigned int i=0; i != M.Width(); ++i)
        std::cout << col_buf[i] << ", ";
    std::cout << col_buf[M.Width()] << std::endl;

    std::cout << "Row indices: "; std::cout.flush();
    for (unsigned int i=0; i != M.Size(); ++i)
        std::cout << row_buf[i] << ", ";
    std::cout << std::endl;

    std::cout << "Data:        "; std::cout.flush();
    for (unsigned int i=0; i != M.Size(); ++i)
        std::cout << buf[i] << ", ";
    std::cout << std::endl;
}
Ejemplo n.º 7
0
void Tikhonov
( Orientation orientation,
  const SparseMatrix<F>& A,
  const Matrix<F>& B,
  const SparseMatrix<F>& G,
        Matrix<F>& X, 
  const LeastSquaresCtrl<Base<F>>& ctrl )
{
    DEBUG_CSE
    
    // Explicitly form W := op(A)
    // ==========================
    SparseMatrix<F> W;
    if( orientation == NORMAL )
        W = A;
    else if( orientation == TRANSPOSE )
        Transpose( A, W );
    else
        Adjoint( A, W );

    const Int m = W.Height();
    const Int n = W.Width();
    const Int numRHS = B.Width();

    // Embed into a higher-dimensional problem via appending regularization
    // ====================================================================
    SparseMatrix<F> WEmb;
    if( m >= n )
        VCat( W, G, WEmb ); 
    else
        HCat( W, G, WEmb );
    Matrix<F> BEmb;
    Zeros( BEmb, WEmb.Height(), numRHS );
    if( m >= n )
    {
        auto BEmbT = BEmb( IR(0,m), IR(0,numRHS) );
        BEmbT = B;
    }
    else
        BEmb = B;

    // Solve the higher-dimensional problem
    // ====================================
    Matrix<F> XEmb;
    LeastSquares( NORMAL, WEmb, BEmb, XEmb, ctrl );

    // Extract the solution
    // ====================
    if( m >= n )
        X = XEmb;
    else
        X = XEmb( IR(0,n), IR(0,numRHS) ); 
}
Ejemplo n.º 8
0
void StackedRuizEquil
( SparseMatrix<Field>& A,
  SparseMatrix<Field>& B,
  Matrix<Base<Field>>& dRowA,
  Matrix<Base<Field>>& dRowB,
  Matrix<Base<Field>>& dCol,
  bool progress )
{
    EL_DEBUG_CSE
    typedef Base<Field> Real;
    const Int mA = A.Height();
    const Int mB = B.Height();
    const Int n = A.Width();
    Ones( dRowA, mA, 1 );
    Ones( dRowB, mB, 1 );
    Ones( dCol, n, 1 );

    // TODO(poulson): Expose these as control parameters
    // For now, simply hard-code the number of iterations
    const Int maxIter = 4;

    Matrix<Real> scales, maxAbsValsB;
    const Int indent = PushIndent();
    for( Int iter=0; iter<maxIter; ++iter )
    {
        // Rescale the columns
        // -------------------
        ColumnMaxNorms( A, scales );
        ColumnMaxNorms( B, maxAbsValsB );
        for( Int j=0; j<n; ++j )
            scales(j) = Max(scales(j),maxAbsValsB(j));
        EntrywiseMap( scales, MakeFunction(DampScaling<Real>) );
        DiagonalScale( LEFT, NORMAL, scales, dCol );
        DiagonalSolve( RIGHT, NORMAL, scales, A );
        DiagonalSolve( RIGHT, NORMAL, scales, B );

        // Rescale the rows
        // ----------------
        RowMaxNorms( A, scales );
        EntrywiseMap( scales, MakeFunction(DampScaling<Real>) );
        DiagonalScale( LEFT, NORMAL, scales, dRowA );
        DiagonalSolve( LEFT, NORMAL, scales, A );

        RowMaxNorms( B, scales );
        EntrywiseMap( scales, MakeFunction(DampScaling<Real>) );
        DiagonalScale( LEFT, NORMAL, scales, dRowB );
        DiagonalSolve( LEFT, NORMAL, scales, B );
    }
    SetIndent( indent );
}
Ejemplo n.º 9
0
void KKT
( const SparseMatrix<Real>& A,
  const SparseMatrix<Real>& G,
  const Matrix<Real>& s,
  const Matrix<Real>& z,
        SparseMatrix<Real>& J,
  bool onlyLower )
{
    EL_DEBUG_CSE
    const Int n = A.Width();
    SparseMatrix<Real> Q;
    Q.Resize( n, n );
    qp::affine::KKT( Q, A, G, s, z, J, onlyLower );
}
Ejemplo n.º 10
0
void AugmentedKKT
( const SparseMatrix<Real>& A,
        Real gamma,
        Real delta,
  const Matrix<Real>& x,
  const Matrix<Real>& z,
        SparseMatrix<Real>& J,
  bool onlyLower )
{
    EL_DEBUG_CSE
    const Int n = A.Width();
    SparseMatrix<Real> Q;
    Zeros( Q, n, n );
    qp::direct::AugmentedKKT( Q, A, gamma, delta, x, z, J, onlyLower );
}
Ejemplo n.º 11
0
void KKT
( const SparseMatrix<Real>& A,
        Real gamma,
        Real delta,
        Real beta,
  const Matrix<Real>& x,
  const Matrix<Real>& z,
        SparseMatrix<Real>& J, bool onlyLower )
{
    EL_DEBUG_CSE
    const Int n = A.Width();
    SparseMatrix<Real> Q;
    Q.Resize( n, n );
    qp::direct::KKT( Q, A, gamma, delta, beta, x, z, J, onlyLower );
}
Ejemplo n.º 12
0
void StaticKKT
( const SparseMatrix<Real>& A,
  const SparseMatrix<Real>& G,
        Real gamma,
        Real delta,
        Real beta,
        SparseMatrix<Real>& J,
  bool onlyLower )
{
    EL_DEBUG_CSE
    const Int n = A.Width();
    SparseMatrix<Real> Q;
    Q.Resize( n, n );
    qp::affine::StaticKKT( Q, A, G, gamma, delta, beta, J, onlyLower );
}
Ejemplo n.º 13
0
void Fill( SparseMatrix<T>& A, T alpha )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    A.Resize( m, n );
    Zero( A );
    if( alpha != T(0) )
    {
        A.Reserve( m*n ); 
        for( Int i=0; i<m; ++i )
            for( Int j=0; j<n; ++j )
                A.QueueUpdate( i, j, alpha );
        A.ProcessQueues();
    }
}
Ejemplo n.º 14
0
void MatrixMarket( const SparseMatrix<T>& A, string basename="matrix" )
{
    EL_DEBUG_CSE
    
    string filename = basename + "." + FileExtension(MATRIX_MARKET);
    ofstream file( filename.c_str(), std::ios::binary );
    if( !file.is_open() )
        RuntimeError("Could not open ",filename);

    // Write the header
    // ================
    {
        ostringstream os;
        os << "%%MatrixMarket matrix coordinate ";
        if( IsComplex<T>::value )
            os << "complex "; 
        else
            os << "real ";
        os << "general\n";
        file << os.str();
    }
    
    // Write the size line
    // ===================
    const Int m = A.Height();
    const Int n = A.Width();
    const Int numNonzeros = A.NumEntries();
    file << BuildString(m," ",n," ",numNonzeros,"\n");
    
    // Write the entries
    // =================
    for( Int e=0; e<numNonzeros; ++e )
    {
        const Int i = A.Row(e);
        const Int j = A.Col(e);
        const T value = A.Value(e);
        if( IsComplex<T>::value )
        {
            file << 
              BuildString(i," ",j," ",RealPart(value)," ",ImagPart(value),"\n");
        }
        else
        {
            file << BuildString(i," ",j," ",RealPart(value),"\n");
        }
    }
}
Ejemplo n.º 15
0
void Lanczos
( const SparseMatrix<F>& A,
        Matrix<Base<F>>& T,
        Int basisSize )
{
    DEBUG_CSE
    const Int n = A.Height();
    if( n != A.Width() )
        LogicError("A was not square");
    
    auto applyA =
      [&]( const Matrix<F>& X, Matrix<F>& Y )
      {
          Zeros( Y, n, X.Width() );
          Multiply( NORMAL, F(1), A, X, F(0), Y );
      };
    Lanczos<F>( n, applyA, T, basisSize );
}
Ejemplo n.º 16
0
Base<Field> ProductLanczosDecomp
( const SparseMatrix<Field>& A,
        Matrix<Field>& V,
        Matrix<Base<Field>>& T,
        Matrix<Field>& v,
        Int basisSize )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();

    Matrix<Field> S;

    // Cache the adjoint
    // -----------------
    SparseMatrix<Field> AAdj;
    Adjoint( A, AAdj );

    if( m >= n )
    {
        auto applyA =
          [&]( const Matrix<Field>& X, Matrix<Field>& Y )
          {
              Zeros( S, m, X.Width() );
              Multiply( NORMAL, Field(1), A,    X, Field(0), S );
              Zeros( Y, n, X.Width() );
              Multiply( NORMAL, Field(1), AAdj, S, Field(0), Y );
          };
        return LanczosDecomp( n, applyA, V, T, v, basisSize );
    }
    else
    {
        auto applyA =
          [&]( const Matrix<Field>& X, Matrix<Field>& Y )
          {
              Zeros( S, n, X.Width() );
              Multiply( NORMAL, Field(1), AAdj, X, Field(0), S );
              Zeros( Y, m, X.Width() );
              Multiply( NORMAL, Field(1), A,    S, Field(0), Y );
          };
        return LanczosDecomp( m, applyA, V, T, v, basisSize );
    }
}
Ejemplo n.º 17
0
Base<Field> LanczosDecomp
( const SparseMatrix<Field>& A,
        Matrix<Field>& V,
        Matrix<Base<Field>>& T,
        Matrix<Field>& v,
        Int basisSize )
{
    EL_DEBUG_CSE
    const Int n = A.Height();
    if( n != A.Width() )
        LogicError("A was not square");

    auto applyA =
      [&]( const Matrix<Field>& X, Matrix<Field>& Y )
      {
          Zeros( Y, n, X.Width() );
          Multiply( NORMAL, Field(1), A, X, Field(0), Y );
      };
    return LanczosDecomp( n, applyA, V, T, v, basisSize );
}
Ejemplo n.º 18
0
void GetMappedDiagonal
( const SparseMatrix<T>& A,
        Matrix<S>& d,
        function<S(const T&)> func,
        Int offset )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    const T* valBuf = A.LockedValueBuffer();
    const Int* colBuf = A.LockedTargetBuffer();

    const Int iStart = Max(-offset,0);
    const Int jStart = Max( offset,0);

    const Int diagLength = El::DiagonalLength(m,n,offset);
    d.Resize( diagLength, 1 );
    Zero( d );
    S* dBuf = d.Buffer();

    for( Int k=0; k<diagLength; ++k )
    {
        const Int i = iStart + k;
        const Int j = jStart + k;
        const Int thisOff = A.RowOffset(i);
        const Int nextOff = A.RowOffset(i+1);
        auto it = std::lower_bound( colBuf+thisOff, colBuf+nextOff, j );
        if( *it == j )
        {
            const Int e = it-colBuf;
            dBuf[Min(i,j)] = func(valBuf[e]);
        }
        else
            dBuf[Min(i,j)] = func(0);
    }
}
Ejemplo n.º 19
0
void IPM
( const SparseMatrix<Real>& A,
  const Matrix<Real>& b, 
        Real lambda,
        Matrix<Real>& x,
  const qp::affine::Ctrl<Real>& ctrl )
{
    DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    const Range<Int> uInd(0,n), vInd(n,2*n), rInd(2*n,2*n+m);
    SparseMatrix<Real> Q, AHat, G;
    Matrix<Real> c, h;

    // Q := | 0 0 0 |
    //      | 0 0 0 |
    //      | 0 0 I |
    // ==============
    Zeros( Q, 2*n+m, 2*n+m );
    Q.Reserve( m );
    for( Int e=0; e<m; ++e )
        Q.QueueUpdate( 2*n+e, 2*n+e, Real(1) );
    Q.ProcessQueues();

    // c := lambda*[1;1;0]
    // ===================
    Zeros( c, 2*n+m, 1 );
    auto cuv = c( IR(0,2*n), ALL );
    Fill( cuv, lambda );

    // \hat A := [A, -A, I]
    // ====================
    const Int numEntriesA = A.NumEntries();
    Zeros( AHat, m, 2*n+m );
    AHat.Reserve( 2*numEntriesA+m );
    for( Int e=0; e<numEntriesA; ++e )
    {
        AHat.QueueUpdate( A.Row(e), A.Col(e),    A.Value(e) );
        AHat.QueueUpdate( A.Row(e), A.Col(e)+n, -A.Value(e) );
    }
    for( Int e=0; e<m; ++e )
        AHat.QueueUpdate( e, e+2*n, Real(1) );
    AHat.ProcessQueues();

    // G := | -I  0 0 |
    //      |  0 -I 0 |
    // ================
    Zeros( G, 2*n, 2*n+m );
    G.Reserve( 2*m );
    for( Int e=0; e<2*m; ++e )
        G.QueueUpdate( e, e, Real(-1) );
    G.ProcessQueues();

    // h := 0
    // ======
    Zeros( h, 2*n, 1 );

    // Solve the affine QP
    // ===================
    Matrix<Real> xHat, y, z, s;
    QP( Q, AHat, G, b, c, h, xHat, y, z, s, ctrl );

    // x := u - v
    // ==========
    x = xHat( uInd, ALL );
    x -= xHat( vInd, ALL );
}
Ejemplo n.º 20
0
//-----------------------------------------------------------------------------
void Nmf(const unsigned int kval, 
         const Algorithm algorithm,
         const std::string& csv_file_w,
         const std::string& csv_file_h)
{
    if (!matrix_loaded)
        throw std::logic_error("smallk error (NMF): no matrix has been loaded.");

    if (max_iter < min_iter)
        throw std::logic_error("smallk error (NMF): min_iterations exceeds max_iterations.");

    if (0 == kval)
        throw std::logic_error("smallk error (NMF): k must be greater than 0.");

    // Check the sizes of matrix W(m, k) and matrix H(k, n) and make sure 
    // they don't overflow Elemental's default signed int index type.

    if (!SizeCheck<int>(m, kval))
        throw std::logic_error("smallk error (Nmf): mxk matrix W is too large.");
    
    if (!SizeCheck<int>(kval, n))
        throw std::logic_error("smallk error (Nmf): kxn matrix H is too large.");

    k = kval;

    // convert to the 'NmfAlgorithm' type in nmf.hpp
    switch (algorithm)
    {
    case Algorithm::MU:
        nmf_opts.algorithm = NmfAlgorithm::MU;
        break;
    case Algorithm::HALS:
        nmf_opts.algorithm = NmfAlgorithm::HALS;
        break;
    case Algorithm::RANK2:
        nmf_opts.algorithm = NmfAlgorithm::RANK2;
        break;
    case Algorithm::BPP:
        nmf_opts.algorithm = NmfAlgorithm::BPP;
        break;
    default:
        throw std::logic_error("smallk error (NMF): unknown NMF algorithm.");
    }

    // set k == 2 for Rank2 algorithm
    if (NmfAlgorithm::RANK2 == nmf_opts.algorithm)
        k = 2;

    ldim_w = m;
    ldim_h = k;

    if (buf_w.size() < m*k)
        buf_w.resize(m*k);
    if (buf_h.size() < k*n)
        buf_h.resize(k*n);
    
    // initialize matrices W and H
    bool ok;
    unsigned int height_w = m, width_w = k, height_h = k, width_h = n;

    cout << "Initializing matrix W..." << endl;
    if (csv_file_w.empty())
        ok = RandomMatrix(&buf_w[0], ldim_w, m, k, rng);
    else
        ok = LoadDelimitedFile(buf_w, height_w, width_w, csv_file_w);
    if (!ok)
    {
        std::ostringstream msg;
        msg << "smallk error (Nmf): load failed for file ";
        msg << "\"" << csv_file_w << "\"";
        throw std::runtime_error(msg.str());
    }

    if ( (height_w != m) || (width_w != k))
    {
        cerr << "\tdimensions of matrix W are " << height_w
             << " x " << width_w << endl;
        cerr << "\texpected " << m << " x " << k << endl;
        throw std::logic_error("smallk error (Nmf): non-conformant matrix W.");
    }

    cout << "Initializing matrix H..." << endl;
    if (csv_file_h.empty())
        ok = RandomMatrix(&buf_h[0], ldim_h, k, n, rng);
    else
        ok = LoadDelimitedFile(buf_h, height_h, width_h, csv_file_h);

    if (!ok)
    {
        std::ostringstream msg;
        msg << "smallk error (Nmf): load failed for file ";
        msg << "\"" << csv_file_h << "\"";
        throw std::runtime_error(msg.str());
    }
    
    if ( (height_h != k) || (width_h != n))
    {
        cerr << "\tdimensions of matrix H are " << height_h
             << " x " << width_h << endl;
        cerr << "\texpected " << k << " x " << n << endl;
        throw std::logic_error("smallk error (Nmf): non-conformant matrix H.");
    }    

    // The ratio of projected gradient norms doesn't seem to work very well
    // with MU.  We frequently observe a 'leveling off' behavior and the 
    // convergence is even slower than usual.  So for MU use the relative
    // change in the Frobenius norm of W as the stopping criterion, which
    // always seems to behave well, even though it is on shaky theoretical
    // ground.

    if (NmfAlgorithm::MU == nmf_opts.algorithm)
        nmf_opts.prog_est_algorithm = NmfProgressAlgorithm::DELTA_FNORM;
    else
        nmf_opts.prog_est_algorithm = NmfProgressAlgorithm::PG_RATIO;

    nmf_opts.tol         = nmf_tolerance;
    nmf_opts.height      = m;
    nmf_opts.width       = n;
    nmf_opts.k           = k;
    nmf_opts.min_iter    = min_iter;
    nmf_opts.max_iter    = max_iter;
    nmf_opts.tolcount    = 1;
    nmf_opts.max_threads = max_threads;
    nmf_opts.verbose     = true;
    nmf_opts.normalize   = true;

    // display all params to user
    PrintNmfOpts(nmf_opts);

    NmfStats stats;
    Result result;
    if (is_sparse)
    {
        result = NmfSparse(nmf_opts, 
                           A.Height(), A.Width(), A.Size(),
                           A.LockedColBuffer(),
                           A.LockedRowBuffer(),
                           A.LockedDataBuffer(),
                           &buf_w[0], ldim_w,
                           &buf_h[0], ldim_h,
                           stats);
    }
    else
    {
        result = Nmf(nmf_opts,
                     &buf_a[0], ldim_a,
                     &buf_w[0], ldim_w,
                     &buf_h[0], ldim_h,
                     stats);
    }

    cout << "Elapsed wall clock time: ";
    cout << ElapsedTime(stats.elapsed_us) << endl;
    cout << endl;

    if (Result::OK != result)
        throw std::runtime_error("smallk error (Nmf): NMF solver failure.");

    // write the computed W and H factors to disk

    std::string outfile_w, outfile_h;
    if (outdir.empty())
    {
        outfile_w = DEFAULT_FILENAME_W;
        outfile_h = DEFAULT_FILENAME_H;
    }
    else
    {
        outfile_w = outdir + DEFAULT_FILENAME_W;
        outfile_h = outdir + DEFAULT_FILENAME_H;
    }

    cout << "Writing output files..." << endl;
    
    if (!WriteDelimitedFile(&buf_w[0], ldim_w, m, k, outfile_w, outprecision))
        throw std::runtime_error("smallk error (Nmf): could not write W result.");
    
    if (!WriteDelimitedFile(&buf_h[0], ldim_h, k, n, outfile_h, outprecision))
        throw std::runtime_error("smallk error (Nmf): could not write H result.");
}
Ejemplo n.º 21
0
Archivo: Solver.cpp Proyecto: 93i/godot
/** Bi-conjugate gradient method.  */
MATHLIB_API int BiConjugateGradientSolve( const SparseMatrix &A, const DenseVector &b, DenseVector &x, float epsilon ) {
    piDebugCheck( A.IsSquare() );
    piDebugCheck( A.Width() == b.Dim() );
    piDebugCheck( A.Width() == x.Dim() );

    int i = 0;
    const int D = A.Width();
    const int i_max = 4 * D;

    float resid;
    float rho_1 = 0;
    float rho_2 = 0;
    float alpha;
    float beta;

    DenseVector r(D);
    DenseVector rtilde(D);
    DenseVector p(D);
    DenseVector ptilde(D);
    DenseVector q(D);
    DenseVector qtilde(D);
    DenseVector tmp(D);	// temporal vector.

    // r = b - A·x;
    A.Product( x, tmp );
    r.Sub( b, tmp );

    // rtilde = r
    rtilde.Set( r );

    // p = r;
    p.Set( r );

    // ptilde = rtilde
    ptilde.Set( rtilde );



    float normb = b.Norm();
    if( normb == 0.0 ) normb = 1;

    // test convergence
    resid = r.Norm() / normb;
    if( resid < epsilon ) {
        // method converges?
        return 0;
    }


    while( i < i_max ) {

        i++;

        rho_1 = DenseVectorDotProduct( r, rtilde );

        if( rho_1 == 0 ) {
            // method fails.
            return -i;
        }

        if (i == 1) {
            p.Set( r );
            ptilde.Set( rtilde );
        } 
        else {
            beta = rho_1 / rho_2;

            // p = r + beta * p;
            p.Mad( r, p, beta );

            // ptilde = ztilde + beta * ptilde;
            ptilde.Mad( rtilde, ptilde, beta );
        }

        // q = A * p;
        A.Product( p, q );

        // qtilde = A^t * ptilde;
        A.TransProduct( ptilde, qtilde );

        alpha = rho_1 / DenseVectorDotProduct( ptilde, q );

        // x += alpha * p;
        x.Mad( x, p, alpha );

        // r -= alpha * q;
        r.Mad( r, q, -alpha );

        // rtilde -= alpha * qtilde;
        rtilde.Mad( rtilde, qtilde, -alpha );

        rho_2 = rho_1;

        // test convergence
        resid = r.Norm() / normb;
        if( resid < epsilon ) {
            // method converges
            return i;
        }
    }

    return i;
}
Ejemplo n.º 22
0
//-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    Timer timer;
    double elapsed_s;

    // print usage info if no command line args were specified
    std::string prog_name(argv[0]);
    if (1 == argc)
    {
        PrintUsage(prog_name);
        return 0;
    }

    CommandLineOptions opts;
    ParseCommandLine(argc, argv, opts);
    if (!IsValid(opts))
        return -1;

    //
    // Check to see if the specified directories exist.
    //

    if (!DirectoryExists(opts.indir))
    {
        cerr << "\npreprocessor: the specified input directory "
             << opts.indir << " does not exist." << endl;
        return -1;
    }

    if (!opts.outdir.empty())
    {
        if (!DirectoryExists(opts.outdir))
        {
            cerr << "\npreprocessor: the specified output directory "
                 << opts.outdir << " does not exist." << endl;
            return -1;
        }
    }

    // setup paths and filenames
    std::string inputdir  = EnsureTrailingPathSep(opts.indir);
    std::string infile = inputdir + std::string("matrix.mtx");
    std::string indict = inputdir + std::string("dictionary.txt");
    std::string indocs = inputdir + std::string("documents.txt");

    std::string outputdir, outfile, outdict, outdocs;
    if (!opts.outdir.empty())
    {
        outputdir = EnsureTrailingPathSep(opts.outdir);
        outfile = outputdir + std::string("reduced_matrix.mtx");
        outdict = outputdir + std::string("reduced_dictionary.txt");
        outdocs = outputdir + std::string("reduced_documents.txt");
    }
    else
    {
        outfile = std::string("reduced_matrix.mtx");
        outdict = std::string("reduced_dictionary.txt");
        outdocs = std::string("reduced_documents.txt");
    }

    //
    // load the input dictionary and documents
    //
    std::vector<std::string> dictionary, documents;

    if (!LoadStringsFromFile(indict, dictionary))
    {
        cerr << "\npreprocessor: could not open dictionary file " 
             << indict << endl;
        return -1;
    }
    
    unsigned int num_terms = dictionary.size();

    if (!LoadStringsFromFile(indocs, documents))
    {
        cerr << "\npreprocessor: could not open documents file "
             << indocs << endl;
        return -1;
    }

    unsigned int num_docs = documents.size();

    // print options to screen prior to run
    opts.indir = inputdir;
    if (outputdir.empty())
        opts.outdir = std::string("current directory");
    else
        opts.outdir = outputdir;
    PrintOpts(opts);

    bool boolean_mode = (0 != opts.boolean_mode);
    
    SparseMatrix<double> A;
    unsigned int height, width, nonzeros;

    //
    // load the input matrix
    //

    cout << "Loading input matrix " << infile << endl;
    timer.Start();
    if (!LoadMatrixMarketFile(infile, A, height, width, nonzeros))
    {
        cerr << "\npreprocessor: could not load file " << infile << endl;
        return -1;
    }
    timer.Stop();
    elapsed_s = static_cast<double>(timer.ReportMilliseconds() * 0.001);
    cout << "\tInput file load time: " << elapsed_s << "s." << endl;

    //
    // check num_terms and num_docs
    //

    if (num_terms < A.Height())
    {
        cerr << "\npreprocessor error: expected " << A.Height() 
             << " terms in the dictionary; found " << num_terms << "." << endl;
        return -1;
    }

    if (num_docs < A.Width())
    {
        cerr << "\npreprocessor error: expected " << A.Width()
             << " strings in the documents file; found " << num_docs
             << "." << endl;
        return -1;
    }

    //
    // do the preprocessing
    //

    timer.Start();

    TermFrequencyMatrix  M(A, boolean_mode);

    // allocate the index sets for the terms and docs
    std::vector<unsigned int> term_indices(height);
    std::vector<unsigned int> doc_indices(width);
    std::vector<double> scores;
  
    bool ok = preprocess_tf(M, term_indices, doc_indices, scores,
                            opts.max_iter, opts.docs_per_term, opts.terms_per_doc);
    timer.Stop();
    elapsed_s = static_cast<double>(timer.ReportMilliseconds() * 0.001);
    cout << "Processing time: " << elapsed_s << "s." << endl;
    cout << endl;

    if (!ok)
    {
        cerr << "\npreprocessor: matrix has dimension zero." << endl;
        cerr << "no output files will be written" << endl;
        return false;
    }

    //
    // write the result matrix to disk
    //

    cout << "Writing output matrix " << outfile << endl;
    timer.Start();
    if (!M.WriteMtxFile(outfile, &scores[0], opts.precision))
    {
        cerr << "\npreprocessor: could not write file " 
             << outfile << endl;
        return -1;
    }
    timer.Stop();
    elapsed_s = static_cast<double>(timer.ReportMilliseconds() * 0.001);
    cout << "Output file write time: " << elapsed_s << "s." << endl;

    //
    // write the reduced dictionary and documents to disk
    //
    cout << "Writing dictionary file " << outdict << endl;
    timer.Start();
    if (!WriteStringsToFile(outdict, dictionary, term_indices, M.Height()))
    {
        cerr << "\npreprocessor: could not write file "
             << outdict << endl;
    }
    timer.Stop();
    elapsed_s = static_cast<double>(timer.ReportMilliseconds() * 0.001);
    
    cout << "Writing documents file " << outdocs << endl;
    timer.Start();
    if (!WriteStringsToFile(outdocs, documents, doc_indices, M.Width()))
    {
        cerr << "\npreprocessor: could not write file "
             << outdocs << endl;
    }
    timer.Stop();
    elapsed_s += static_cast<double>(timer.ReportMilliseconds() * 0.001);
    cout << "Dictionary + documents write time: " << elapsed_s << "s." << endl;    

    return 0;
}
Ejemplo n.º 23
0
Archivo: Solver.cpp Proyecto: 93i/godot
/** Bi-conjugate gradient stabilized method. */
int BiCGSTABPrecondSolve( const SparseMatrix &A, const DenseVector &b, DenseVector &x, const IPreconditioner &M, float epsilon ) {
    piDebugCheck( A.IsSquare() );
    piDebugCheck( A.Width() == b.Dim() );
    piDebugCheck( A.Width() == x.Dim() );

    int i = 0;
    const int D = A.Width();
    const int i_max = D;
    //	const int i_max = 1000;


    float resid;
    float rho_1 = 0;
    float rho_2 = 0;
    float alpha = 0;
    float beta = 0;
    float omega = 0;

    DenseVector p(D);
    DenseVector phat(D);
    DenseVector s(D);
    DenseVector shat(D);
    DenseVector t(D);
    DenseVector v(D);

    DenseVector r(D);
    DenseVector rtilde(D);

    DenseVector tmp(D);

    // r = b - A·x;
    A.Product( x, tmp );
    r.Sub( b, tmp );

    // rtilde = r
    rtilde.Set( r );


    float normb = b.Norm();
    if( normb == 0.0 ) normb = 1;

    // test convergence
    resid = r.Norm() / normb;
    if( resid < epsilon ) {
        // method converges?
        return 0;
    }


    while( i<i_max ) {

        i++;

        rho_1 = DenseVectorDotProduct( rtilde, r );
        if( rho_1 == 0 ) {
            // method fails
            return -i;
        }


        if( i == 1 ) {
            p.Set( r );
        }
        else {
            beta = (rho_1 / rho_2) * (alpha / omega);

            // p = r + beta * (p - omega * v);
            p.Mad( p, v, -omega );
            p.Mad( r, p, beta );
        }

        //phat = M.solve(p);
        //phat.Set( p );
        M.Precond( &phat, p );

        //v = A * phat;
        A.Product( phat, v );

        alpha = rho_1 / DenseVectorDotProduct( rtilde, v );

        // s = r - alpha * v;
        s.Mad( r, v, -alpha );


        resid = s.Norm() / normb;

        //printf( "--- Iteration %d: residual = %f\n", i, resid );

        if( resid < epsilon ) {
            // x += alpha * phat;
            x.Mad( x, phat, alpha );
            return i;
        }

        //shat = M.solve(s);
        //shat.Set( s );
        M.Precond( &shat, s );

        //t = A * shat;
        A.Product( shat, t );

        omega = DenseVectorDotProduct( t, s ) / DenseVectorDotProduct( t, t );

        // x += alpha * phat + omega * shat;
        x.Mad( x, shat, omega );
        x.Mad( x, phat, alpha );

        //r = s - omega * t;
        r.Mad( s, t, -omega );

        rho_2 = rho_1;

        resid = r.Norm() / normb;
        if( resid < epsilon ) {
            return i;
        }

        if( omega == 0 ) {
            return -i;	// ???
        }
    }

    return i;
}
Ejemplo n.º 24
0
void RLS
( const SparseMatrix<Real>& A, 
  const Matrix<Real>& b, 
        Real rho,
        Matrix<Real>& x, 
  const socp::affine::Ctrl<Real>& ctrl )
{
    DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();

    Matrix<Int> orders, firstInds;
    Zeros( orders, m+n+3, 1 );
    Zeros( firstInds, m+n+3, 1 );
    for( Int i=0; i<m+1; ++i )
    {
        orders.Set( i, 0, m+1 );
        firstInds.Set( i, 0, 0 );
    }
    for( Int i=0; i<n+2; ++i )
    {
        orders.Set( i+m+1, 0, n+2 ); 
        firstInds.Set( i+m+1, 0, m+1 );
    }

    // G := | -1  0  0 |
    //      |  0  0  A |
    //      |  0 -1  0 |
    //      |  0  0 -I |
    //      |  0  0  0 |
    SparseMatrix<Real> G;
    {
        const Int numEntriesA = A.NumEntries();
        Zeros( G, m+n+3, n+2 );
        G.Reserve( numEntriesA+n+2 );
        G.QueueUpdate( 0, 0, -1 );
        for( Int e=0; e<numEntriesA; ++e )
            G.QueueUpdate( A.Row(e)+1, A.Col(e)+2, A.Value(e) );
        G.QueueUpdate( m+1, 1, -1 );
        for( Int j=0; j<n; ++j )
            G.QueueUpdate( j+m+2, j+2, -1 );
        G.ProcessQueues();
    }

    // h := | 0 |
    //      | b |
    //      | 0 |
    //      | 0 |
    //      | 1 |
    Matrix<Real> h;
    Zeros( h, m+n+3, 1 ); 
    auto hb = h( IR(1,m+1), ALL );
    hb = b;
    h.Set( END, 0, 1 );

    // c := [1; rho; 0]
    Matrix<Real> c;
    Zeros( c, n+2, 1 );
    c.Set( 0, 0, 1 );
    c.Set( 1, 0, rho );

    SparseMatrix<Real> AHat;
    Zeros( AHat, 0, n+2 );
    Matrix<Real> bHat;
    Zeros( bHat, 0, 1 );

    Matrix<Real> xHat, y, z, s;
    SOCP( AHat, G, bHat, c, h, orders, firstInds, xHat, y, z, s, ctrl );
    x = xHat( IR(2,END), ALL );
}
Ejemplo n.º 25
0
void IPM
( const SparseMatrix<Real>& A,
  const Matrix<Real>& d,
        Real lambda,
        Matrix<Real>& x,
  const qp::affine::Ctrl<Real>& ctrl )
{
    EL_DEBUG_CSE
    const Int m = A.Height();
    const Int n = A.Width();
    const Range<Int> wInd(0,n), betaInd(n,n+1), zInd(n+1,n+m+1);

    SparseMatrix<Real> Q, AHat, G;
    Matrix<Real> c, b, h;

    // Q := | I 0 0 |
    //      | 0 0 0 |
    //      | 0 0 0 |
    // ==============
    Zeros( Q, n+m+1, n+m+1 );
    Q.Reserve( n );
    for( Int e=0; e<n; ++e )
        Q.QueueUpdate( e, e, Real(1) );
    Q.ProcessQueues();

    // c := [0;0;lambda]
    // =================
    Zeros( c, n+m+1, 1 );
    auto cz = c( zInd, ALL );
    Fill( cz, lambda );

    // AHat = []
    // =========
    Zeros( AHat, 0, n+m+1 );

    // b = []
    // ======
    Zeros( b, 0, 1 );

    // G := |-diag(d) A, -d, -I|
    //      |      0,     0, -I|
    // =========================
    Zeros( G, 2*m, n+m+1 );
    const Int numEntriesA = A.NumEntries();
    G.Reserve( numEntriesA+3*m );
    for( Int e=0; e<numEntriesA; ++e )
        G.QueueUpdate( A.Row(e), A.Col(e), -d(A.Row(e))*A.Value(e) );
    for( Int e=0; e<m; ++e )
        G.QueueUpdate( e, n, -d(e) );
    for( Int e=0; e<m; ++e )
    {
        G.QueueUpdate( e,   e+n+1, Real(-1) );
        G.QueueUpdate( e+m, e+n+1, Real(-1) );
    }
    G.ProcessQueues();

    // h := [-ones(m,1); zeros(m,1)]
    // =============================
    Zeros( h, 2*m, 1 );
    auto h0 = h( IR(0,m), ALL );
    Fill( h0, Real(-1) );

    // Solve the affine QP
    // ===================
    Matrix<Real> y, z, s;
    QP( Q, AHat, G, b, c, h, x, y, z, s, ctrl );
}