Example #1
0
void MuteVisitor::visit (const MatrixExp &e)
{
    exps_t lines = e.getLines();
    for (exps_t::const_iterator it = lines.begin(), itEnd = lines.end(); it != itEnd ; ++it)
    {
        (*it)->mute();
        (*it)->accept(*this);
    }
}
Example #2
0
/** \name Visit Matrix Expressions nodes.
 ** \{ */
void PrintVisitor::visit (const MatrixExp &e)
{
    ast::exps_t::const_iterator	i, j;
    *ostr << SCI_OPEN_MATRIX;
    ++indent;
    this->is_last_matrix_line = false;
    ast::exps_t lines = e.getLines();
    for (i = lines.begin() ; i != lines.end() ; )
    {
        bool addIndent = false;
        j = i;
        if (++j == lines.end())
        {
            this->is_last_matrix_line = true;
        }
        else
        {
            if ((*i)->getLocation().last_line != (*j)->getLocation().first_line)
            {
                addIndent = true;
            }
        }

        if (displayOriginal)
        {
            (*i)->getOriginal()->accept(*this);
        }
        else
        {
            (*i)->accept(*this);
        }

        //if (lines.size() > 1 || this->is_last_column_comment)
        if (addIndent)
        {
            *ostr << std::endl;
            this->apply_indent();
        }

        ++i;
    }
    *ostr << SCI_CLOSE_MATRIX;
    --indent;
}
void RunVisitorT<T>::visitprivate(const MatrixExp &e)
{
    CoverageInstance::invokeAndStartChrono((void*)&e);
    try
    {
        exps_t::const_iterator row;
        exps_t::const_iterator col;
        types::InternalType *poResult = NULL;
        std::list<types::InternalType*> rowList;

        exps_t lines = e.getLines();
        if (lines.size() == 0)
        {
            setResult(types::Double::Empty());
            CoverageInstance::invokeAndStartChrono((void*)&e);
            return;
        }

        //special case for 1x1 matrix
        if (lines.size() == 1)
        {
            exps_t cols = lines[0]->getAs<MatrixLineExp>()->getColumns();
            if (cols.size() == 1)
            {
                setResult(NULL); // Reset value on loop re-start

                cols[0]->accept(*this);
                //manage evstr('//xxx') for example
                if (getResult() == NULL)
                {
                    setResult(types::Double::Empty());
                }
                CoverageInstance::invokeAndStartChrono((void*)&e);
                return;
            }
        }

        //do all [x,x]
        for (row = lines.begin(); row != lines.end(); row++)
        {
            types::InternalType* poRow = NULL;
            exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
            for (col = cols.begin(); col != cols.end(); col++)
            {
                setResult(NULL); // Reset value on loop re-start

                try
                {
                    (*col)->accept(*this);
                }
                catch (const InternalError& error)
                {
                    if (poRow)
                    {
                        poRow->killMe();
                    }
                    if (poResult)
                    {
                        poResult->killMe();
                    }

                    throw error;
                }

                types::InternalType *pIT = getResult();
                if (pIT == NULL)
                {
                    continue;
                }

                //reset result but without delete the value
                clearResultButFirst();

                if (pIT->isImplicitList())
                {
                    types::ImplicitList *pIL = pIT->getAs<types::ImplicitList>();
                    if (pIL->isComputable())
                    {
                        types::InternalType* pIT2 = pIL->extractFullMatrix();
                        pIT->killMe();
                        pIT = pIT2;
                    }
                    else
                    {
                        if (poRow == NULL)
                        {
                            //first loop
                            poRow = pIT;
                        }
                        else
                        {
                            try
                            {
                                poRow = callOverloadMatrixExp(L"c", poRow, pIT);
                            }
                            catch (const InternalError& error)
                            {
                                if (poResult)
                                {
                                    poResult->killMe();
                                }
                                throw error;
                            }
                        }

                        continue;
                    }
                }

                if (pIT->isGenericType() == false)
                {
                    pIT->killMe();
                    std::wostringstream os;
                    os << _W("unable to concatenate\n");
                    throw ast::InternalError(os.str(), 999, (*col)->getLocation());
                }

                types::GenericType* pGT = pIT->getAs<types::GenericType>();

                if (poRow == NULL)
                {
                    //first loop
                    if (poResult == NULL && pGT->isDouble() && pGT->getAs<types::Double>()->isEmpty())
                    {
                        pGT->killMe();
                        continue;
                    }

                    if (pGT->isDouble() && pGT->getAs<types::Double>()->isEmpty())
                    {
                        if (poResult && (poResult->isList() || poResult->isStruct()))
                        {
                            //in case of [list(); [], ...]

                            //we don't know what to do with [], keep it as "normal" value and continue process
                            poRow = pGT;
                            continue;
                        }

                        pGT->killMe();
                        continue;
                    }

                    poRow = pGT;
                    continue;
                }

                //manage overload on list/struct/implicitlist and hypermatrix before management of []
                if (pGT->isList() || poRow->isList() || pGT->isStruct() || poRow->isStruct() || poRow->isImplicitList() || pGT->getDims() > 2)
                {
                    try
                    {
                        poRow = callOverloadMatrixExp(L"c", poRow, pGT);
                    }
                    catch (const InternalError& error)
                    {
                        if (poResult)
                        {
                            poResult->killMe();
                        }
                        throw error;
                    }

                    continue;
                }

                if (pGT->isDouble() && pGT->getAs<types::Double>()->isEmpty())
                {
                    pGT->killMe();
                    continue;
                }

                types::GenericType* pGTResult = poRow->getAs<types::GenericType>();

                //check dimension
                if (pGT->getDims() != 2 || pGT->getRows() != pGTResult->getRows())
                {
                    poRow->killMe();
                    if (poRow != pGT)
                    {
                        pGT->killMe();
                    }
                    std::wostringstream os;
                    os << _W("inconsistent row/column dimensions\n");
                    throw ast::InternalError(os.str(), 999, (*row)->getLocation());
                }

                // if we concatenate [Double Sparse], transform the Double to Sparse and perform [Sparse Sparse]
                // this avoids to allocate a Double result of size of Double+Sparse and initialize all elements.
                if (pGT->isSparse() && pGTResult->isDouble())
                {
                    poRow = new types::Sparse(*pGTResult->getAs<types::Double>());
                    pGTResult->killMe();
                    pGTResult = poRow->getAs<types::GenericType>();
                }
                else if (pGT->isSparseBool() && pGTResult->isBool()) // [Bool SparseBool] => [SparseBool SparseBool]
                {
                    poRow = new types::SparseBool(*pGTResult->getAs<types::Bool>());
                    pGTResult->killMe();
                    pGTResult = poRow->getAs<types::GenericType>();
                }
                else if (pGT->isDollar() && pGTResult->isDouble())
                {
                    int _iRows = pGTResult->getRows();
                    int _iCols = pGTResult->getCols();
                    int* piRank = new int[_iRows * _iCols];
                    memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
                    poRow = new types::Polynom(pGT->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
                    types::Polynom* pP = poRow->getAs<types::Polynom>();
                    types::SinglePoly** pSS = pP->get();
                    types::Double* pDb = pGTResult->getAs<types::Double>();
                    double* pdblR = pDb->get();
                    if (pDb->isComplex())
                    {
                        double* pdblI = pDb->getImg();
                        pP->setComplex(true);
                        for (int i = 0; i < pDb->getSize(); i++)
                        {
                            pSS[i]->setRank(0);
                            pSS[i]->setCoef(pdblR + i, pdblI + i);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < pDb->getSize(); i++)
                        {
                            pSS[i]->setRank(0);
                            pSS[i]->setCoef(pdblR + i, NULL);
                        }
                    }

                    delete[] piRank;
                }

                types::InternalType *pNewSize = AddElementToVariable(NULL, poRow, pGTResult->getRows(), pGTResult->getCols() + pGT->getCols());
                types::InternalType* p = AddElementToVariable(pNewSize, pGT, 0, pGTResult->getCols());
                if (p != pNewSize)
                {
                    pNewSize->killMe();
                }
                // call overload
                if (p == NULL)
                {
                    try
                    {
                        poRow = callOverloadMatrixExp(L"c", pGTResult, pGT);
                    }
                    catch (const InternalError& error)
                    {
                        if (poResult)
                        {
                            poResult->killMe();
                        }
                        throw error;
                    }
                    continue;
                }

                if (poRow != pGT)
                {
                    pGT->killMe();
                }

                if (p != poRow)
                {
                    poRow->killMe();
                    poRow = p;
                }
            }

            if (poRow == NULL)
            {
                continue;
            }

            if (poResult == NULL)
            {
                poResult = poRow;
                continue;
            }

            // management of concatenation with 1:$
            if (poRow->isImplicitList() || poResult->isImplicitList())
            {
                try
                {
                    poResult = callOverloadMatrixExp(L"f", poResult, poRow);
                }
                catch (const InternalError& error)
                {
                    throw error;
                }
                continue;
            }

            types::GenericType* pGT = poRow->getAs<types::GenericType>();

            //check dimension
            types::GenericType* pGTResult = poResult->getAs<types::GenericType>();

            if (pGT->isList() || pGTResult->isList() || pGT->isStruct() || pGTResult->isStruct() || pGT->getDims() > 2)
            {
                try
                {
                    poResult = callOverloadMatrixExp(L"f", pGTResult, pGT);
                }
                catch (const InternalError& error)
                {
                    throw error;
                }

                continue;
            }
            else
            {//[]
                if (pGT->isDouble() && pGT->getAs<types::Double>()->isEmpty())
                {
                    pGT->killMe();
                    continue;
                }
            }

            //check dimension
            if (pGT->getCols() != pGTResult->getCols())
            {
                poRow->killMe();
                if (poResult)
                {
                    poResult->killMe();
                }
                std::wostringstream os;
                os << _W("inconsistent row/column dimensions\n");
                throw ast::InternalError(os.str(), 999, (*e.getLines().begin())->getLocation());
            }

            // if we concatenate [Double Sparse], transform the Double to Sparse and perform [Sparse Sparse]
            // this avoids to allocate a Double result of size of Double+Sparse and initialize all elements.
            if (pGT->isSparse() && pGTResult->isDouble())
            {
                poResult = new types::Sparse(*pGTResult->getAs<types::Double>());
                pGTResult->killMe();
                pGTResult = poResult->getAs<types::GenericType>();
            }
            else if (pGT->isSparseBool() && pGTResult->isBool()) // [Bool SparseBool] => [SparseBool SparseBool]
            {
                poResult = new types::SparseBool(*pGTResult->getAs<types::Bool>());
                pGTResult->killMe();
                pGTResult = poResult->getAs<types::GenericType>();
            }

            types::InternalType* pNewSize = AddElementToVariable(NULL, poResult, pGTResult->getRows() + pGT->getRows(), pGT->getCols());
            types::InternalType* p = AddElementToVariable(pNewSize, pGT, pGTResult->getRows(), 0);
            if (p != pNewSize)
            {
                pNewSize->killMe();
            }

            // call overload
            if (p == NULL)
            {
                try
                {
                    poResult = callOverloadMatrixExp(L"f", pGTResult, pGT);
                }
                catch (const InternalError& error)
                {
                    throw error;
                }
                continue;
            }

            if (poResult != poRow)
            {
                poRow->killMe();
            }

            if (p != poResult)
            {
                poResult->killMe();
                poResult = p;
            }
        }

        if (poResult)
        {
            setResult(poResult);
        }
        else
        {
            setResult(types::Double::Empty());
        }
    }
    catch (const InternalError& error)
    {
        setResult(NULL);
        CoverageInstance::invokeAndStartChrono((void*)&e);
        throw error;
    }
    CoverageInstance::invokeAndStartChrono((void*)&e);
}