[Python-de] C++ Erweiterung nach Python (mit Hilfe von SWIG) [Teil2]

Keule m_konermann at gmx.de
Sun Feb 3 17:40:34 EST 2002


Hallo nochmal !

Anbei die noch fehlenden 3 Dateien, musste ich separat schicken aufgrund 
der Grössenbeschränkung von 40 kb/ mail.


Schönen Gruss
Marcus
-------------- next part --------------
#include "basisfile.h"

filetext::filetext () {
  tlln = 0;
  tfln = 0;
  variable_pointer = NULL;
  next = NULL;
}

filetext::~filetext () {
  clean ();
}


void filetext::clean () {
  clean (this);
}

void filetext::clean (struct filetext *ft) {
  if (ft) {
    if (ft->next) { 
      clean (ft->next);
      ft->next = NULL;
    }
    variable_pointer = NULL;
    text.clean ();
    parameter_text.clean ();
  }
}

basisfile::basisfile () {
  filename = NULL;
  text = NULL;
}

basisfile::basisfile (struct string &fn) {
  filename = new struct string;
  filename->copy (fn);
  text = NULL;
}

basisfile::basisfile (char *fn) {
  init (fn);
}

basisfile::~basisfile () {
  clean ();
}

void basisfile::init (char *fn) {
  filename = new struct string;
  filename->copy (fn);
  text = NULL;
}
  

void basisfile::clean () {
  if (filename) {
    delete filename;
    filename = NULL;
  }
  if (text) {
    delete text;
    text = NULL;
  }
}

int basisfile::readfile () {
  if (!filename->size) {
    printf ("basisfile::readfile:\n No filename to read specified.\n");
    return 1;
  }
  
  /* initialize text-pointer */
  text = new struct filetext;
    
  /* Copy complete input file to text */
  text->tfln = 1;
  if ((text->tlln = text->text.filereadc (*filename, '\n')) < 0) {
    printf ("basisfile::readfile ():\n ");
    strprint (*filename, "Error while reading file `", "'.\n");
    return 1;
  }
  
  return 0;
}


int basisfile::writefile (string &otherfilename, char *mode) {
  struct filetext *help = this->text;
    
  if ( (*mode != 'a') && (*mode != 'w') ) {
    printf ("basisfile::writefile:\n Invalid mode %s ", mode);
    strprint (otherfilename, "for writing to file `", "'.\n");
    return 1;
  }
  
  FILE *out = otherfilename.fileopen (mode);

  if (out)
    while (help != NULL) {
      if (help->text.size)
	help->text.filewrite (out);
      if (help->parameter_text.size)
	help->parameter_text.filewrite (out);
      help = help->next;
    }
  else {
    strprint (otherfilename, "basisfile::writefile:\n Unable to open file `",
	      "'");
    printf (" with mode %s.\n", mode);
    return 2;
  }

  while (help != NULL) {
    if (help->text.size)
      help->text.filewrite (otherfilename, "a");
    if (help->parameter_text.size)
      help->parameter_text.filewrite (otherfilename, "a");
    help = help->next;
  }
  
  return 0;
}


int basisfile::writefile (char *mode) {
  struct filetext *help = this->text;
    
  if ( (*mode != 'a') && (*mode != 'w') ) {
    printf ("basisfile::writefile:\n Invalid mode %s ", mode);
    strprint (*filename, "for writing to file `", "'.\n");
    return 1;
  }
  
  FILE *out = filename->fileopen (mode);

  if (out) {
    while (help != NULL) {
      if (help->text.size)
	help->text.filewrite (out);
      if (help->parameter_text.size)
	help->parameter_text.filewrite (out);
      help = help->next;
    }
    fclose (out);
  }
  else {
    strprint (*filename, "basisfile::writefile:\n Unable to open file `", "'");
    printf (" with mode %s.\n", mode);
    return 2;
  }

//    while (help != NULL) {
//      if (help->text.size)
//        help->text.filewrite (*filename, "a");
//      if (help->parameter_text.size)
//        help->parameter_text.filewrite (*filename, "a");
//      help = help->next;
//    }

  return 0;
}


int basisfile::build (struct variablelist *variable) {
  struct filetext *help;

  /* Look for specified variable */
  while (variable) {
    help = this->text;
    /* search all parts of basisfile (except in parameter-text-parts) */
    while (help) {
      /* search in text */
      if (variable->linenumber <= help->tlln) {
	/* split text */
	if ( split (&help, variable) ) {
	  printf ("Error while splitting basisfile structure.\n");
	  return 1;
	}
	else
	  /* parameter found */
	  help = NULL;
      }
      else {
	/* nothing found */
	help = help->next;
      }
    }
    /* found parameter? */
    if (!variable->text) {
      printf ("Couldn't find parameter number %d.\n", variable->number);
      printf ("Probably line number %d exceeds number of lines of file.\n",
	      variable->linenumber);
      return 2;
    }
    /* look at next one */
    variable = variable->next;
  }
  return 0;
}


int basisfile::split (struct filetext **text, struct variablelist *variable, 
		      int separators) {
  int line = (*text)->tfln; 
  int linepos = 0, prepos = 0, pastpos;
  int original_size = (*text)->text.size;
  int original_tlln = (*text)->tlln;
  string help, dummy;
  int next_line_offset;
  struct filetext *hft = NULL;

  /* check text */
  if (!text || !(*text)) {
    printf ("basisfile::split:\n Empty filetext structure.  Aborting.\n");
    return 100;
  }

  /* check linenumber and position */
  if (variable->linenumber < 1) {
    printf ("basisfile::split:\n Invalid linenumber %d.\n",
	    variable->linenumber);
    return 99;
  }
  if (variable->position < 0) {
    printf ("basisfile::split:\n Invalid position %d.\n",
	    variable->position);
    return 99;
  }

  /* find right line */
  while (line < variable->linenumber) {
    linepos += (*text)->text.string_complement_span("\n", linepos) + 1;
    line++;
  }
   
  next_line_offset = (*text)->text.string_complement_span("\n", linepos) + 1;
  /* if "\n" was not found, next_line_offset is position of "\0".
     Since this character is not meant to be copied to help, we must
     decrease next_line_offset by 1 in this case. */
  if (next_line_offset+linepos == (*text)->text.size)
    help.ncopy ((*text)->text, next_line_offset-1, linepos);
  else
    help.ncopy ((*text)->text, next_line_offset, linepos);
  
  /* find beginning position of parameter-text in line */
  while (separators < variable->position) { 
    /* if not found */
    if (!(help.string_string(dummy, variable->preseparator, prepos+1))) {
      /* Does line in question continue with next struct? */
      if ( ((*text)->next) && ((*text)->next->tfln == line) )
	return (split ( &((*text)->next), variable, separators));
      else {
	printf("Problem in line no. %d:\n", line);
	printf(" Can not find more than %d", separators);
	strprint (variable->preseparator, " preseparators `", "'.\n");
	printf(" Should have found %d.\n", variable->position);
	strprint (help, "Text of the line under consideration:\n \"", "\"\n");
	return 1;
      }
    } 
    prepos = help.size - dummy.size;
    separators++;
  }

  /* if no separators were meant to be found, dummy would not contain
     the string continuing with guessed variable-text start: dummy
     would be empty. */
  if (!separators)
    dummy.copy (help);

  /* find ending position of parameter-text in line */
  if (!variable->pastseparator.size) {
    printf("Problem with specification of variable no. %d:\n", 
	   variable->number);
    printf(" pastseparatpor is empty.\n");
    return 2;
  }
  else
    if (!(help.string_string(dummy, variable->pastseparator, 
			     help.size-dummy.size 
			     + variable->preseparator.size - 1))) {
      printf("Problem in line no. %d:\n", line);
      printf(" Can not find");
      strprint (variable->pastseparator, " pastseparator `", "' after ");
      printf ("%d. ", separators);
      strprint(variable->preseparator, "presaparator `", "'.\n");
      strprint (help, "Text of the line under consideration:\n \"", "\"\n");
      return 3;
    } 

  pastpos = linepos + help.size - dummy.size;

  /* set adequat positions of beginning of parameter_text */
  prepos += linepos + variable->preseparator.size - 1;

  /* save whole text */
  dummy.copy ((*text)->text);
  /* copy non-parameter-text to text */
  (*text)->text.ncopy (dummy, prepos);
  /* breaking line no. $line means, that text last line number is $line now. */
  (*text)->tlln = line;

  /* Are we dealing with a line already splitted into text and
     paramter_text?  Then save parameter_text and variable_pointer and
     take care of the variable-pointer to this old parameter_text. */
  if ((*text)->parameter_text.size) {
    /* create new basisfile-node */
    hft = new struct filetext;
    /* save parameter_text there. */
    hft->parameter_text.copy ((*text)->parameter_text);
    /* save variable_pointer, too */
    hft->variable_pointer = (*text)->variable_pointer;
    /* redirect variablelist-pointer to new location of old parameter_text. */
    hft->variable_pointer->text = hft;
  }
  /* is some original text left behind new parameter_text?  Save it!  */
  if (pastpos < original_size) {
    /* create new basisfile-node, if not done already */
    if (!hft)
      hft = new struct filetext;
    /* save rest of the text in new node, too */
    hft->text.ncopy (dummy, original_size-pastpos-1, pastpos);
  }

  /* copy parameter-text to parameter_text */
  (*text)->parameter_text.ncopy (dummy, pastpos-prepos, prepos);
  /* link pointer of variable to according parameter_text and backlink
     pointer of *text to that same variable pointer. */
  variable->text = (*text);
  (*text)->variable_pointer = variable;
  
  /* set adequat line numbers for new node and link it to the
     structure, if new node exists. */
  if (hft) {
    /* text last line number is last line number of original text. */
    hft->tlln = original_tlln;
    /* if parameter_text does not include '\n' of original line, new
       text first line number is just the number of the breaked line
       ($line).  Otherwise new tfln is number of next line. */
    if ((*text)->parameter_text.string_character ('\n'))
      hft->tfln = line+1;
    else
      hft->tfln = line;
    /* link new node to structure.  aehm?? Take care of pointer of variable
       struct pointing to text->next. */
    hft->next = (*text)->next;
    //hbf->next->variable_pointer->text = &hbf;
    (*text)->next = hft;
  }
  return 0;
}

int vl2pt (struct variablelist *vl) {
  while (vl) {
    if (vl->text) {
      if (vl->text->parameter_text.copy (vl->x_now)) {
	printf ("vl2pt:\n ");
	printf ("Error while copying x_now to paramter text.\n");
	return 1;
      }
    }
    else {
      printf ("vl2pt:\n ");
      printf ("Cannot find paramter text for variable no. %d.\n", 
	      vl->number);
      return 2;
    }
    vl = vl->next;
  }
  return 0;
}

void print (struct filetext *ft) {
  while (ft) {
    printf ("tfln = %d\ttlln = %d\n", ft->tfln, ft->tlln);
    printf ("variablen_pointer->nummer = ");
    if (ft->variable_pointer)
      printf("%d\n", ft->variable_pointer->number); 
    else
      printf("\n");
    strprint (ft->text, "text:\n `", "'\n");
    strprint (ft->parameter_text, "parameter_text: `", "'\n");
    ft = ft->next;
  }
}
-------------- next part --------------
#include "safe_string.h"
#include "variable.h"

#include <math.h>

string::string ()
{
  size = 0;
  str = NULL;
  label = NULL;
}


string::string ( int s, char *l )
{
  init ( s, l );
}


string::string ( char *s, char *l )
{
  size = strlen ( s ) + 1;
  init ( size, l );
  strcpy ( str, s );
}


string::string ( string &s, char *l )
{
  str = NULL;
  size = 0;
  label = l;
  copy ( s );
}


string::~string ()
{
  clean ();
}

void
string::clean ()
{
  if ( str )
    delete [] str;
  str = NULL;
}


void
string::init ( int s, char *l )
{
  if ( s ) {
    size = s;
    str = new char [ s ];
  }
  else
    str = NULL;
  if ( l ) {
    label = new char [ strlen ( l ) + 1 ];
    strcpy ( label, l );
  }
  else
    label = NULL;
}


string &
string::operator = ( string &s )
{
  size = s.size;
  str = s.str;
  label = s.label;
  return *this;
}


void
string::check_index ( int i )
{
  if (  ( i < 0 )  ||  ( i >= size )  )
    {
      printf ( "string::check_index ( %d )", i );
      if ( label )
	printf ( " %s", label );
      printf ( ": Access out of bounds.\n" );
      exit (0);
    }
}


struct string &
string::copy ( string &s )
{
  if ( this->str == s.str )
    return *this;
  
  if ( str )
    delete [] str;
  
  if ( !s.str ) {
    size = 0;
    str = NULL;
    return *this;
  }
  
  size = s.size;
  str = new char [ size ];
  for ( int i=0; i < size; i++ )
    (*this) (i) = s (i);

  return *this;
}


struct string &
string::copy ( char *s )
{
  if ( this->str == s )
    return *this;

  if ( str )
    delete [] str;
  
  size = strlen ( s ) + 1;
  str = new char [ size ];

  for ( int i=0; i < size-1; i++ )
    (*this) (i) = s [i];

  str[size-1] = '\0';

  return *this;
}


int string::copy (double d, long int decimal) {
  /* check decimal */
  if (decimal<0) {
    printf ("string::copy:\n Invalid value of decimal: %d\n", decimal);
    return 1;
  }
  decimal;
  /* number of digits before dot */
  int digits = 0;
  /* number of characters for sprintf-format-string "%fdigits.decimal" */
  /* 4 = '%' 'f' '.' */
  int noc = 3;
  /* calculate number of digits needed to print d */
  /* watch out for negative numbers */
  if ( d < 0 )
    digits += (int)log10(-d) + 2;
  else
    if ( d == 0 ) {
      digits = 1;
      noc++;
    }
    else
      digits += (int)log10(d) + 1;

  /* calculate number of characters needed to print format string */
  noc += (int)log10(digits)+1 + (int)log10(decimal)+1;

  /* build format string */
  char *formatstring = new char [noc];
  sprintf (formatstring, "%%%d.%df", digits, decimal);
    
  /* build string */
  str = new char [ digits + decimal + 2 ];
  sprintf ( str, formatstring, d );
  str[digits + decimal+1] = '\0';
    
  delete [] formatstring;
  
  return 0;
}

int string::copy (int i) {
  /* number of digits */
  int digits = 0;
  /* calculate number of digits needed to print d */
  /* watch out for negative numbers */
  if ( i < 0 )
    digits += (int)log10(-(double)i) + 2;
  else
    if ( i == 0 )
      digits = 1;
    else
      digits += (int)log10(double(i)) + 1;

  /* build string */
  init ( digits + 1 );
  sprintf ( str, "%d", i );
  str[digits] = '\0';

  return 0;
}


int string::copy (struct variable *v) {
  if (!v) {
    printf ("string::copy(struct variable *v):\n");
    printf (" No variable given.\n");
    return 1;
  }
  switch (v->type) {
  case 'i': /* integer */
    copy (v->iv);
    break;
  case 'd': /* double */
//      for (int run = 0; run < 500000; run++) {
//        printf ("run = %d\n", run);
//        fflush(NULL);
      copy (v->dv, v->dprecision);
      //    }
      //return 1;
    break;
  case 's': /* string */
    copy (*(v->sv));
    break;
  default: /* Unknown type */
    printf ("string::copy:\n Unknown type `%c' of struct variable.\n", 
	    v->type);
    return 1;
  }
  return 0;
}

void
string::out (char **s) {
  *s = new char [size];
  strcpy (*s, str);
}

string &
string::compose ( string &first, string &second, char *inbetween )
{
  copy ( first );
  cat ( inbetween );
  cat ( second );
  return *this;
}


string &
string::compose ( string &first, char *second, char *inbetween )
{
  copy ( first );
  cat ( inbetween );
  cat ( second );
  return *this;
}

string &
string::compose ( string &first, double second, char *inbetween )
{
  char help[1000000];
  sprintf(help, "%g", second);
  copy ( first );
  cat ( inbetween );
  cat ( help );
  return *this;
}

string &
string::compose ( string &first, int second, char *inbetween )
{
  char help[1000000];
  sprintf(help, "%d", second);
  copy ( first );
  cat ( inbetween );
  cat ( help );
  return *this;
}

int
string::element ( int i )
{
  return str[i];
}

int
string::compare ( string &s )
{
  return strcmp ( this->str, s.str );
}


int
string::compare ( char *s )
{
  if ( this->str )
    if ( strcmp ( this->str, s ) )
      return 1;
    else
      return 0;
  return -1;
}

int string::string_span ( char *stopset, int offset ) {
  return (strspn (str+offset, stopset)); 
}

int string::string_span ( string &stopset, int offset ) {
  return (strspn (str+offset, stopset.str)); 
}

int string::string_complement_span ( char *stopset ) {
  return (strcspn (str, stopset));
}

int string::string_complement_span ( char *stopset, int offset ) {
  return (strcspn (str+offset, stopset)); 
}

int string::string_complement_span ( string &stopset, int offset ) {
  return (strcspn (str+offset, stopset.str)); 
}

int string::string_string ( struct string &result, char *needle ) {
  char *help;
  if ((help = strstr(str, needle))) {
    result.copy(help);
    return 1;
  }
  else
    return 0;
}

int string::string_string ( struct string &result, struct string &needle ) {
  char *help;
  if ((help = strstr(str, needle.str))) {
    result.copy(help);
    return 1;
  }
  else
    return 0;
}

int string::string_string ( struct string &result, struct string &needle, 
			    int offset ) {
  char *help;
  if ((help = strstr(str+offset, needle.str))) {
    result.copy(help);
    return 1;
  }
  else
    return 0;
}

int string::string_character ( char c ) {
  if (strchr(str, c))
    return 1;
  else
    return 0;
}


void string::string_pointer_break ( string &result, char *needle ) {
  result.copy (strpbrk (str, needle));
}


struct string &
string::ncopy ( string &s, int n )
{
  if ( str )
    delete [] str;

  if ( n > s.size )
    size = s.size;
  else
    size = n + 1;

  if ( size )
    {
      str = new char [ size ];
      
      for ( int i=0; i < size-1; i++ )
	(*this) (i) = s (i);
      (*this) ( size-1 ) = '\0';
    }
  return *this;
}


struct string &
string::ncopy ( string &s, int n, int offset )
{
  if ( n + offset >= s.size )
    {
      printf ( "Error in string::ncopy : ");
      printf ( "  n=%d, offset=%d, s.size=%d\n", n, offset, s.size );
      printf ( "    Hint: size includes `\\0'.\n" );
      exit ( 1 );
    }

  if ( str )
    delete [] str;

  if ( n > s.size-offset )
    size = s.size-offset;
  else
    size = n + 1;

  if ( size )
    {
      str = new char [ size ];
      
      for ( int i=0; i < size-1; i++ )
	(*this) (i) = s (i+offset);
      (*this) ( size-1 ) = '\0';
    }
  return *this;
}


string &
string::cat ( string &s )
{
  string help ( str );

  size += s.size-1;

  if ( str )
    delete [] str;

  str = new char [ size ];

  for ( int i=0; i < size; i++ )
    if ( i < help.size-1 )
      (*this)(i) = help (i);
    else
      (*this)(i) = s (i-help.size+1);
  
  return *this;
}


string &
string::cat ( char *s )
{
  if ( !s )
    return *this;
  
  if ( !str )
    {
      copy ( s );
      return *this;
    }
  
  string help ( str );
  
  size += strlen ( s );
  
  if ( str )
    delete [] str;
  
  str = new char [ size ];
  
  for ( int i=0; i < size; i++ )
    if ( i < help.size-1 )
      (*this)(i) = help (i);
    else
      (*this)(i) = s [ i-help.size+1 ];
  
  return *this;
}


FILE * 
string::fileopen ( char *s )
{
  return ( fopen ( str, s ) );
}

int
string::fileread (string &file) {
  FILE *in;;
  int number = 0;
    
  /* Count number of characters of input file */
  /* open file */
  if ((in = file.fileopen("r"))==NULL) {
    strprint (file, "Cannot open file `", "'.\n");
    return 1;
  }
  /* Count */
  while ( fgetc(in) != EOF )
    number++;
  /* close file */
  fclose (in);

  /* Copy file to string */
  /* open again */
  if ((in = file.fileopen("r"))==NULL) {
    strprint (file, "Cannot open file `", "'.\n");
    printf ("Since I've been able to open it recently, something really");
    printf ("strange is going on.\n");
    return -1;
  }
  /* get memory */
  init (number);
  /* copy */
  for (int i=0; i<number; i++)
    str[i] = fgetc(in);
  return 0;
}

int
string::filereadc (string &file, char c) {
  FILE *in;
  int characters = 1;
  int counter = 0;
  char ch;

  /* Count number of characters of input file and number of c's */
  /* open file */
  if ((in = file.fileopen("r"))==NULL) {
    strprint (file, "Cannot open file `", "'.\n");
    return -1;
  }
  /* Count */
  while ( (ch = fgetc(in)) != EOF ) {
    characters++;
    if ( ch == c )
      counter++;
  }
  /* close file */
  fclose (in);

  /* Copy file to string */
  /* open again */
  if ((in = file.fileopen("r"))==NULL) {
    strprint (file, "Cannot open file `", "'.\n");
    printf ("Since I've been able to open it recently, something really");
    printf ("strange is going on.\n");
    return -1;
  }
  /* get memory */
  init (characters);
  /* copy */
  for (int i=0; i<characters-1; i++)
    str[i] = fgetc(in);
  str[characters-1] = '\0';
  
  fclose (in);
  
  return counter;
}

int string::filewrite (string &file, char *mode) {
  if ( (*mode != 'a') && (*mode != 'w') ) {
    printf ("string::filewrite:\n Invalid mode %s ", mode);
    strprint (file, "for writing string to file `", "'.\n");
    return 1;
  }

  FILE *out = fopen (file.str, mode);
  if (out) {
    fprintf (out, "%s", str);
    fclose (out);
  }
  else {
    strprint (file, "string::filewrite:\n Unable to open file `", "'");
    printf (" with mode %s.\n", mode);
    return 2;
  }
    
  return 0;
}


int string::filewrite (FILE *out) {
  if (out)
    fprintf (out, "%s", str);
  else {
    printf ("string::filewrite:\n file pointer = NULL.\n");
    return 1;
  }
    
  return 0;
}


int string::system_call () {
  return system (str);
}

void
print ( struct string &s )
{
  printf ( "string " );
  if ( s.label )
    printf ( " %s ", s.label );
  printf ( " = \"" );
  for ( int i=0; i<s.size-1; i++ )
    printf ( "%c", s(i) );
  printf ("\"\n");
  return;
}


void 
strprint ( struct string &s, char *first, char *last )
{
  if ( first )
    printf ( "%s", first );    
  for ( int i=0; i < s.size - 1; i++ )
    printf ( "%c", s(i) );
  if ( last )
    printf ( "%s", last );    
  return;
}

void 
strprint ( struct string &s, int offset, char *first, char *last )
{
  if ( first )
    printf ( "%s", first );    
  for ( int i=offset; i < s.size - 1; i++ )
    printf ( "%c", s(i) );
  if ( last )
    printf ( "%s", last );    
  return;
}

void 
strprint ( struct string &s, int offset, char stop, char *first, char *last )
{
  if ( first )
    printf ( "%s", first );    
  
  int i = offset;
  while ( (i < s.size-1) && (s(i) != stop) ) {
    printf ( "%c", s(i) );
    i++;
  }

  if ( last )
    printf ( "%s", last );    
  return;
}

-------------- next part --------------
#include "simanneal.h"

#include <time.h>
#include <math.h>

#include "calculate.h"

simanneal_varlist::simanneal_varlist () {
  vl = NULL;
  next = NULL;
}

simanneal_varlist::~simanneal_varlist () {
  clean (this);
}

void simanneal_varlist::clean () {
  clean (this);
}

void simanneal_varlist::clean (struct simanneal_varlist *svl) {
  if (svl) {
    if (svl->next) {
      clean (svl->next);
      svl->next = NULL;
    }
    vl->clean ();
  }
}

int simanneal_varlist::pt2xn () {
  struct simanneal_varlist *help = this;
  while (help) {
    if (help->vl->pt2xn (1)) {
      printf ("simanneal_varlist::pt2xn ():\n ");
      printf ("Error while copying parameter text to x_now of variable no. %d",
	      help->vl->number);
      printf ("\n");
      return 1;
    }
    help = help->next;
  }
  return 0;
}

int x_now_2_x_opt (struct simanneal_varlist *svl) {
  while (svl) {
    if (!svl->vl) {
      printf ("x_now_2_x_opt ():\n ");
      printf ("Empty variable list!.\n");
      return 1;
    }
    if (!svl->vl->x_opt) {
      printf ("x_now_2_x_opt ():\n ");
      printf ("Empty x_opt in variable list!.\n");
      return 1;
    }
    if (!svl->vl->x_now) {
      printf ("x_now_2_x_opt ():\n ");
      printf ("Empty x_now in variable list!.\n");
      return 1;
    }

    svl->vl->x_opt->copy (svl->vl->x_now);
    svl = svl->next;
  }
  return 0;
}

simulated_annealing::simulated_annealing () {
  vl = NULL;
  svl = NULL;
  text = NULL;
  success = NULL;
  call = NULL;
};

simulated_annealing::simulated_annealing (struct variablelist *vlist, 
					  struct basisfile *bf, 
					  struct evaluate *eval,
					  int tm, double tf, 
					  struct string *syscall) {
  tc_max = tm;
  t_factor = tf;
  vl = vlist;
  text = bf;
  success = eval;
  call = syscall;
}


simulated_annealing::~simulated_annealing () {
  vl = NULL;
  svl = NULL;
  text = NULL;
  success = NULL;
  call = NULL;
}

int simulated_annealing::build_varlist () {
  struct simanneal_varlist *help = NULL;
  struct variablelist *helpvl = vl;

  while (helpvl) {
    if (helpvl->number > 0) {
      if (help) {
	help->next = new struct simanneal_varlist;
	help = help->next;
      }
      else {
	svl = new struct simanneal_varlist;
	help = svl;
      }
      help->vl = helpvl;
    }
    helpvl = helpvl->next;
  }
  
  if (!help) {
    printf ("simulated_annealing::build_varlist:\n");
    printf (" No valid variables found.\n");
    return 1;
  }
  return 0;
}

int simulated_annealing::optimize ()
{
  /* Value of calculation with valid vector */
  struct variable f_x;
  f_x.init (0.0, 10);
  /* Value of calculation with new vector */
  struct variable f_x_dx;
  f_x_dx.init (0.0, 10);
  /* temperature */
  double temperature = 1;
  /* counter of times of temperature increasement */
  int tc = 1;
  int take;

  /* initialize random number generator */
  time_t init_rand;
  time (&init_rand);
  srand (init_rand);

  /* calculate with first vector */
  if (calculate (f_x, text, call)) {
    printf ("simulated_annealing::optimize ():\n ");
    strprint (*call, "Error while trying to execute\n  `", "'\n");
    return 1;
  }

  while (!success->abort(f_x)) {
    /* build next variation of vector x */
    if (vary_simvarlist ()) {
      printf ("simulated_annealing::optimize ():\n");
      printf (" Error while building new variable vector.\n");
      return 1;
    }

      /* calculate for next variation of vector */
    if (calculate (f_x_dx, vl, text, call)) {
      strprint (*call, "Error while executing\n  ", "\n");
      return 1;
    }
    
    /* evaluate result */
    if ((take = take_new_result (f_x_dx, f_x, temperature)) < 0) {
      printf ("simulated_annealing::optimize:\n");
      printf (" Error while evaluating new result.\n");
      return 1;
    }


    if (take) {
      /* new result is better */
      f_x = f_x_dx;
      /* => x_now becomes new x_opt */
      x_now_2_x_opt (svl);
      /* reset temperature counter */
      tc = 1;
      /* testy */
      printf ("%g\n", svl->vl->x_now->dv);
    }
    else {
      if (tc++ == tc_max) {
	tc = 1;
	temperature *= t_factor;
      }
    }
  }
  return 0;
}

int simulated_annealing::take_new_result (struct variable &fnew, 
					  struct variable &fold, double t) {
  double old;
  double test;
  switch (fnew.type) {
  case 'd' : /* double value */
    if (read_double(old, &fold)) {
      printf ("simulated_annealing::take_new_result:\n");
      printf (" Error while reading `fold'.\n");
      return -1;
    }
    test = (double)rand()/RAND_MAX;
    if ( (fnew.dv < old) 
	 || (exp((old-fnew.dv)/t) > (double)rand()/RAND_MAX)
	 )
      return 1;
    return 0;
    break;
  case 'i' : /* integer value */
    printf ("simulated_annealing::take_new_result:\n");
    printf (" Comparison with integers isn't implemented yet.\n");
    return -1;
    break;
  case 's' : /* string value */
    printf ("simulated_annealing::take_new_result:\n");
    printf (" Comparison with strings isn't implemented yet.\n");
    return -1;
    break;
  default :
    printf ("simulated_annealing::take_new_result:\n");
    printf (" Unknown type of `fnew' `%c'.\n", fnew.type);
    return -1;
  }
  return 0;
}


int simulated_annealing::vary_simvarlist ()
{
  struct simanneal_varlist *help = svl;
  while (help) {
    if (!help->vl->sap) {
      printf("simulated_annealing::vary_simvarlist():\n");
      printf(" No simulated annealing parameters found for variable no. %d.\n",
	     help->vl->number);
      return 1;
    }
    if (random_step (help->vl->x_now, help->vl->sap->dx)) {
      printf ("simulated_annealing::vary_simvarlist():\n");
      printf (" Error while making random step of variable no. %d.\n",
	      help->vl->number);
      return 1;
    }
    help = help->next;
  }
  return 0;
}

//  double 
//  simulated_annealing::amotsa (matrix &p, vector &y, vector &psum, int ndim, vector &pb, 
//  		   double *yb, int ihi, double *yhi, double fac, double tt,
//  		   struct antenna_list *antenna, double f, double k,
//  		   int (*e_func)(complex<double> &E,radiator_list *send, 
//  				 double x, double y, double z, double f, 
//  				 double beta, complex<double> rho,
//  				 char receive_type, char polarization, 
//  				 char field, int posnum)) {
//    int j;
//    double fac1, fac2, yflu, ytry;
//    vector ptry (ndim, "ptry");
  
//    fac1 = (1.0-fac)/ndim;
//    fac2 = fac1-fac;
//    for (j=0; j<ndim; j++)
//      ptry(j) = psum(j)*fac1 - p(ihi,j)*fac2;

//    /* copy try values to antenna */
//    for (int i=0; i<antenna->cl->size; i++) 
//      *(antenna->cl->c[i]) = ptry(i);
//    if (guete_e_position (ytry, f, k, antenna, e_func)) {
//      printf("calculate::amotsa ():\n ");
//      printf("Error while calculating target function value.\n");
//      return 1;
//    }

//    if (ytry <= *yb) {
//      /* try is better => take try! (antenna already holds the
//         try-values) */
//      pb = ptry;
//      *yb = ytry;
//    }
//    else {
//      /* try is worse => discard try.  antenna holds the try-values:
//         restore the pb values to antenna! */
//      for (int i=0; i<antenna->cl->size; i++) 
//        *(antenna->cl->c[i]) = pb(i);
//    }
//    yflu = ytry-tt*log((double)rand()/RAND_MAX);
//    if (yflu < *yhi) {
//      y(ihi) = ytry;
//      *yhi = yflu;
//      for (j=0; j<ndim; j++) {
//        psum(j) += ptry(j)-p(ihi,j);
//        p(ihi,j)=ptry(j);
//      }
//    }
//    return yflu;
//  }

//  int
//  calculate::simuann (double &e_max, double &x_max, double &y_max, double &z_max,
//  		    double &angle_max, antenna_list *antenna, matrix &p_ini, 
//  		    double temperature, double f, double k, 
//  		    int (*e_func)(complex<double> &E,radiator_list *send, 
//  				  double x, double y, double z, double f, 
//  				  double beta, complex<double> rho,
//  				  char receive_type, char polarization, 
//  				  char field, int posnum),
//  		    int biter, int itm, double tfe, double td) {

//    int itermax = itm;
//    double tdecrease = td;
//    double tfactorend = tfe;
//    double oldbest = -1e99;
//    int bigiterate_max = biter;
//    string filename;

//    // Randomgenerator initialisieren
//    time_t init_rand;
//    time (&init_rand);
//    srand (init_rand);
//    // Numerical Recipies in C, p. 452 ff.
  
//    double tt, sum;
//    int n,m;

//    /* number of variables to vary */
//    int ndim = antenna->cl->size;       
//    int mpts = ndim + 1;
//    int i, ilo, ihi, j;
//    double yhi, ylo, ynhi, yt, ytry, ysave;
//    double rtol, swap;
//    vector psum (ndim, "psum");
//    vector pb (ndim, "p best ever");
//    vector y (ndim+1, "y");
//    double yb = 1e99;
//    struct matrix p (p_ini, "point simplex matrix");

//    double ftol = 1e-6;
//    int iter;

//    double verybest = 1e99;
//    vector verybestpoint (ndim, "very best point ever found");

//    for (int bigiterate = 0; bigiterate < bigiterate_max; bigiterate++){
//          p = p_ini;

//      //    print (p);

//      yb = 1e99;
//      zero (pb);
    
//      /* calculate first vector (for edges of simplex described by p) */
//      for (i=0; i<y.size; i++) {
//        /* copy edge coordinates to vector coordinates */
//        for (j=0; j<p.cols; j++)
//  	*(antenna->cl->c[j]) = p(i,j);
//        if (guete_e_position (y(i), f, k, antenna, e_func)) {
//  	printf("calculate::simuann ():\n ");
//  	printf("Error while calculating target function.\n");
//  	return 1;
//        }
//      }
    
//      tt = -temperature;
    
    
//      while (-tt > tfactorend * temperature) {
//        //     printf (" tt = %g\n", tt);
//       iter = itermax;
      
//        // GET_PSUM
//        for (n=0; n<ndim; n++) {
//  	for (sum = 0, m=0; m<mpts; m++)
//  	  sum += p(m,n);
//  	psum(n) = sum;
//        }
      
//        //      print (psum);
      
//        for (;;) {
//  	ilo = 0;
//  	ihi = 1;
//  	ynhi = ylo = y(ilo) + tt*log((double)rand()/RAND_MAX);
//  	yhi = y(ihi) + tt*log((double)rand()/RAND_MAX);
//  	if (ylo > yhi) {
//  	  ihi = 0;
//  	  ilo = 1;
//  	  ynhi = yhi;
//  	  yhi = ylo;
//  	  ylo = ynhi;
//  	}
//  	for (i=2; i<mpts; i++) {
//  	  yt = y(i)+tt*log((double)rand()/RAND_MAX);
//  	  if (yt <= ylo) {
//  	    ilo = i;
//  	    ylo = yt;
//  	  }
//  	  if (yt > yhi) {
//  	    ynhi = yhi;
//  	    ihi = i;
//  	    yhi = yt;
//  	  }
//  	  else 
//  	    if (yt > ynhi)
//  	      ynhi = yt;
//  	}
//  	rtol = 2*fabs(yhi-ylo)/(fabs(yhi)+fabs(ylo));
//  	//printf ("\nrtol = %g\t iter = %d\n", rtol, iter);
//  	if (rtol < ftol || iter < 0) {
//  	  swap = y(0);
//  	  y(1) = y(ilo);
//  	  y(ilo) = swap;
//  	  for (n=0; n<ndim; n++) {
//  	    swap = p(0,n);
//  	    p(0,n) = p(ilo,n);
//  	    p(ilo,n) = swap;
//  	  }
//  	  break;
//  	}
//  	iter -= 2;
	
//  	/* Begin a new iteration. */
//  	/* Try extrapolation through the face of the simplex by a
//             factor of -1 across from the high point. (reflection of the
//             simplex from the high point. */
//  	ytry = amotsa(p, y, psum, ndim, pb, &yb, ihi, &yhi, -1.0, tt, 
//  		      antenna, f, k, e_func);
//  	if (ytry <= ylo) 
//  	  /* Reflection try leads to a better result.  So try an
//               additional extrapolation by a factor of 2. */
//  	  ytry = amotsa(p, y, psum, ndim, pb, &yb, ihi, &yhi, 2.0, tt,
//  			antenna, f, k, e_func);
//  	else 
//  	  if (ytry >= ynhi) {
//  	    /* reflected point is worse than the second-highest, so
//  	       look for an intermediate lower point, i.e. do a
//  	       one-dimensional contraction. */
//  	    ysave = yhi;
//  	    ytry =amotsa(p, y, psum, ndim, pb, &yb, ihi, &yhi, 0.5, tt,
//  			 antenna, f, k, e_func);
//  	    if (ytry >= ysave) {
//  	      /* The high point seems to stay.  So better contract
//                   around the lowest (i.e. best) point. */
//  	      for (i=0; i<mpts; i++)
//  		if (i!=ilo) {
//  		  for (j=0; j<ndim; j++) {
//  		    psum(j) = 0.5*(p(i,j)+p(ilo,j));
//  		    p(i,j) = psum(j);
//  		  }
//  		  for (int u=0; u<psum.size; u++)
//  		    *(antenna->cl->c[u]) = psum(u);
//  		  if (guete_e_position (y(i), f, k, antenna, e_func)) {
//  		    printf("calculate::simuann ():\n ");
//  		    printf("Error while calculating target function.\n");
//  		    return 1;
//  		  }
//  		}
//  	      iter -= ndim;
//  	      // GET_PSUM
//  	      for (n=0; n<ndim; n++) {
//  		for (sum = 0, m=0; m<mpts; m++)
//  		  sum += p(m,n);
//  		psum(n) = sum;
//  	      }
//  	    }
//  	  }
//  	  else
//  	    ++iter;
//        }

//        tt *= tdecrease;
//        if (oldbest != yb) {
//  	oldbest = yb;
//        }
//      }
    
//      if (verybest > yb) {
//        verybest = yb;
//        for (int q=0; q<pb.size; q++)
//  	verybestpoint(q) = pb(q);
//      }
//    }

//    e_max = 1/verybest*1/verybest;
//    x_max = antenna->x;
//    y_max = antenna->y;
//    z_max = antenna->z;

//    return 0;
//  }


More information about the Python-de mailing list