/** matrix_id = astra_mex_projector('matrix', id);
 *
 * Create an explicit projection matrix for this projector.
 * It returns an ID usable with astra_mex_matrix().
 * id: identifier of the projector object as stored in the astra-library.
 */
void astra_mex_projector_matrix(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{ 
	// step1: get input
	if (nrhs < 2) {
		mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
		return;
	}
	int iPid = (int)(mxGetScalar(prhs[1]));

	// step2: get projector
	CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
	if (!pProjector || !pProjector->isInitialized()) {
		mexErrMsgTxt("Projector not initialized.\n");
		return;
	}

	CSparseMatrix* pMatrix = pProjector->getMatrix();
	if (!pMatrix || !pMatrix->isInitialized()) {
		mexErrMsgTxt("Couldn't initialize data object.\n");
		delete pMatrix;
		return;
	}

	// store data object
	int iIndex = CMatrixManager::getSingleton().store(pMatrix);

	// return data id
	if (1 <= nlhs) {
		plhs[0] = mxCreateDoubleScalar(iIndex);
	}
}
/** data = astra_mex_matrix('get', id);
 *
 * Fetch data from the astra-library to a MATLAB matrix.
 * id: identifier of the matrix data object as stored in the astra-library.
 * data: MATLAB
 */
void astra_mex_matrix_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{ 
	// step1: check input
	if (nrhs < 2) {
		mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
		return;
	}
	if (!mxIsDouble(prhs[1])) {
		mexErrMsgTxt("Identifier should be a scalar value. \n");
		return;
	}
	int iDataID = (int)(mxGetScalar(prhs[1]));

	// step2: get data object
	CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID);
	if (!pMatrix || !pMatrix->isInitialized()) {
		mexErrMsgTxt("Data object not found or not initialized properly.\n");
		return;
	}

	// create output
	if (1 <= nlhs) {
		bool bResult = astra_to_matlab(pMatrix, plhs[0]);
		if (!bResult) {
			mexErrMsgTxt("Failed to get matrix.\n");
		}
	}
	
}
예제 #3
0
void CSparseMatrix::multiply_AB(const CSparseMatrix& A, const CSparseMatrix& B)
{
	ASSERT_(A.cols() == B.rows());

	cs* sm = cs_multiply(&(A.sparse_matrix), &(B.sparse_matrix));
	ASSERT_(sm);
	this->copy_fast(sm);
	cs_spfree(sm);
}
예제 #4
0
void CSparseMatrix::add_AB(const CSparseMatrix& A, const CSparseMatrix& B)
{
	ASSERT_(A.cols() == B.cols() && A.rows() == B.rows());

	cs* sm = cs_add(&(A.sparse_matrix), &(B.sparse_matrix), 1, 1);
	ASSERT_(sm);
	this->copy_fast(sm);
	cs_spfree(sm);
}
예제 #5
0
//-------------------------------------------------------------------------------------
HRESULT CIsochartMesh::InitializeLSCMEquation(
    CSparseMatrix<double>& A,
    CVector<double>& B,
    CVector<double>& U,
    uint32_t dwBaseVertId1,
    uint32_t dwBaseVertId2)
{
    HRESULT hr = S_OK;
    CSparseMatrix<double> orgA;
    CSparseMatrix<double> M;
    CVector<double> orgB;

    if (!orgA.resize(2*m_dwFaceNumber, (m_dwVertNumber-2)*2))
    {
        return E_OUTOFMEMORY;
    }
    if (!M.resize(2*m_dwFaceNumber, 2*2))
    {
        return E_OUTOFMEMORY;
    }
    
    for (uint32_t ii=0; ii<m_dwFaceNumber; ii++)
    {
        FAILURE_RETURN(
            AddFaceWeight(ii, orgA, M, dwBaseVertId1, dwBaseVertId2));
    }

    // b = -M*u
    if (!CSparseMatrix<double>::Mat_Mul_Vec(orgB, M, U))
    {
        return E_OUTOFMEMORY;
    }
    assert(orgB.size() == 2*m_dwFaceNumber);
    CVector<double>::scale(orgB, orgB, static_cast<double>(-1));

    // A' = A^T * A
    if (!CSparseMatrix<double>::Mat_Trans_MUL_Mat(A, orgA))
    {
        return E_OUTOFMEMORY;
    }

    // B' = A^T * b
    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(B, orgA, orgB))
    {
        return E_OUTOFMEMORY;
    }
    
    return hr;
}
예제 #6
0
void generateRandomSparseMatrix(size_t N, size_t M, size_t nEntries,  CSparseMatrix &MAT)
{
	MAT.clear();

	MAT.setRowCount(N);
	MAT.setColCount(M);

	for (size_t i=0;i<nEntries;i++)
	{
		MAT.insert_entry( 
			mrpt::random::randomGenerator.drawUniform32bit() % N,
			mrpt::random::randomGenerator.drawUniform32bit() % M,
			mrpt::random::randomGenerator.drawGaussian1D(0,1) );
	}

	// Return already compressed:
	MAT.compressFromTriplet();
}
/** id = astra_mex_matrix('create', data);
 *   
 * Create a new matrix object in the astra-library.
 * data: a sparse MATLAB matrix containing the data.
 * id: identifier of the matrix object as it is now stored in the astra-library.
 */
void astra_mex_matrix_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
{ 
	// step1: get datatype
	if (nrhs < 2) {
		mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
		return;
	}

	if (!mxIsSparse (prhs[1])) {
		mexErrMsgTxt("Argument is not a valid MATLAB sparse matrix.\n");
		return;
	}

	unsigned int iHeight = mxGetM(prhs[1]);
	unsigned int iWidth = mxGetN(prhs[1]);
	unsigned long lSize = mxGetNzmax(prhs[1]);

	CSparseMatrix* pMatrix = new CSparseMatrix(iHeight, iWidth, lSize);

	// Check initialization
	if (!pMatrix->isInitialized()) {
		mexErrMsgTxt("Couldn't initialize data object.\n");
		delete pMatrix;
		return;
	}

	bool bResult = matlab_to_astra(prhs[1], pMatrix);

	if (!bResult) {
		mexErrMsgTxt("Failed to create data object.\n");
		delete pMatrix;
		return;
	}

	// store data object
	int iIndex = CMatrixManager::getSingleton().store(pMatrix);

	// return data id
	if (1 <= nlhs) {
		plhs[0] = mxCreateDoubleScalar(iIndex);
	}
}
예제 #8
0
/** Constructor from a square semidefinite-positive sparse matrix.
 *   The actual Cholesky decomposition takes places in this constructor.
 *  \exception std::runtime_error On non-square input matrix.
 *  \exception mrpt::math::CExceptionNotDefPos On non-semidefinite-positive
 * matrix as input.
 */
CSparseMatrix::CholeskyDecomp::CholeskyDecomp(const CSparseMatrix& SM)
	: m_symbolic_structure(nullptr),
	  m_numeric_structure(nullptr),
	  m_originalSM(&SM)
{
	ASSERT_(SM.cols() == SM.rows());
	ASSERT_(SM.isColumnCompressed());

	// symbolic decomposition:
	m_symbolic_structure =
		cs_schol(1 /* order */, &m_originalSM->sparse_matrix);

	// numeric decomposition:
	m_numeric_structure =
		cs_chol(&m_originalSM->sparse_matrix, m_symbolic_structure);

	if (!m_numeric_structure)
		throw mrpt::math::CExceptionNotDefPos(
			"CSparseMatrix::CholeskyDecomp: Not positive definite matrix.");
}
void CPersistMatrixFlt::Save(CPNLBase *pObj, CContextSave *pContext)
{
    CMatrix<float> *pMat = static_cast<CMatrix<float>*>(pObj);

    MatrixCommonSave<float>(pMat, pContext);
    pnlString buf;
    if(dynamic_cast<CDenseMatrix<float>*>(pMat))
    {
        CDenseMatrix<float> *pDenseMat = static_cast<CDenseMatrix<float>*>(pMat);
        int len;
        const float *pData;

        pDenseMat->GetRawData(&len, &pData);
        SaveArray<float>(buf, pData, len);
    }
    else
    {// Sparse
        CSparseMatrix<float> *pSparseMat = static_cast<CSparseMatrix<float>*>(pMat);
        CMatrixIterator<float> *it = pSparseMat->InitIterator();
        intVector index;

        for(; pSparseMat->IsValueHere(it); pSparseMat->Next(it))
        {
            pSparseMat->Index(it, &index);
            SaveArray<int>(buf, &index.front(), index.size());
            buf << ":" << *pSparseMat->Value(it) << '\n';
        }

        delete it;
    }

    pContext->AddText(buf.c_str());
}
예제 #10
0
int main()
{
  CSparseMatrix A;
  Trituple t;
  unsigned int rows;
  unsigned int cols;
  fstream infile;
  infile.open("data.dat",fstream::in);

  if(!infile)
    {
      cerr<<"error:unable to open input file:"
          <<endl;
      return -1;
    }
  infile>>rows>>cols;
  //  cout<<"begin read data"<<endl;
  unsigned int r;
  unsigned int c;
  double v;
  do{
    infile>>r>>c>>v;
    t.set_value3(r,c,v);
    A.insert_data(r,c,v);
    //   cout<<"succefully!"<<endl;
  }while(!infile.eof());
  infile.close();
  cout<<"the matrix A's cell is "<<endl;
  A.matrixPrint();
  CSparseMatrix B = A.Minus();
  cout<<"the matrix B's cell is"<<endl;
  B.matrixPrint();
  B=B.Transpose2();

  CSparseMatrix C = A*B;
  cout<<"the matrix C's cell is"<<endl;
  C.matrixPrint();


}
예제 #11
0
TEST(SparseMatrix, InitFromTriplet)
{
	CSparseMatrix SM;
	CMatrixDouble  D(10,20);

	SM.insert_entry(2,2, 4.0);  D(2,2) = 4.0;
	SM.insert_entry(6,8, -2.0);  D(6,8) = -2.0;

	SM.setRowCount(10);
	SM.setColCount(20);

	CMatrixDouble    dense_out1;
	SM.get_dense(dense_out1);

	SM.compressFromTriplet();

	CMatrixDouble    dense_out2;
	SM.get_dense(dense_out2);

	EXPECT_TRUE(dense_out1==dense_out2);
}
HRESULT CIsochartMesh::InitializeBarycentricEquation(
    CSparseMatrix<double>& A,
    CVector<double>& BU,
    CVector<double>& BV,
    const std::vector<double>& boundTable,
    const std::vector<uint32_t>& vertMap)
{
    HRESULT hr = S_OK;

    CSparseMatrix<double> orgA;
    CVector<double> orgBU, orgBV;

    // 1. Allocate memory
    size_t dwOrgADim = m_dwVertNumber - boundTable.size()/2;

    try
    {
        orgA.resize(dwOrgADim, dwOrgADim);
        orgBU.resize(dwOrgADim);
        orgBV.resize(dwOrgADim);
    }
    catch (std::bad_alloc&)
    {
        return E_OUTOFMEMORY;
    }

    // 2. Fill the linear equation
    for (size_t ii=0; ii<m_dwVertNumber; ii++)
    {
        if (m_pVerts[ii].bIsBoundary)
        {
            continue;
        }
    
        auto& adjacent = m_pVerts[ii].vertAdjacent;
        double bu = 0, bv = 0;

        orgA.setItem(vertMap[ii], vertMap[ii], double(adjacent.size()));
        for (size_t jj=0; jj<adjacent.size(); jj++)
        {
            uint32_t dwAdj = adjacent[jj];
            
            if (m_pVerts[dwAdj].bIsBoundary)
            {
                bu += boundTable[vertMap[dwAdj]*2];
                bv += boundTable[vertMap[dwAdj]*2+1];
            }
            else
            {
                orgA.setItem(vertMap[ii], vertMap[dwAdj], double(-1));	
            }
        }
        orgBU[vertMap[ii]] = bu;
        orgBV[vertMap[ii]] = bv;
    }

    // 3. get Symmetric matrix
    // A' = A^T * A
    if (!CSparseMatrix<double>::Mat_Trans_MUL_Mat(A, orgA))
    {
        return E_OUTOFMEMORY;
    }

    // B' = A^T * b
    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(BU, orgA, orgBU))
    {
        return E_OUTOFMEMORY;
    }

    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(BV, orgA, orgBV))
    {
        return E_OUTOFMEMORY;
    }
    
    return hr;
}
CPNLBase *CPersistMatrixFlt::Load(CContextLoad *pContext)
{
    CommonMatrixAttrs attrs;
    pnlString text;

    pContext->GetText(text);
    MatrixCommonLoad(&attrs, pContext);
    if(attrs.m_Class == mcDense || attrs.m_Class == mcNumericDense
        || attrs.m_Class == mc2DNumericDense)
    {
        floatVector data;
        std::istringstream buf(text.c_str());

        LoadArray<float>(buf, data);
        switch(attrs.m_Class)
        {
        case mcDense:
            return CDenseMatrix<float>::Create(attrs.m_nDim, &attrs.m_Ranges.front(),
                &data.front(), attrs.m_bClamp);
        case mcNumericDense:
            return CNumericDenseMatrix<float>::Create(attrs.m_nDim,
                &attrs.m_Ranges.front(), &data.front(), attrs.m_bClamp);
        case mc2DNumericDense:
            return C2DNumericDenseMatrix<float>::Create(&attrs.m_Ranges.front(),
                &data.front(), attrs.m_bClamp);
        }
        PNL_THROW(CInvalidOperation, "Unknown matrix type");
    }

    CSparseMatrix<float> *pSparse;
    switch(attrs.m_Class)
    {
    case mcSparse:
        pSparse = CSparseMatrix<float>::Create(attrs.m_nDim, &attrs.m_Ranges.front(), 0);
        break;
    case mcNumericSparse:
        pSparse = CNumericSparseMatrix<float>::Create(attrs.m_nDim,
            &attrs.m_Ranges.front(), attrs.m_bClamp);
        break;
    case mc2DNumericSparse:
    default:
        PNL_THROW(CInvalidOperation, "Unknown matrix type");
        break;
    }

    std::istringstream bufSparse(text.c_str());
    intVector index;
    char ch;
    float val;
    for(;bufSparse.good();)
    {
        LoadArray(bufSparse, index);
        if(!bufSparse.good())
        {
            break;
        }
        if(bufSparse.peek() == ']')
        {
            bufSparse >> ch;
        }
        bufSparse >> ch;
        ASSERT(ch == ':');
        bufSparse >> val;
        pSparse->SetElementByIndexes(val, &index.front());
    }
예제 #14
0
//-------------------------------------------------------------------------------------
HRESULT CIsochartMesh::AddFaceWeight(
    uint32_t dwFaceID,
    CSparseMatrix<double>& A,
    CSparseMatrix<double>& M,
    uint32_t dwBaseVertId1,
    uint32_t dwBaseVertId2)
{
    HRESULT hr = S_OK;

    assert(dwBaseVertId1 < dwBaseVertId2);
    ISOCHARTFACE& face = m_pFaces[dwFaceID];

    XMFLOAT2 v2d[3];
    XMFLOAT3 axis[2];

    IsochartCaculateCanonicalCoordinates(
        m_baseInfo.pVertPosition + m_pVerts[face.dwVertexID[0]].dwIDInRootMesh,
        m_baseInfo.pVertPosition + m_pVerts[face.dwVertexID[1]].dwIDInRootMesh,
        m_baseInfo.pVertPosition + m_pVerts[face.dwVertexID[2]].dwIDInRootMesh,
        v2d,
        v2d+1,
        v2d+2,
        axis);

    double t = 
        (v2d[0].x*v2d[1].y - v2d[0].y*v2d[1].x) +
        (v2d[1].x*v2d[2].y - v2d[1].y*v2d[2].x) +
        (v2d[2].x*v2d[0].y - v2d[2].y*v2d[0].x);

    t = static_cast<double>(IsochartSqrt(t));
    if (IsInZeroRange2(static_cast<float>(t)))
    {
        return hr;
    }

    CSparseMatrix<double>* pA = nullptr;
    for (size_t ii=0; ii<3; ii++)
    {
        ISOCHARTVERTEX& vert = m_pVerts[face.dwVertexID[ii]];

        double w_r = v2d[(ii+2)%3].x - v2d[(ii+1)%3].x;
        double w_i = v2d[(ii+2)%3].y - v2d[(ii+1)%3].y;

        size_t dwCol1;
        size_t dwCol2;

        if ( IN_CONSTANT == GetPosInMatrix(
            vert.dwID, 
            m_dwVertNumber, 
            dwBaseVertId1,
            dwBaseVertId2,
            dwCol1,
            dwCol2))
        {
            pA = &M;
        }
        else
        {
            pA = &A;
        }

        if (!pA->setItem(dwFaceID, dwCol1, w_r/t))
        {
            return E_OUTOFMEMORY;
        }
        if (!pA->setItem(dwFaceID, dwCol2, -w_i/t))
        {
            return E_OUTOFMEMORY;
        }

        if (!pA->setItem(dwFaceID+m_dwFaceNumber, dwCol1, w_i/t))
        {
            return E_OUTOFMEMORY;
        }		
        if (!pA->setItem(dwFaceID+m_dwFaceNumber, dwCol2, w_r/t))
        {
            return E_OUTOFMEMORY;
        }		
    }
    return hr;
}