Esempio n. 1
0
inline void
MakeLegendre( Matrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("MakeLegendre");
#endif
    if( A.Height() != A.Width() )
        LogicError("Cannot make a non-square matrix Legendre");
    MakeZeros( A );

    const Int n = A.Width();
    for( Int j=0; j<n-1; ++j )
    {
        const F gamma = F(1) / Pow( F(2)*(j+1), F(2) );
        const F beta = F(1) / (2*Sqrt(F(1)-gamma));
        A.Set( j+1, j, beta );
        A.Set( j, j+1, beta );
    }
}
Esempio n. 2
0
void
Ledger::rawTxInsert (uint256 const& key,
                     std::shared_ptr<Serializer const
                     > const& txn, std::shared_ptr<
                     Serializer const> const& metaData)
{
    assert (metaData);

    // low-level - just add to table
    Serializer s(txn->getDataLength () +
                 metaData->getDataLength () + 16);
    s.addVL (txn->peekData ());
    s.addVL (metaData->peekData ());
    auto item = std::make_shared<
                SHAMapItem const> (key, std::move(s));
    if (! txMap().addGiveItem
            (std::move(item), true, true))
        LogicError("duplicate_tx: " + to_string(key));
}
void CharPolyMod(ZZ_pX& g, const ZZ_pX& a, const ZZ_pX& ff)
{
   ZZ_pX f = ff;
   MakeMonic(f);
   long n = deg(f);

   if (n <= 0 || deg(a) >= n) 
      LogicError("CharPoly: bad args");

   if (IsZero(a)) {
      clear(g);
      SetCoeff(g, n);
      return;
   }

   if (n > 25) {
      ZZ_pX h;
      MinPolyMod(h, a, f);
      if (deg(h) == n) {
         g = h;
         return;
      }
   }

   if (ZZ_p::modulus() < n+1) {
      HessCharPoly(g, a, f);
      return;
   }

   vec_ZZ_p u(INIT_SIZE, n+1), v(INIT_SIZE, n+1);

   ZZ_pX h, h1;
   negate(h, a);
   long i;

   for (i = 0; i <= n; i++) {
      u[i] = i;
      add(h1, h, u[i]);
      resultant(v[i], f, h1);
   }

   interpolate(g, u, v);
}
Esempio n. 4
0
inline LDLPivot
SelectFromPanel
( const Matrix<F>& A,
  const Matrix<F>& X,
  const Matrix<F>& Y, 
  LDLPivotType pivotType,
  Base<F> gamma )
{
    DEBUG_CSE
    LDLPivot pivot;
    switch( pivotType )
    {
    case BUNCH_KAUFMAN_A: 
    case BUNCH_KAUFMAN_C: pivot = PanelBunchKaufmanA( A, X, Y, gamma ); break;
    case BUNCH_KAUFMAN_D: pivot = PanelBunchKaufmanD( A, X, Y, gamma ); break;
    default: LogicError("This pivot type not yet supported");
    }
    return pivot;
}
Esempio n. 5
0
// get path of current executable
/*static*/ wstring File::GetExecutablePath()
{
#ifdef WIN32
    wchar_t path[33000];
    if (GetModuleFileNameW(NULL, path, _countof(path)) == 0)
        LogicError("GetExecutablePath: GetModuleFileNameW() unexpectedly failed.");
    return path;
#else
    // from http://stackoverflow.com/questions/4025370/can-an-executable-discover-its-own-path-linux
    pid_t pid = getpid();
    char path[PATH_MAX + 1] = { 0 };
    sprintf(path, "/proc/%d/exe", pid);
    char dest[PATH_MAX + 1] = { 0 };
    if (readlink(path, dest, PATH_MAX) == -1)
        RuntimeError("GetExecutableDirectory: readlink() call failed.");
    else
        return msra::strfun::utf16(dest);
#endif
}
void EDF(vec_ZZ_pEX& factors, const ZZ_pEX& ff, const ZZ_pEX& bb,
         long d, long verbose)

{
   ZZ_pEX f = ff;
   ZZ_pEX b = bb;

   if (!IsOne(LeadCoeff(f)))
      LogicError("EDF: bad args");

   long n = deg(f);
   long r = n/d;

   if (r == 0) {
      factors.SetLength(0);
      return;
   }

   if (r == 1) {
      factors.SetLength(1);
      factors[0] = f;
      return;
   }

   if (d == 1) {
      RootEDF(factors, f, verbose);
      return;
   }

   
   double t;
   if (verbose) { 
      cerr << "computing EDF(" << d << "," << r << ")..."; 
      t = GetTime(); 
   }

   factors.SetLength(0);

   RecEDF(factors, f, b, d, verbose);

   if (verbose) cerr << (GetTime()-t) << "\n";
}
void FastTraceVec(vec_ZZ_p& S, const ZZ_pX& f)
{
   long n = deg(f);

   if (n <= 0) 
      LogicError("FastTraceVec: bad args");

   if (n == 0) {
      S.SetLength(0);
      return;
   }

   if (n == 1) {
      S.SetLength(1);
      set(S[0]);
      return;
   }
   
   long i;
   ZZ_pX f1;

   f1.rep.SetLength(n-1);
   for (i = 0; i <= n-2; i++)
      f1.rep[i] = f.rep[n-i];
   f1.normalize();

   ZZ_pX f2;
   f2.rep.SetLength(n-1);
   for (i = 0; i <= n-2; i++)
      mul(f2.rep[i], f.rep[n-1-i], i+1);
   f2.normalize();

   ZZ_pX f3;
   InvTrunc(f3, f1, n-1);
   MulTrunc(f3, f3, f2, n-1);

   S.SetLength(n);

   S[0] = n;
   for (i = 1; i < n; i++)
      negate(S[i], coeff(f3, i-1));
}
Esempio n. 8
0
void plain_mul_transpose_aux(mat_ZZ_p& X, const mat_ZZ_p& A, const mat_ZZ_p& B)  
{  
   long n = A.NumRows();  
   long l = A.NumCols();  
   long m = B.NumRows();  
  
   if (l != B.NumCols())  
      LogicError("matrix mul: dimension mismatch");  
  
   X.SetDims(n, m);  

   ZZ_pContext context;
   context.save();

   long sz = ZZ_p::ModulusSize();
   bool seq = (double(n)*double(l)*double(m)*double(sz)*double(sz) < PAR_THRESH);
  
   NTL_GEXEC_RANGE(seq, m, first, last)
   NTL_IMPORT(n)
   NTL_IMPORT(l)
   NTL_IMPORT(m)

   context.restore();

   long i, j, k;  
   ZZ acc, tmp;  

   for (j = first; j < last; j++) {
      const ZZ_p *B_col = B[j].elts();

      for (i = 0; i < n; i++) {
         clear(acc);
         for (k = 0; k < l; k++) {
            mul(tmp, rep(A[i][k]), rep(B_col[k]));
            add(acc, acc, tmp);
         }
         conv(X[i][j], acc);
      }
   }

   NTL_GEXEC_RANGE_END
}  
Esempio n. 9
0
inline void
DistNodalMultiVec<F>::Pull
( const DistMap& inverseMap, const DistSymmInfo& info,
  const DistMultiVec<F>& X )
{
    DEBUG_ONLY(CallStackEntry cse("DistNodalMultiVec::Pull"))
    height_ = X.Height();
    width_ = X.Width();

    // Traverse our part of the elimination tree to see how many indices we need
    int numRecvInds=0;
    const int numLocal = info.localNodes.size();
    for( int s=0; s<numLocal; ++s )
        numRecvInds += info.localNodes[s].size;
    const int numDist = info.distNodes.size();
    for( int s=1; s<numDist; ++s )
        numRecvInds += info.distNodes[s].multiVecMeta.localSize;
    
    // Fill the set of indices that we need to map to the original ordering
    int off=0;
    std::vector<int> mappedInds( numRecvInds );
    for( int s=0; s<numLocal; ++s )
    {
        const SymmNodeInfo& nodeInfo = info.localNodes[s];
        for( int t=0; t<nodeInfo.size; ++t )
            mappedInds[off++] = nodeInfo.off+t;
    }
    for( int s=1; s<numDist; ++s )
    {
        const DistSymmNodeInfo& nodeInfo = info.distNodes[s];
        const Grid& grid = *nodeInfo.grid;
        const int gridSize = grid.Size();
        const int gridRank = grid.VCRank();
        const int alignment = 0;
        const int shift = Shift( gridRank, alignment, gridSize );
        for( int t=shift; t<nodeInfo.size; t+=gridSize )
            mappedInds[off++] = nodeInfo.off+t;
    }
    DEBUG_ONLY(
        if( off != numRecvInds )
            LogicError("mappedInds was filled incorrectly");
    )
Esempio n. 10
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 );
}
void BuildIrred(ZZ_pEX& f, long n)
{
   if (n <= 0)
      LogicError("BuildIrred: n must be positive");

   if (n == 1) {
      SetX(f);
      return;
   }

   ZZ_pEX g;

   do {
      random(g, n);
      SetCoeff(g, n);
   } while (!IterIrredTest(g));

   f = g;

}
Esempio n. 12
0
XmlDomElement* FootprintPad::serializeToXmlDomElement() const throw (Exception)
{
    if (!checkAttributesValidity()) throw LogicError(__FILE__, __LINE__);

    QScopedPointer<XmlDomElement> root(new XmlDomElement("pad"));
    root->setAttribute("uuid", mUuid);
    root->setAttribute("type", typeToString(mType));
    root->setAttribute("x", mPosition.getX().toMmString());
    root->setAttribute("y", mPosition.getY().toMmString());
    root->setAttribute("rotation", mRotation);
    root->setAttribute("width", mWidth);
    root->setAttribute("height", mHeight);
    root->setAttribute("drill", mDrillDiameter);
    root->setAttribute("layer", mLayerId);
    foreach (const QString& locale, mNames.keys())
        root->appendTextChild("name", mNames.value(locale))->setAttribute("locale", locale);
    foreach (const QString& locale, mDescriptions.keys())
        root->appendTextChild("description", mDescriptions.value(locale))->setAttribute("locale", locale);
    return root.take();
}
Esempio n. 13
0
void UndoStack::abortCommand() throw (Exception)
{
    Q_ASSERT(mCurrentIndex == mCommands.count());

    if (!mCommandActive)
        throw LogicError(__FILE__, __LINE__, QString(), tr("No command active!"));

    mCommands.last()->undo(); // throws an exception on error
    mCurrentIndex--;
    mCommandActive = false;
    delete mCommands.takeLast(); // delete and remove the aborted command from the stack

    // emit signals
    emit undoTextChanged(getUndoText());
    emit redoTextChanged(tr("Redo"));
    emit canUndoChanged(canUndo());
    emit canRedoChanged(false);
    emit cleanChanged(isClean());
    emit commandAborted(); // this is important!
}
Esempio n. 14
0
Base<F> LanczosDecomp
( const DistSparseMatrix<F>& A,
        DistMultiVec<F>& V, 
        ElementalMatrix<Base<F>>& T,
        DistMultiVec<F>& v,
        Int basisSize )
{
    DEBUG_CSE
    const Int n = A.Height();
    if( n != A.Width() )
        LogicError("A was not square");

    auto applyA =
      [&]( const DistMultiVec<F>& X, DistMultiVec<F>& Y )
      {
          Zeros( Y, n, X.Width() );
          Multiply( NORMAL, F(1), A, X, F(0), Y );
      };
    return LanczosDecomp( n, applyA, V, T, v, basisSize );
}
Esempio n. 15
0
void ComponentSignalInstance::init() throw (Exception)
{
    // create ERC messages
    mErcMsgUnconnectedRequiredSignal.reset(new ErcMsg(mCircuit.getProject(), *this,
        QString("%1/%2").arg(mComponentInstance.getUuid().toStr()).arg(mComponentSignal->getUuid().toStr()),
        "UnconnectedRequiredSignal", ErcMsg::ErcMsgType_t::CircuitError, QString()));
    mErcMsgForcedNetSignalNameConflict.reset(new ErcMsg(mCircuit.getProject(), *this,
        QString("%1/%2").arg(mComponentInstance.getUuid().toStr()).arg(mComponentSignal->getUuid().toStr()),
        "ForcedNetSignalNameConflict", ErcMsg::ErcMsgType_t::SchematicError, QString()));
    updateErcMessages();

    // register to component attributes changed
    connect(&mComponentInstance, &ComponentInstance::attributesChanged,
            this, &ComponentSignalInstance::updateErcMessages);

    // register to net signal name changed
    if (mNetSignal) connect(mNetSignal, &NetSignal::nameChanged, this, &ComponentSignalInstance::netSignalNameChanged);

    if (!checkAttributesValidity()) throw LogicError(__FILE__, __LINE__);
}
Esempio n. 16
0
inline void
MakeGKS( Matrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("MakeGKS");
#endif
    const Int m = A.Height();
    const Int n = A.Width();
    if( m != n )
        LogicError("Cannot make a non-square matrix GKS");

    MakeZeros( A );
    for( Int j=0; j<n; ++j )
    {
        const F jDiag = F(1)/Sqrt(F(j));
        for( Int i=0; i<j; ++i )
            A.Set( i, j, -jDiag );
        A.Set( j, j, jDiag );
    }
}
Esempio n. 17
0
inline 
Grid::Grid( mpi::Comm comm, int height, GridOrder order )
: haveViewers_(false), order_(order)
{
    DEBUG_ONLY(CallStackEntry cse("Grid::Grid"))

    // Extract our rank, the underlying group, and the number of processes
    mpi::Dup( comm, viewingComm_ );
    mpi::CommGroup( viewingComm_, viewingGroup_ );
    size_ = mpi::Size( viewingComm_ );

    // All processes own the grid, so we have to trivially split viewingGroup_
    owningGroup_ = viewingGroup_;

    height_ = height;
    if( height_ < 0 )
        LogicError("Process grid dimensions must be non-negative");

    SetUpGrid();
}
Esempio n. 18
0
void InnerProduct(ZZ_p& x, const vec_ZZ_p& a, const vec_ZZ_p& b,
                  long offset)
{
    if (offset < 0) LogicError("InnerProduct: negative offset");
    if (NTL_OVERFLOW(offset, 1, 0))
        ResourceError("InnerProduct: offset too big");

    long n = min(a.length(), b.length()+offset);
    long i;
    NTL_ZZRegister(accum);
    NTL_ZZRegister(t);

    clear(accum);
    for (i = offset; i < n; i++) {
        mul(t, rep(a[i]), rep(b[i-offset]));
        add(accum, accum, t);
    }

    conv(x, accum);
}
Esempio n. 19
0
void UndoStack::endCommand() throw (Exception)
{
    Q_ASSERT(mCurrentIndex == mCommands.count());

    if (!mCommandActive)
        throw LogicError(__FILE__, __LINE__, QString(), tr("No command active!"));

    if (mCommands.last()->getChildCount() == 0)
    {
        // the last command is empty --> remove it from the stack!
        abortCommand();
        return;
    }

    mCommandActive = false;

    // emit signals
    emit canUndoChanged(canUndo());
    emit commandEnded();
}
Esempio n. 20
0
void CompositeDataReader::StartEpoch(const EpochConfiguration& cfg)
{
    EpochConfiguration config = cfg;

    if (config.m_totalEpochSizeInSamples <= 0)
    {
        RuntimeError("Unsupported Epoch size '%d'.", (int)config.m_totalEpochSizeInSamples);
    }

    m_sequenceEnumerator->StartEpoch(config);

    // TODO: As the next step the packers should be moved into the network.
    switch (m_packingMode)
    {
    case PackingMode::sample:
        m_packer = std::make_shared<FramePacker>(
            m_provider,
            m_sequenceEnumerator,
            m_streams);
        break;
    case PackingMode::sequence:
        m_packer = std::make_shared<SequencePacker>(
            m_provider,
            m_sequenceEnumerator,
            m_streams);
        break;
    case PackingMode::truncated:
    {
        config.m_truncationSize = m_truncationLength;
        m_packer = std::make_shared<TruncatedBPTTPacker>(
            m_provider,
            m_sequenceEnumerator,
            m_streams);
        break;
    }
    default:
        LogicError("Unsupported type of packer '%d'.", (int)m_packingMode);
    }

    m_packer->StartEpoch(config);
}
void PowerCompose(ZZ_pEX& y, const ZZ_pEX& h, long q, const ZZ_pEXModulus& F)
{
   if (q < 0) LogicError("PowerCompose: bad args");

   ZZ_pEX z(INIT_SIZE, F.n);
   long sw;

   z = h;
   SetX(y);

   while (q) {
      sw = 0;

      if (q > 1) sw = 2;
      if (q & 1) {
         if (IsX(y))
            y = z;
         else
            sw = sw | 1;
      }

      switch (sw) {
      case 0:
         break;

      case 1:
         CompMod(y, y, z, F);
         break;

      case 2:
         CompMod(z, z, z, F);
         break;

      case 3:
         Comp2Mod(y, z, y, z, z, F);
         break;
      }

      q = q >> 1;
   }
}
Esempio n. 22
0
void ComponentSignalInstance::setNetSignal(NetSignal* netsignal) throw (Exception)
{
    if (!mAddedToCircuit)
        throw LogicError(__FILE__, __LINE__);

    if (mNetSignal)
    {
        disconnect(mNetSignal, &NetSignal::nameChanged, this, &ComponentSignalInstance::netSignalNameChanged);
        mNetSignal->unregisterComponentSignal(*this);
    }

    mNetSignal = netsignal;

    if (mNetSignal)
    {
        mNetSignal->registerComponentSignal(*this);
        connect(mNetSignal, &NetSignal::nameChanged, this, &ComponentSignalInstance::netSignalNameChanged);
    }

    updateErcMessages();
}
Esempio n. 23
0
void DirectoryLock::tryLock(bool* wasStale) {
  LockStatus status = getStatus();  // can throw
  if (wasStale) {
    *wasStale = (status == LockStatus::StaleLock);
  }
  switch (status) {
    case LockStatus::Unlocked:
    case LockStatus::StaleLock:
      lock();  // can throw
      break;
    case LockStatus::Locked:
      throw RuntimeError(
          __FILE__, __LINE__,
          QString(tr("The directory is locked, "
                     "check if it is already opened elsewhere: %1"))
              .arg(mDirToLock.toNative()));
    default:
      Q_ASSERT(false);
      throw LogicError(__FILE__, __LINE__);
  }
}
Esempio n. 24
0
void MultiShiftTrsm
( LeftOrRight side,
  UpperOrLower uplo,
  Orientation orientation,
  F alpha,
  const ElementalMatrix<F>& U,
  const ElementalMatrix<F>& shifts, 
        ElementalMatrix<F>& X )
{
    DEBUG_ONLY(CSE cse("MultiShiftTrsm"))
    X *= alpha;
    if( side == LEFT && uplo == UPPER )
    {
        if( orientation == NORMAL )
            mstrsm::LUN( U, shifts, X );
        else
            mstrsm::LUT( orientation, U, shifts, X );
    }
    else
        LogicError("This option is not yet supported");
}
Esempio n. 25
0
void MultiShiftTrsm
( LeftOrRight side,
  UpperOrLower uplo,
  Orientation orientation,
  F alpha,
  const AbstractDistMatrix<F>& U,
  const AbstractDistMatrix<F>& shifts, 
        AbstractDistMatrix<F>& X )
{
    EL_DEBUG_CSE
    X *= alpha;
    if( side == LEFT && uplo == UPPER )
    {
        if( orientation == NORMAL )
            mstrsm::LUN( U, shifts, X );
        else
            mstrsm::LUT( orientation, U, shifts, X );
    }
    else
        LogicError("This option is not yet supported");
}
Esempio n. 26
0
void NormMod(ZZ_p& x, const ZZ_pX& a, const ZZ_pX& f)
{
   if (deg(f) <= 0 || deg(a) >= deg(f)) 
      LogicError("norm: bad args");

   if (IsZero(a)) {
      clear(x);
      return;
   }

   ZZ_p t;
   resultant(t, f, a);
   if (!IsOne(LeadCoeff(f))) {
      ZZ_p t1;
      power(t1, LeadCoeff(f), deg(a));
      inv(t1, t1);
      mul(t, t, t1);
   }

   x = t;
}
Esempio n. 27
0
void BlockConstructFromObj(ZZ_p* x, long n, const ZZ_p& y)
{
    if (n <= 0) return;


    if (!ZZ_pInfo)
        LogicError("ZZ_p constructor called while modulus undefined");

    long d = ZZ_p::ModulusSize();

    BasicBlockConstruct(x, n, d);

    NTL_SCOPE(guard) {
        BlockDestroy(x, n);
    };

    long i;
    for (i = 0; i < n; i++) x[i] = y;

    guard.relax();
}
Esempio n. 28
0
inline void
LVar2( Matrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("cholesky::LVar2");
    if( A.Height() != A.Width() )
        LogicError("Can only compute Cholesky factor of square matrices");
#endif
    // Matrix views
    Matrix<F> 
        ATL, ATR,   A00, A01, A02,
        ABL, ABR,   A10, A11, A12,
                    A20, A21, A22;

    // Start the algorithm
    PartitionDownDiagonal
    ( A, ATL, ATR,
         ABL, ABR, 0 );
    while( ATL.Height() < A.Height() )
    {
        RepartitionDownDiagonal
        ( ATL, /**/ ATR,  A00, /**/ A01, A02,
         /*************/ /******************/
               /**/       A10, /**/ A11, A12,
          ABL, /**/ ABR,  A20, /**/ A21, A22 );

        //--------------------------------------------------------------------//
        Herk( LOWER, NORMAL, F(-1), A10, F(1), A11 );
        cholesky::LVar3Unb( A11 );
        Gemm( NORMAL, ADJOINT, F(-1), A20, A10, F(1), A21 );
        Trsm( RIGHT, LOWER, ADJOINT, NON_UNIT, F(1), A11, A21 );
        //--------------------------------------------------------------------//

        SlidePartitionDownDiagonal
        ( ATL, /**/ ATR,  A00, A01, /**/ A02,
               /**/       A10, A11, /**/ A12,
         /*************/ /******************/
          ABL, /**/ ABR,  A20, A21, /**/ A22 );
    }
}
Esempio n. 29
0
void LibraryBaseElement::readFromFile() throw (Exception)
{
    Q_ASSERT(mDomTreeParsed == false);

    // check directory
    QUuid dirUuid = QUuid(mDirectory.getFilename());
    if ((!mDirectory.isExistingDir()) || (dirUuid.isNull()))
    {
        throw RuntimeError(__FILE__, __LINE__, dirUuid.toString(),
            QString(tr("Directory does not exist or is not a valid UUID: \"%1\""))
            .arg(mDirectory.toNative()));
    }

    // find the xml file with the highest file version number
    for (int version = APP_VERSION_MAJOR; version >= 0; version--)
    {
        QString filename = QString("v%1/%2.xml").arg(version).arg(mXmlFileNamePrefix);
        mXmlFilepath = mDirectory.getPathTo(filename);
        if (mXmlFilepath.isExistingFile()) break; // file found
    }

    // open XML file
    SmartXmlFile file(mXmlFilepath, false, false);
    QSharedPointer<XmlDomDocument> doc = file.parseFileAndBuildDomTree(true);
    parseDomTree(doc->getRoot());

    // check UUID
    if (mUuid != dirUuid)
    {
        throw RuntimeError(__FILE__, __LINE__,
            QString("%1/%2").arg(mUuid.toString(), dirUuid.toString()),
            QString(tr("UUID mismatch between element directory and XML file: \"%1\""))
            .arg(mXmlFilepath.toNative()));
    }

    // check attributes
    if (!checkAttributesValidity()) throw LogicError(__FILE__, __LINE__);

    Q_ASSERT(mDomTreeParsed == true);
}
Esempio n. 30
0
inline void
UVar3( UnitOrNonUnit diag, Matrix<F>& U )
{
#ifndef RELEASE
    CallStackEntry entry("triangular_inverse::UVar3");
    if( U.Height() != U.Width() )
        LogicError("Nonsquare matrices cannot be triangular");
#endif
    // Matrix views
    Matrix<F> 
        UTL, UTR,  U00, U01, U02,
        UBL, UBR,  U10, U11, U12,
                   U20, U21, U22;

    // Start the algorithm
    PartitionUpDiagonal
    ( U, UTL, UTR,
         UBL, UBR, 0 );
    while( UBR.Height() < U.Height() )
    {
        RepartitionUpDiagonal
        ( UTL, /**/ UTR,  U00, U01, /**/ U02,
               /**/       U10, U11, /**/ U12,
         /*************/ /******************/
          UBL, /**/ UBR,  U20, U21, /**/ U22 );

        //--------------------------------------------------------------------//
        Trsm( RIGHT, UPPER, NORMAL, diag, F(-1), U11, U01 );
        Gemm( NORMAL, NORMAL, F(1), U01, U12, F(1), U02 );
        Trsm( LEFT, UPPER, NORMAL, diag, F(1), U11, U12 );
        UVar3Unb( diag, U11 );
        //--------------------------------------------------------------------//

        SlidePartitionUpDiagonal
        ( UTL, /**/ UTR,  U00, /**/ U01, U02,
         /*************/ /******************/
               /**/       U10, /**/ U11, U12,
          UBL, /**/ UBR,  U20, /**/ U21, U22 );
    }
}