Ejemplo n.º 1
0
 static bool is_small(Interval r) {
   return r.sup()- r.inf() < .001;
 }
Ejemplo n.º 2
0
  Interval LDB::operator ()(const LDB::ipolynomial_type    *poly_ptr,
                            const LDB::additional_var_data *data_ptr  ) const
  {
    unsigned int data_size = data_ptr->size();

    /*
      Abspalten der linearen Terme. Die Konstante wird den hoeheren Termen zugerechnet.
      Gleichzeitig werden die hoeheren Terme eingeschlossen.
    */

    Interval rest(0.0);
    std::vector<Interval> arguments( data_ptr->size() );
    for(unsigned int i = 0; i < data_size; i++)
      if( (*data_ptr)[ i ].operator ->() != 0 )
        arguments[ i ] = ((*data_ptr)[ i ])->domain_ - ((*data_ptr)[ i ])->devel_point_;

    std::vector<Interval> linear_coeffs(data_size, Interval(0.0));
    std::vector<unsigned int> var_codes; var_codes.reserve(data_size); //Codes of Vars with linear term.

    LDB::ipolynomial_type::const_iterator
      curr = poly_ptr->begin(),
      last = poly_ptr->end();

    while( curr != last )
    {
      if( curr->key().expnt_sum() == 0 )      //Konstanter Term.
      {
        rest += curr->value();
      }
      else if( curr->key().expnt_sum() == 1 ) //Linearer Term.
      {
        unsigned int i = curr->key().min_var_code();

        var_codes.push_back(i-1);
        linear_coeffs[i-1] = curr->value();
      }
      else //Nonlinear term.
      {
        Interval prod(1.0);

        //Evaluate the current monomial.
        for(unsigned int i = curr->key().min_var_code(); i <= curr->key().max_var_code(); i++)
        {
          unsigned int e = curr->key().expnt_of_var(i);
          if( e != 0 )
          {
            prod *= power( arguments[i-1], e );
          }
        }
        //Multiply with coefficient.
        prod *= curr->value();

        //Add enclosure to bound interval.
        rest += prod;
      }

      ++curr;
    }

    if( var_codes.size() == 0 ) return rest; //No linear terms in polynomial. So return with enclosure of
    //higher order terms.

    /*
      Lokale Kopien der 'Domains' anlegen, da diese im weiteren Verlauf unter Umstaenden
      veraendert werden.
    */

    std::vector<Interval> domain_of_max(data_size,Interval(0.0));
    std::vector<Interval> domain_of_min(data_size,Interval(0.0));

    for(unsigned int i = 0; i < data_size; i++)
    {
      if( (*data_ptr)[i].operator ->() ) //There is information.
      {
        domain_of_max[i] = domain_of_min[i] = ((*data_ptr)[i])->domain_;
      }
    }

    /*
      Jetzt beginnt der Algorithmus des LDB range bounders.
    */

    Interval idelta(rest.diam());
    for(unsigned int i = 0; i < var_codes.size(); i++)
    {
      unsigned int k = var_codes[i];
      Interval b = linear_coeffs[k];
      idelta += b.diam() * abs( ((*data_ptr)[k])->domain_ - ((*data_ptr)[k])->devel_point_ );
    }
    double delta = idelta.sup();

    bool resizing = false;
    for(unsigned int i = 0; i < var_codes.size(); i++)
    {
      unsigned int k = var_codes[i];

      double   mid_b  = linear_coeffs[k].mid();
      Interval abs_b  = Interval( std::abs(mid_b) );
      Interval domain = ((*data_ptr)[k])->domain_;
      Interval upper  = abs_b * domain.diam();
      if( upper.inf() > delta )
      {
        Interval tmp = delta / abs_b;
        if( mid_b > 0 )
        {
          domain_of_min[k] = domain_of_min[k].inf() + Interval(0,tmp.sup());
          domain_of_max[k] = domain_of_max[k].sup() - Interval(0,tmp.sup());
        }
        else
        {
          domain_of_min[k] = domain_of_min[k].sup() - Interval(0,tmp.sup());
          domain_of_max[k] = domain_of_max[k].inf() + Interval(0,tmp.sup());
        }
        resizing = true;
      }
    }

    for(unsigned int i = 0; i < data_size; i++)
    {
      if( (*data_ptr)[i].operator ->() ) //There is information.
      {
        domain_of_min[i] -= ((*data_ptr)[i])->devel_point_;
        domain_of_max[i] -= ((*data_ptr)[i])->devel_point_;
      }
    }

    if( resizing ) //Die Domains wurden verändert.
    {
      Interval min(0.0),max(0.0);

      curr = poly_ptr->begin();

      while( curr != last ) //Walk trough the polynomial.
      {
        Interval prod1(1.0),prod2(1.0);

        //Evaluate the current monomial.
        for(unsigned int i = (*curr).key().min_var_code(); i <= (*curr).key().max_var_code(); i++)
        {
          unsigned int e = (*curr).key().expnt_of_var(i);
          if( e != 0 )
          {
            prod1 *= power( domain_of_min[ i - 1 ], e );
            prod2 *= power( domain_of_max[ i - 1 ], e );
          }
        }

        //Multiply with coefficient.
        prod1 *= (*curr).value();   // <---- Multiply with double value.
        prod2 *= (*curr).value();   // <---- Multiply with double value.

        //Add enclosure to interval.
        min += prod1;
        max += prod2;

        ++curr;
      }

      return Interval( min.inf(), max.sup() );
    }
    else
    {
      for(unsigned int i = 0; i < var_codes.size(); i++)
      {
        unsigned int k = var_codes[i];
        rest += linear_coeffs[k] * domain_of_min[k];
      }
      return rest;
    }
  }
Ejemplo n.º 3
0
 static bool is_unknown_sign(Interval rv) {
   return rv.inf() <=0 && rv.sup() >=0;
 }