Main Page   Namespace List   Class Hierarchy   Compound List   File List   Header Files   Sources   Namespace Members   Compound Members   File Members  

total_energy_function.cpp

00001 //$Header: /home/ben/Mapper/c++/RCS/total_energy_function.cpp,v 6.4 2002/06/25 16:13:50 ben Exp $
00002 // Copyright Benedict Adamson 2002.
00003 // This file is part of Mapper.
00004 
00005 // Mapper is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 
00010 // Mapper is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with Mapper; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00029 #include <climits>
00030 
00031 #include "total_energy_function.h"
00032 
00033 
00034 
00035 const unsigned total_energy_function::fixed_point = UINT_MAX;
00036 
00037 
00038 
00039 total_energy_function::total_energy_function(
00040    const double t
00041    )
00042    :
00043    tol_( t ),
00044    points_( 0 ),
00045    fixed_points_( 0 ),
00046    constraints_( 0 ),
00047    constraint_to_var(),
00048    point_to_var()
00049 {
00050    {//preconditions:
00051       assert( 0 < t && t < 1 );
00052    };
00053    {//postconditions
00054       assert( this->tol() == t );
00055       assert( this->points() == 0 );
00056       assert( this->fixed_points() == 0 );
00057       assert( this->constraints() == 0 );
00058    };
00059 }
00060 
00061 
00062 
00063 total_energy_function::~total_energy_function(void)
00064 {
00065    //Do nothing
00066 }
00067 
00068 
00069 
00070 void total_energy_function::set_tol(
00071    const double t
00072    )
00073 {
00074    {//preconditions:
00075       assert( 0 < t && t < 1 );
00076    };
00077    this->tol_ = t;
00078    {//preconditions:
00079       assert( this->tol() == t );
00080    };
00081 }
00082 
00083 
00084 
00085 void assoc(
00086    total_energy_function &f,
00087    const vector< vector2 * > &po,
00088    const set< vector2 * > &fp,
00089    const vector< constraint * > &co
00090    )
00091 {
00092    {//preconditions
00093       assert( f.points() == 0 );
00094       assert( f.fixed_points() == 0 );
00095       assert( f.constraints() == 0 );
00096       assert( fp.size() <= po.size() );
00097    };
00098    f.points_ = &po;
00099    f.fixed_points_ = &fp;
00100    f.constraints_ = &co;
00101    {//compute point_to_var
00102       unsigned i = 0;
00103       for( vector< vector2 * >::const_iterator j = po.begin();
00104            j != po.end();
00105            j++ )
00106       {
00107          vector2 *pj = *j;
00108          assert( pj );
00109          if( fp.count( pj ) ) //pj is a fixed point
00110             f.point_to_var[ pj ] = total_energy_function::fixed_point;
00111          else{
00112             f.point_to_var[ pj ] = i;
00113             i += 2; //allocate variables for x and y coordinates
00114          };
00115       };
00116    };
00117    {//compute constraint_to_var
00118       const unsigned nc = co.size();
00119       f.constraint_to_var = vector< vector<unsigned> >( nc );
00120       for( unsigned i = 0; i < nc; i++ ){
00121          const vector< vector2 * > &cp( co[i]->points() );
00122          const unsigned np = cp.size();
00123          assert( 0 < np ); //otherwise, constrains nothing
00124          f.constraint_to_var[i] = vector<unsigned>( np );
00125          for( unsigned j = 0; j < np; j++ ){
00126             vector2 *p = cp[j];
00127             assert( p );
00128             assert( f.point_to_var.count( p ) );
00129             f.constraint_to_var[i][j] = f.point_to_var[ p ];
00130          };
00131       };
00132    };
00133    {//postconditions
00134       assert( f.points() == &po );
00135       assert( f.fixed_points() == &fp );
00136       assert( f.constraints() == &co );
00137    };
00138 }
00139 
00140 
00141 
00142 double total_energy_function::operator() (
00143    const vector<double> &x
00144    ) const
00145 {
00146    {//preconditions:
00147       assert( this->points() );
00148       assert( this->fixed_points() );
00149       assert( this->constraints() );
00150       assert( x.size() == this->n_vars() );
00151    };
00152    double e;
00153    vector<double> dedx( this->n_vars() );
00154    this->evaluate( x, e, dedx );
00155    //discard dedx
00156    return e;
00157 }
00158 
00159 
00160 
00161 
00162 void total_energy_function::evaluate(
00163    const vector<double> &x,
00164    double &e, //output
00165    vector<double> &gradient //output
00166    ) const
00167 {
00168    {//preconditions:
00169       assert( this->points() );
00170       assert( this->fixed_points() );
00171       assert( this->constraints() );
00172       assert( x.size() == this->n_vars() );
00173    };
00174    //f == (*this)( x )
00175    {//initialise running totals
00176       e = 0.0;
00177       gradient = vector<double>( this->n_vars() );
00178    };
00179    const unsigned n_constraints = this->constraints()->size();
00180    const double tol_c = this->tol()/double(1U + n_constraints);
00181    for( unsigned i = 0; i < n_constraints; i++ ){
00182       const constraint *c =  (*(this->constraints()))[i];
00183       assert( c );
00184       const vector< unsigned > &ctv( this->constraint_to_var[i] );
00185       const unsigned np = c->points().size();
00186       assert( 0 < np );
00187       vector< vector2 > p( np ), dedp( np );
00188       for( unsigned j = 0; j < np; j++ ){
00189          const unsigned var = ctv[j];
00190          if( var == fixed_point ){
00191             const vector2 *pj = c->points()[j];
00192             assert( pj );
00193             p[j] = *pj;
00194          }else{
00195             assert( var+1 < this->n_vars() );
00196             p[j] = vector2( x[ var ], x[ var+1 ] );
00197          };
00198       };
00199       double ep;
00200       c->energy( tol_c, p, ep, dedp );
00201       {//increase the running totals
00202          e += ep;
00203          for( unsigned j = 0; j < np; j++ ){
00204             const unsigned var = ctv[j];
00205             if( var != fixed_point ){
00206                assert( var+1 < this->n_vars() );
00207                gradient[ var ] += dedp[j].x;
00208                gradient[ var+1 ] += dedp[j].y;
00209             };//else no effect on gradient
00210          };
00211       };
00212    };
00213 }
00214 
00215 
00216 
00217 vector<double> total_energy_function::current_var(void) const
00218 {
00219    {//preconditions
00220       assert( this->points() );
00221       assert( this->fixed_points() );
00222    };
00223    vector<double> result( this->n_vars() );
00224    map< vector2 *, unsigned > &m(
00225       const_cast< map< vector2 *, unsigned > & >(
00226          this->point_to_var
00227          )); //circumvent const
00228    for( vector< vector2 *const >::iterator i = points()->begin();
00229         i != points()->end();
00230         i++ ){
00231          vector2 *p = *i;
00232          assert( p );
00233          assert( m.count( p ) );
00234          const unsigned j = m[ p ];
00235          if( j == fixed_point )
00236             ;//no variables
00237          else{ //j and j+1 are the corresponding variables
00238             assert( j+1 < this->n_vars() );
00239             result[j] = p->x;
00240             result[j+1] = p->y;
00241          };
00242    };
00243    return result;
00244 }
00245 
00246 
00247 
00248 void total_energy_function::move_points(
00249    const vector<double> & x
00250    ) const
00251 {
00252    {//preconditions:
00253       assert( x.size() == this->n_vars() );
00254    };
00255    map< vector2 *, unsigned > &m(
00256       const_cast< map< vector2 *, unsigned > & >(
00257          this->point_to_var
00258          )); //circumvent const
00259    for( vector< vector2 *const >::iterator i = points()->begin();
00260         i != points()->end();
00261         i++ ){
00262          vector2 *p = *i;
00263          assert( p );
00264          assert( m.count( p ) );
00265          const unsigned j = m[ p ];
00266          if( j == fixed_point )
00267             ;//no variables
00268          else{ //j and j+1 are the corresponding variables
00269             assert( j+1 < this->n_vars() );
00270             p->x = x[j];
00271             p->y = x[j+1];
00272          };
00273    };
00274    {//postconditions:
00275       assert( this->current_var() == x );
00276    };
00277 }

Generated at Sun Jul 14 20:38:13 2002 for Mapper by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999