void SiconosVector::toBlock(SiconosVector& vOut, unsigned int sizeB, unsigned int startIn, unsigned int startOut) const { // To copy a subBlock of the vector (from position startIn to startIn+sizeB) into vOut (from pos. startOut to startOut+sizeB). // Check dim ... assert(startIn < size() && "vector toBlock(v1,v2,...): start position in input vector is out of range."); assert(startOut < vOut.size() && "vector toBlock(v1,v2,...): start position in output vector is out of range."); assert(startIn + sizeB <= size() && "vector toBlock(v1,v2,...): end position in input vector is out of range."); assert(startOut + sizeB <= vOut.size() && "vector toBlock(v1,v2,...): end position in output vector is out of range."); unsigned int endOut = startOut + sizeB; unsigned int numIn = num(); unsigned int numOut = vOut.num(); if (numIn == numOut) { if (numIn == 1) // vIn / vOut are Dense noalias(ublas::subrange(*vOut.dense(), startOut, endOut)) = ublas::subrange(*vect.Dense, startIn, startIn + sizeB); else // if(numIn == 4)// vIn / vOut are Sparse noalias(ublas::subrange(*vOut.sparse(), startOut, endOut)) = ublas::subrange(*vect.Sparse, startIn, startIn + sizeB); } else // vIn and vout of different types ... { if (numIn == 1) // vIn Dense noalias(ublas::subrange(*vOut.sparse(), startOut, endOut)) = ublas::subrange(*vect.Dense, startIn, startIn + sizeB); else // if(numIn == 4)// vIn Sparse noalias(ublas::subrange(*vOut.dense(), startOut, endOut)) = ublas::subrange(*vect.Sparse, startIn, startIn + sizeB); } }
void SiconosVector::subBlock(unsigned int index, const SiconosVector& vIn) { // Add vIn from the current vector, starting from position "index". // vIn may be a BlockVector. // if ( num != 1 ) SiconosVectorException::selfThrow("SiconosVector::subBlock : vector should be dense"); unsigned int end = vIn.size(); if ((index + end) > size()) SiconosVectorException::selfThrow("SiconosVector::subBlock : invalid ranges"); unsigned int numVin = vIn.num(); if (numVin != num()) SiconosVectorException::selfThrow("SiconosVector::subBlock : inconsistent types."); if (_dense) noalias(ublas::subrange(*vect.Dense, index, index + end)) -= *vIn.dense(); else noalias(ublas::subrange(*vect.Sparse, index, index + end)) -= *vIn.sparse(); }
void SiconosVector::setBlock(unsigned int index, const SiconosVector& vIn) { // Set current vector elements, starting from position "index", to the values of vector vIn // Exceptions ... assert(&vIn != this && "SiconosVector::this->setBlock(pos,vIn): vIn = this."); assert(index < size() && "SiconosVector::setBlock : invalid ranges"); unsigned int end = vIn.size() + index; assert(end <= size() && "SiconosVector::setBlock : invalid ranges"); assert (vIn.num() == num() && "SiconosVector::setBlock: inconsistent types."); if (_dense) noalias(ublas::subrange(*vect.Dense, index, end)) = *vIn.dense(); else noalias(ublas::subrange(*vect.Sparse, index, end)) = *vIn.sparse(); }
// Copy SiconosVector::SiconosVector(const SiconosVector &svect) : std11::enable_shared_from_this<SiconosVector>() { if (ask<IsDense>(svect)) // dense { _dense = true; vect.Dense = new DenseVect(svect.size()); noalias(*vect.Dense) = (*svect.dense()); // std::copy((vect.Dense)->begin(), (vect.Dense)->end(), (svect.dense())->begin()); } else //sparse { _dense = false; vect.Sparse = new SparseVect(svect.size()); noalias(*vect.Sparse) = (*svect.sparse()); //std::copy((vect.Sparse)->begin(), (vect.Sparse)->end(), (svect.sparse())->begin()); } // Note FP: using constructor + noalias = (or std::copy) is more // efficient than a call to ublas::vector copy constructor, this for // large or small vectors. }
void private_addprod(const SiconosMatrix& A, unsigned startRow, unsigned int startCol, const SiconosVector& x, SiconosVector& y) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); assert(!A.isBlock() && "private_addprod(A,start,x,y) error: not yet implemented for block matrix."); // we take a submatrix subA of A, starting from row startRow to row (startRow+sizeY) and between columns startCol and (startCol+sizeX). // Then computation of y = subA*x + y. unsigned int numA = A.getNum(); unsigned int numY = y.getNum(); unsigned int numX = x.getNum(); unsigned int sizeX = x.size(); unsigned int sizeY = y.size(); assert(numX == numY && "private_addprod(A,start,x,y) error: not yet implemented for x and y of different types."); if (numY == 1 && numX == 1) { assert(y.dense() != x.dense()); if (numA == 1) noalias(*y.dense()) += prod(ublas::subrange(*A.dense(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 2) noalias(*y.dense()) += prod(ublas::subrange(*A.triang(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 3) noalias(*y.dense()) += prod(ublas::subrange(*A.sym(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 4) noalias(*y.dense()) += prod(ublas::subrange(*A.sparse(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else //if(numA==5) noalias(*y.dense()) += prod(ublas::subrange(*A.banded(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); } else // x and y sparse { if (numA == 4) *y.sparse() += prod(ublas::subrange(*A.sparse(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.sparse()); else SiconosMatrixException::selfThrow("private_addprod(A,start,x,y) error: not yet implemented for x, y sparse and A not sparse."); } }