Example #1
0
// renvoie vide si le systËme lineaire I(v,R,S,precision) n'a pas de solution et
// sinon renvoie une solution de I i.e. un  ensemble de variables X_q telles que
// v^{-1}P = \sum_{q \in R} X_qP_q --  en rappelant que R[w]=q => P_q = w^{-1}P
// En prenant un maximum de max variables
RESULT PPRFA::solmax (T_ModeVariables modeVariables,
					  SFunc & solution,	// La solution
                      const Word & v,	// Le residuel a tester
                      const Sample & S,	// L'echantillon
                      Simplex & simplx,	// L'objet simplex qui permet de calculer la solution
                      double precision,	// La precision (sa signification depend du mode)
                      T_ModeReturn moderet,	// Le mode de retour : beg debut de l'arbre, end à la fin
                      T_ModeEpsilon modeeps,	// Le mode : epsfixed avec epsilon fixe, variable avec epsilon variable.
                      WordSet &W,	// L'ensemble de mots sur lesquels on teste,
									// doit contenirs les mots des √©tapes prÈcÈdentes
                      unsigned int max) const
{
    try
    {
		
        //    cout << "\t\tcreation du systeme" << endl;
		
        unsigned int i;
        int n;		// number of variables
        int err;
        WordSFunc::const_iterator q;
		
        // number of variables = number of states
        n = XR.size ();
		
		/*
		// ---------- Affichage de la liste de mots utilises --------------
          set<Word, ordre_mot>::const_iterator wy;
          map<Word, State>::const_iterator ri;
		  int compte = 1;
          cout << "\nliste de mots associes à " << v << " et à {";
          for (ri=XR.begin() ; ri != XR.end() ; ri++) {
            if (ri->first.empty())
				cout << "eps,";
            else
				cout << ri->first << ",";
          }
          cout << "}" << endl;
          for (wy = W.begin() ;  wy != W.end() ;wy++) {
            if (wy->empty())
				cout << "eps,";
            else
				cout << *wy << ",";
			if (!(compte++ % 10))
				cout << "\n";
          }
		  cout << "\nNombre de mots : " << W.size();
          cout << endl;
          // --------------------------------------------------------------
		*/
		
        // avec l'entree 0 on traite tous les mots
        if (max == 0)
            max = W.size () + 1;
		
        // inequations en <= (nb=ineq1), inequations en >= (nb=ineq2)
        // les inequations X_q >= 0 sont deja
        // prisent en comptent de manière implicite
        double s1;
        double s2;
        set< Word, ordre_mot >::const_iterator wi;
		
        double pvw = 0;	// v^{-1}P(w)
		
        s2 = S[v];
		
		// Initialisation du simplexe
		simplx.set_number_of_unknown_to(XR.size()+1);
		
		// sum of all Xi is equal to 1
		simplx.setparam(1,0); // --- la variable 1 est toujours epsilon ---
		simplx.setval(1);     //
        for (q = XR.begin (); q != XR.end (); q++)
            simplx.setparam(q->second+1,1);
		simplx.add_equality_constraint();
		// cout << "XR.size() = " << XR.size() << endl;
		
		
		// loop for each word :
		simplx.setparam(1,1); // --- la variable 1 est toujours epsilon ---
				
		i=0;
		for (wi = W.begin (); wi != W.end () && i <= max; wi++)
		{
			s1 = S[(v + *wi)];
			pvw = (double) s1 / (double) s2;
			simplx.setval(pvw);
			for (q = XR.begin (); q != XR.end (); q++)
			{
				s1 = S[q->first + *wi];
				simplx.setparam(q->second+1, (double) s1 / (double) S[q->first]);
			}
			simplx.add_absolute_constraint();
			++i;
		}
		
		
        switch (modeeps)
        {
            // ---------------------------------------------------------- EPSFIXED -
			case epsfixed:
				simplx.set_minimize_epsilon_mode(precision);
				break;
			// ---------------------------------------------------------- VARIABLE -
			case variable:
				simplx.set_minimize_epsilon_mode(-1);
				break;
			default:
				cerr << "!!! PFA::sol -- modeeps " << modeeps << " inconnu !!!" << endl;
        }
		
		switch(modeVariables) {
			case determinist:
				simplx.set_mode(ZeroOrOne);
				break;
			case positive:
				simplx.set_mode(realZeroBounded);
				break;
			case nonconstrained:
				simplx.set_mode(realNotBounded);
				break;
		}
		
		map<int,float> preciseSol;
		float epsilon;
		// simplx.affiche();
		err = simplx.has_solution(preciseSol, epsilon);
		// cout << (err?"solution trouvée":"pas de solution") << ", epsilon = " << epsilon << endl;
		if ((!err) || (epsilon>precision)) {
			solution.clear();
			return ERR(0);
		}
		else {
			solution.clear();
			float tmp;
			for (map<int,float>::const_iterator q =  preciseSol.begin() ; q != preciseSol.end() ; q++) {
				if (q->first != 1) {
					if ((tmp = (float) q->second) != 0) {
						solution[q->first - 1] = (float) q->second;
					}
				}
			}
			return VAL(0);
		}
    }
    catch (int erreur)
    {
        if (PFA_VERBOSE)
        {
            cerr << "ERREUR !!! PFA::solmax !!! n°" << erreur << endl;
        }
        solution.clear ();
        return erreur;
    }
}