Esempio n. 1
0
inline void eliminationOperators(SpMat& A, DynamicVector<size_t>& Cset, size_t fnode,
        DynamicVector<double>& q, SpMat& P, size_t& P_col, size_t P_row) {
    /* Inizializziamo la riga P_row con A.nonZeros(fnode) - 1 non nulli*/
    double scalingFactor = 1.0;
    /* Riserviamo spazio in ciascuna colonna di P per un adeguato numero
     * di elementi. Il -1 c'è perché (il reciproco del)l'elemento in
     * diagonale lo mettiamo in q
     */
    P.reserve(P_row, A.nonZeros(fnode) - 1);
    /* Per ciascuna f-riga prendo gli elementi in ogni c-colonna */
    DynamicVector<size_t>::Iterator ccol = Cset.begin();
    for (SpMat::Iterator frow = A.begin(fnode); frow != A.end(fnode); ++frow) {
        if (frow->index() == fnode) { //Elemento della diagonale
            q[P_row] = (1.0 / frow->value()); //Q ha elementi pari al numero di righe di R
            scalingFactor = -(q[P_row]);
        } else if (ccol != Cset.end()) {
            break; //Non ha senso andare avanti se abbiamo finito i ccol
        } else if (frow->index() == (*ccol)) {
            /* Elemento fuori della diagonale ed è anche un c-colonna */
            P.append(P_row, P_col, frow->value());
            P_col++;
            ccol++;
        }
    }

    P.finalize(P_row); //Finalizziamo la riga P_row

    /* Non dimentichiamo di scalare gli elementi della riga corrente
     * per  -scalingFactor */
    for (SpMat::Iterator it = P.begin(P_row); it != P.end(P_row); it++)
        it->value() *= -scalingFactor;
}
DynamicVector<Movie> Controller::findMoviesOfTitle(string title)
{
	DynamicVector<Movie> list;
	for (int i = 0; i < this->repository.movies.size(); i++)
	{
		if (this->repository.movies[i].title == title)
		{
			list.add(this->repository.movies[i]);
		}
	}
	return list;
}
DynamicVector<Movie> Controller::findMoviesOfYear(int year)
{
	DynamicVector<Movie> list;
	for (int i = 0; i < this->repository.movies.size(); i++)
	{
		if (this->repository.movies[i].year == year)
		{
			list.add(this->repository.movies[i]);
		}
	}
	return list;
}
Esempio n. 4
0
  void SetCases()
  {
    std::string error;
    Dynamic table = TABLE;
    nkit::TableIndex::Ptr index;
    nkit::TableIndex::ConstIterator it;

    DynamicVector vargs;
    vargs.push_back(Dynamic("NEW"));
    vargs.push_back(Dynamic(0));
    vargs.push_back(Dynamic(true));
    vargs.push_back(Dynamic(0));
    vargs.push_back(Dynamic(0.0));

    COMMON_TABLE_INIT(table);

    index = table.CreateIndex("name,name1", &error);
    NKIT_TEST_ASSERT_WITH_TEXT(index, error);

    NKIT_TEST_ASSERT(table.SetRow(table.height() / 2, vargs));
    DynamicVector::iterator vit = vargs.begin();
    for (size_t col = 0; vit != vargs.end(); ++vit, ++col)
    {
  #if defined(MY_TRACE_)
    print(*vit, "", false);
    std::cout << " <> ";
    print(table.GetCellValue(table.height() / 2, col));
  #endif // MY_TRACE_
      NKIT_TEST_ASSERT(*vit == table.GetCellValue(table.height() / 2, col));
    } // for
    NKIT_TEST_ASSERT(index->GetEqual(Dynamic("NEW"),Dynamic(0)) != index->end());
  }
/* returns a list of random movies from repo, throws OutOfRangeException */
DynamicVector<Movie> Controller::getRandomMovies(int howMany)
{
	if (howMany<0 || howMany > this->repository.movies.size())
	{
		throw OutOfRangeException("Size is " + this->repository.movies.size());
	}
	DynamicVector<Movie> list;
	DynamicVector<Movie> shuffledOriginalList = this->repository.movies.clone();
	shuffledOriginalList.shuffle();
	for (int i = 0; i < howMany; i++)
	{
		list.add(shuffledOriginalList[i]);
	}
	return list;
}
Esempio n. 6
0
 void encodeDynamicVector(float *buffer, size_t componentsCount, size_t count, const GLTFConverterContext& converterContext) {
     GLTFOutputStream *outputStream = converterContext._compressionOutputStream;
     Real max[32];
     Real min[32];
     O3DGCStreamType streamType = converterContext.compressionMode == "ascii" ? O3DGC_STREAM_TYPE_ASCII : O3DGC_STREAM_TYPE_BINARY;
     
     DynamicVector dynamicVector;
     dynamicVector.SetVectors(buffer);
     dynamicVector.SetDimVector(componentsCount);
     dynamicVector.SetMax(max);
     dynamicVector.SetMin(min);
     dynamicVector.SetNVector(count);
     dynamicVector.SetStride(componentsCount);
     dynamicVector.ComputeMinMax(O3DGC_SC3DMC_MAX_SEP_DIM);//O3DGC_SC3DMC_MAX_ALL_DIMS        
     DVEncodeParams params;
     
     params.SetQuantBits(componentsCount == 1 ? 11 : 17); //HACK, if that's 1 component it is the TIME and 10 bits is OK
     params.SetStreamType(streamType);
     
     DynamicVectorEncoder encoder;
     encoder.SetStreamType(streamType);
     Timer timer;
     timer.Tic();
     BinaryStream bstream(componentsCount * count * 16);
     encoder.Encode(params, dynamicVector, bstream);
     timer.Toc();
     outputStream->write((const char*)bstream.GetBuffer(), bstream.GetSize());
     
     /*
     if (componentsCount == 4) {
         DynamicVector  dynamicVector1;
         DynamicVectorDecoder decoder;
         decoder.DecodeHeader(dynamicVector1, bstream);
         dynamicVector1.SetStride(dynamicVector1.GetDimVector());
         
         std::vector<Real> oDV;
         std::vector<Real> oDVMin;
         std::vector<Real> oDVMax;
         oDV.resize(dynamicVector1.GetNVector() * dynamicVector1.GetDimVector());
         oDVMin.resize(dynamicVector1.GetDimVector());
         oDVMax.resize(dynamicVector1.GetDimVector());
         dynamicVector1.SetVectors(& oDV[0]);
         dynamicVector1.SetMin(& oDVMin[0]);
         dynamicVector1.SetMax(& oDVMax[0]);
         decoder.DecodePlayload(dynamicVector1, bstream);
         
         float* dbuffer = (float*)dynamicVector1.GetVectors();
         
         printf("****dump axis-angle. Axis[3] / Angle[1]\n");
         for (int i = 0 ; i < count ; i++) {
             int offset = i * 4;
             printf("[raw]%f %f %f %f [10bits]%f %f %f %f\n",
                    buffer[offset+0],buffer[offset+1],buffer[offset+2],buffer[offset+3],
                    dbuffer[offset+0],dbuffer[offset+1],dbuffer[offset+2],dbuffer[offset+3]);
         }
     }
     */
 }
Esempio n. 7
0
 bool test(const DynamicVector<RealType>& params) const {
     for (size_t i=0; i<params.size(); i++) {
         if ((params[i] < low_) || (params[i] > high_))
             return false;
     }
     return true;
 }
Esempio n. 8
0
 bool test(const DynamicVector<RealType>& params) const {
     for (size_t i=0; i<params.size(); ++i) {
         if (params[i] <= 0.0)
             return false;
     }
     return true;
 }
DynamicVector<Movie> Controller::getSortedMoviesByActor()
{
	DynamicVector<Movie> clone = this->repository.movies.clone();
	for (int i = 0; i < clone.size() - 1; i++)
	{
		for (int j = i + 1; j < clone.size(); j++)
		{
			if (clone[i].actor.compare(clone[j].actor)>0)
			{
				Movie aux = clone[i];
				clone[i] = clone[j];
				clone[j] = aux;
			}
		}
	}
	return clone;
}
Esempio n. 10
0
DynamicVector<string> AnagramController::anagramsForWord(string word) {
  //add the word as the key and the sorted word as value in the dictionary
  for (int i = 0; i<repo->getAll().getSize(); i++){
    string key = repo->getAll().elementAtIndex(i);
    map.addValueAndKey(key, sortWord(key));
  }

  word = sortWord(word);
  DynamicVector<string> elements = DynamicVector<string>();
  Node<string, string> *first = map.getNodeForValue(word);
  //find the first node that has as value, the desired sorted word and
  //add the key to the elements
  while (first != NULL && first->getData()->getValue() == word) {
    elements.add(first->getData()->getKey());
    first = first->getNext();
  }
  return elements;
}
Esempio n. 11
0
int ChParallelDataManager::OutputBlazeVector(DynamicVector<real> src, std::string filename) {
    const char* numformat = "%.16g";
    ChStreamOutAsciiFile stream(filename.c_str());
    stream.SetNumFormat(numformat);

    for (int i = 0; i < src.size(); i++)
        stream << src[i] << "\n";

    return 0;
}
Esempio n. 12
0
inline void eliminationOperators(DMat& A, DynamicVector<size_t>& Cset, size_t fnode,
        DynamicVector<double>& q, SpMat& P, size_t& P_col, size_t P_row) {
    double scalingFactor = 1.0;
    P.reserve(P_row, A.nonZeros(fnode) - 1);
    DynamicVector<size_t>::Iterator ccol = Cset.begin();
    for (size_t frow = 0; frow < A.rows(); ++frow) {
        if (frow == fnode) { //Elemento sulla diagonale
            q[P_row] = (1.0 / A(frow, fnode));
            scalingFactor = -(q[P_row]);
        } else if (ccol != Cset.end()) {
            break; //Non ha senso andare avanti se abbiamo finito i ccol
        } else if (frow == (*ccol)) {
            P.append(P_row, P_col, A(frow, fnode));
            P_col++;
            ccol++;
        }
    }
    P.finalize(P_row);

    for (SpMat::Iterator it = P.begin(P_row); it != P.end(P_row); it++)
        it->value() *= -scalingFactor;
}
DynamicVector<Movie> Controller::getSortedMoviesByYearAndGenre()
{
	DynamicVector<Movie> clone = this->repository.movies.clone();
	for (int i = 0; i < clone.size() - 1; i++)
	{
		for (int j = i + 1; j < clone.size(); j++)
		{
			if (clone[i].year > clone[j].year)
			{
				Movie aux = clone[i];
				clone[i] = clone[j];
				clone[j] = aux;
			}
			else if (clone[i].year == clone[j].year && clone[i].genre.compare(clone[j].genre)> 0)
			{
				Movie aux = clone[i];
				clone[i] = clone[j];
				clone[j] = aux;
			}
		}
	}
	return clone;
}
Esempio n. 14
0
  void DeleteCases()
  {
    std::string error;
    Dynamic table = TABLE;
    nkit::TableIndex::Ptr index;
    nkit::TableIndex::ConstIterator it;

    COMMON_TABLE_INIT(table);

    index = table.CreateIndex("name,name1,name3", &error);

    // Fail cases tests
    NKIT_TEST_ASSERT(index);
    NKIT_TEST_ASSERT(index->GetEqual(Dynamic(3), Dynamic(1)) == index->end());
    NKIT_TEST_ASSERT(index->GetEqual(Dynamic("A3"), Dynamic(3)) == index->end());

    // Good cases tests
    for (size_t ops = 0; ops < TABLE_GROW_SIZE; ++ops)
    {
      DynamicVector vargs;
      vargs.push_back(Dynamic("A3"));
      vargs.push_back(Dynamic(3));
      vargs.push_back(Dynamic(false));
      vargs.push_back(Dynamic(1));
      vargs.push_back(Dynamic(double(2.0 + ops)));
      NKIT_TEST_ASSERT(table.InsertRow(0, vargs));
    }

    for (size_t ops = 0; ops < TABLE_GROW_SIZE; ++ops)
      NKIT_TEST_ASSERT(table.DeleteRow(0));

    it = index->GetEqual(Dynamic("A3"), Dynamic(3), Dynamic(1));
    NKIT_TEST_ASSERT(it != index->end());
    for (; it != index->end(); ++it)
    {
  #if defined(MY_TRACE_)
        print(it[4]);
  #endif // MY_TRACE_
    }

    NKIT_TEST_ASSERT(table == e);
  }
Esempio n. 15
0
  void InsertCases()
  {
    std::string error;
    Dynamic table = TABLE;
    nkit::TableIndex::Ptr index;
    nkit::TableIndex::ConstIterator it;

    COMMON_TABLE_INIT(table);

    // Fail cases tests
    for (size_t ops = 0; ops < TABLE_GROW_SIZE; ++ops) // wrong type
    {
      DynamicVector vargs;
      vargs.push_back(Dynamic(1));
      vargs.push_back(Dynamic(3));
      vargs.push_back(Dynamic(false));
      vargs.push_back(Dynamic(1));
      vargs.push_back(Dynamic("name"));
      NKIT_TEST_ASSERT(table.InsertRow(0, vargs) == false);
    }
    NKIT_TEST_ASSERT(table == e);

    index = table.CreateIndex("name,name1,name3", &error);
    NKIT_TEST_ASSERT(index);
    NKIT_TEST_ASSERT(index->GetEqual(Dynamic(3), Dynamic(1)) == index->end());
    NKIT_TEST_ASSERT(index->GetEqual(Dynamic("A3"), Dynamic(3)) == index->end());

    // Good cases tests
    for (size_t ops = 0; ops < TABLE_GROW_SIZE; ++ops)
    {
      DynamicVector vargs;
      vargs.push_back(Dynamic("A3"));
      vargs.push_back(Dynamic(3));
      vargs.push_back(Dynamic(false));
      vargs.push_back(Dynamic(1));
      vargs.push_back(Dynamic(double(2.0 + ops)));
      NKIT_TEST_ASSERT(table.InsertRow(0, vargs));
    }
    it = index->GetEqual(Dynamic("A3"), Dynamic(3), Dynamic(1));
    NKIT_TEST_ASSERT(it != index->end());
    for (; it != index->end(); ++it)
    {
  #if defined(MY_TRACE_)
        print(it[4]);
  #endif // MY_TRACE_
    }

    for (size_t ops = 0; ops < TABLE_GROW_SIZE; ++ops)
    {
      DynamicVector vargs;
      vargs.push_back(Dynamic("A10"));
      vargs.push_back(Dynamic(3));
      vargs.push_back(Dynamic(false));
      vargs.push_back(Dynamic(1));
      vargs.push_back(Dynamic(double(1.0 + ops)));
      NKIT_TEST_ASSERT(table.InsertRow(table.height() / 2, vargs));
    }

    it = index->GetEqual(Dynamic("A10"), Dynamic(3), Dynamic(1));
    NKIT_TEST_ASSERT(it != index->end());
    for (; it != index->end(); ++it)
    {
  #if defined(MY_TRACE_)
        print(it[4]);
  #endif // MY_TRACE_
    }

    it = index->GetEqual(Dynamic("A"), Dynamic(1), Dynamic(1));
    NKIT_TEST_ASSERT(it != index->end());
    NKIT_TEST_ASSERT(it[4] == Dynamic(99.0));

    it = index->GetEqual(Dynamic("A2"), Dynamic(2), Dynamic::GetDefault(detail::INTEGER));
    NKIT_TEST_ASSERT(it != index->end());

    it = index->GetEqual(Dynamic("A1"), Dynamic(1), Dynamic::GetDefault(detail::INTEGER));
    NKIT_TEST_ASSERT(it != index->end());
  }
Esempio n. 16
0
File: VQModel.cpp Progetto: nykm/sop
void VQModel::Adapt(const std::shared_ptr<Model>& other, const std::vector< DynamicVector<Real> >& samples,
    unsigned int iterations, Real relevanceFactor)
{
    const VQModel* model = dynamic_cast<VQModel*>(other.get());

    if (model == nullptr)
    {
        std::cout << "Not VQModel." << std::endl;
        return;
    }

    SetOrder(model->GetOrder());
    Init();

    std::vector<unsigned int> indices(samples.size());

    // Initialize the feature vectors of the centroids.

    for (unsigned int c = 0; c < GetOrder(); c++)
    {
        mClusterCentroids[c] = model->mClusterCentroids[c];
    }

    // Do the iterations.
    for (unsigned int i = 0; i < iterations; i++)
    {
        //Find the closest centroid to each sample
        for (unsigned int n = 0; n < samples.size(); n++)
        {
            Real minDist = std::numeric_limits<Real>::max();

            for (unsigned int c = 0; c < GetOrder(); c++)
            {
                Real dist = samples[n].Distance(mClusterCentroids[c]);

                if (dist < minDist)
                {
                    minDist = dist;
                    indices[n] = c;
                }
            }
        }

        //Set the centroids to the average of the samples in each centroid
        for (unsigned int c = 0; c < GetOrder(); ++c)
        {
            mClusterCentroids[c].Assign(0.0f);

            mClusterSizes[c] = 0;
        }

        for (unsigned int s = 0; s < samples.size(); ++s)
        {
            mClusterCentroids[indices[s]].Add(samples[s]);

            ++mClusterSizes[indices[s]];
        }

        for (unsigned int c = 0; c < GetOrder(); ++c)
        {
            if (mClusterSizes[c] > 0)
            {
                mClusterCentroids[c].Multiply(1.0f / static_cast<Real>(mClusterSizes[c]));
            }
        }

        //Calculate the adapted values
        for (unsigned int c = 0; c < GetOrder(); ++c)
        {
            Real size = static_cast<Real>(mClusterSizes[c]);
            Real w = size / (size + static_cast<Real>(relevanceFactor));

            DynamicVector<Real> ubmc = model->mClusterCentroids[c];
            ubmc.Multiply(1.0f - w);

            mClusterCentroids[c].Multiply(w);
            mClusterCentroids[c].Add(ubmc);
        }
    }
}
Esempio n. 17
0
LevelElimination * LAMGLSSolver::coarsenElimination(const Matrix & finerMatrix) {
cout << "coarsenElimination()" << endl;
    //Per salvare i P ed i q
    std::vector<qPStage*> cStages;
    /* Prealloco spazio per al più SETUP_ELIMINATION_MAX_STAGES così evito
     * possibili riallocazioni */
    cStages.reserve(SETUP_ELIMINATION_MAX_STAGES);

    //Copio la matrice così posso modificarla senza modificare quella del finerLevel
    Matrix A(finerMatrix);
    Matrix Acc; //Per lo Schur Complement System
    Matrix Acf; //Per lo Schur Complement System
    // Il numero di stage di eliminazione eseguiti sulla matrice A
    size_t stageNum = 0;

    /* Vector che vengono riusati*/
    DynamicVector<size_t> Cset; //Insieme dei nodi da non eliminare
    DynamicVector<size_t> Fset; //Insieme dei nodi da eliminare
    DynamicVector<size_t> degree; //Grado di ciascun nodo
    DynamicVector<size_t> candidate; //Nodi candidati all'eliminazione
    DynamicVector<NodeEliminationStatus> status; //Stato dei nodi
    /* P è sempre sparsa anche quando A è densa */
    SpMat P;
    DynamicVector<double> q;

    while (stageNum < SETUP_ELIMINATION_MAX_STAGES) {

        size_t A_rows = A.rows();
        if (A_rows <= MAX_DIRECT_SOLVE_SIZE)
            break;
        /* (1) Calcola il vettore degree della matrice. */
        degree.resize(A_rows);

        for (size_t i = 0; i < A_rows; ++i) {
            degree[i] = A.nonZeros(i);
            if (A(i, i) != 0)//Tolgo l'elemento sulla diagonale
                degree[i]--;
            else
                cerr << "La diagionale i-esima c'ha lelemento a zero!!! ERRORE MORTALE!!!" << endl;
        }

        /* (2) [f c ] = lowDegreeNodes(A,degree,MaxDegree)  */
        candidate.resize(A_rows);
        candidate = 0;
        /* Individuo i nodi candidati (degree[i] <= MAX_DEGREE) */
        size_t cnnZ = 0; //Devo usare questa variabili perché i valori "settati" di candidate comprendono il valore "0" cioè il nodo 0
        for (size_t i = 0; i < A_rows; ++i) {
            if (degree[i] <= SETUP_ELIMINATION_MAX_DEGREE) {
                candidate[cnnZ++] = i;
            }
        }
        /* I primi cnnZ elementi sono stati inizializzati */
        candidate.resize(cnnZ, true);

        status.resize(A_rows);
        status = HIGH_DEGREE; //Tutti gli elementi prendono HIGH_DEGREE
        //    status(candidate)  = 0; % Reset all relevant nodes to "not visited"
        for (size_t i = 0; i < candidate.size(); ++i) {
            status[candidate[i]] = NOT_DECIDED;
        }

        for (size_t k = 0; k < candidate.size(); ++k) {
            lowdegreesweep(A, candidate[k], status); //Template call
        }

        /* Adesso devo creare i vettori F e C, inserendovi i nodi che verranno
         * o meno eliminati */
        size_t nf = 0; //|Fset|
        size_t nc = 0; //|Cset|
        Cset.resize(A_rows, false);
        Fset.resize(A_rows, false);
        for (size_t i = 0; i < A_rows; ++i) {
            if (status[i] == LOW_DEGREE)
                Fset[nf++] = i; //Inserisco il nodo i nell'insieme F
            else
                Cset[nc++] = i; //Lo inserisco invece in C
        }

        /* L'insieme C non può mai essere vuoto, dobbiamo lasciargli almeno
         * un elemento
         */
        if (nc == 0) {
            Cset[nc++] = Fset[--nf];
            Fset[nf] = 0;

        }
        Cset.resize(nc, true); //nc non è mai 0
        Fset.resize(nf, true);

        /* FINE di (2) [f c ] = lowDegreeNodes(A,degree,MaxDegree) */


        if ((nf <= SETUP_ELIMINATION_MIN_ELIM_FRACTION * A_rows)) {
            /* Il coarsening non è abbastanza efficace perché andiamo ad eliminare
             * un numero, nf, di nodi che è inferiore alla minima soglia accettabile
             * di eliminazione. Ci fermiamo senza eliminare.*/
            break;
        }


        /* (3) Una volta individuati i nodi da eliminare devo calcolare gli
         * operatori P e q che mi consentono di eliminare tutti questi nodi
         *      [R, q] = eliminationOperators(A, f, index);
         */


        /* In MEX si crea una matrice columnMajor che poi verrà trasposta perché
         * le matrici di Matlab sono columnMajor e se uno vuole sfruttare la
         * rappresentazione interna deve usarle così.
         * Noi invece possiamo già generare la matrice trasposta costruendo
         * direttamente la matrice rowMajor e "sostituendo" ai termini riga
         * quelli colonna.
         */
        /* P è sempre una matrice sparsa perché il numero dei suoi nonzero
         * e basso anche quando A è densa */
        P.resize(nf, nc, false);
        q.resize(nf, false);

        /* Quanti elemenenti abbiamo salvato in Q (e quante righe di R
         * abbiamo costruito)
         */
        size_t P_row = 0;
        size_t P_col = 0;
        /* Per ogni f-riga di A prendi ciascun c-elemento di questa riga e formaci
         * la i-esima riga di R. L'inverso dell'f-esimo elemento di ciascuna f-riga
         * va messo in q. Inoltre ciascuna riga i di R va scalata di un fattore -q[i]
         */
        for (DynamicVector<size_t>::Iterator dvit = Fset.begin(); dvit != Fset.end(); dvit++) {
            eliminationOperators(A, Cset, (*dvit), q, P, P_col, P_row);
            P_row++; //Passiamo alla prosssima riga
        }
        //Salvo i dati così creati nel cStages
        cStages.push_back(new qPStage(new SpMat(P), new DynamicVector<double>(q),
                new DynamicVector<size_t>(Fset), new DynamicVector<size_t>(Cset), (nf + nc)));
        /* FINE (03) [R, q] = eliminationOperators(A, f, index);*/




        /* (4) Adesso devo calcolare il sistema complementare di Schur dato da
         *  A = Ac,c + Ac,f*R^t         */

        /* Acc è la sottomatrice di A che ha come elementi tutti gli a_ij tali
         * che (ij) appartiene a Cset x Cset. Quindi per ogni riga crow devo
         * prenderci tutti gli elementi che hanno indice pari a ccol */
        MtxOps::submatrix(A, Cset, Cset, Acc);

        /* Acf invece ha nc righe e nf colonne*/
        MtxOps::submatrix(A, Cset, Fset, Acf);
        /* Finalmente posso aggiornare A*/
        A = Acc + Acf * P;
        /* Acc_[nc x nc] + (Acf * P)_[nc x nc].
         * Dunque La matrice A risultante diventa una nc x nc e perdiamo esattamente nf nodi.*/
    }//Fine while(stageNum...)

    /* Usciti dal while dobbiamo creare il livello, se è possibile farlo */
    LevelElimination* ret = NULL;
    if (stageNum != 0) {

        if (useSparse) {
            if (isSparseOK(A)) {
                ret = new LevelElimination(new SpMat(A), cStages, multiGrid.back());
            } else {
                useSparse = false;
                ret = new LevelElimination(new DMat(A), cStages, multiGrid.back());
            }
        } else {

            ret = new LevelElimination(new DMat(A), cStages, multiGrid.back());
        }
    }
cout << "coarsenElimination() finito" << endl;
    return ret;
}