Self-value management

From Remeis-Wiki
Jump to navigation Jump to search

This page is under construction

Although the code below is very short (52 lines), its advantages are enormous. Thus, the explanation takes a while and is not written yet ;-)

It combines

to prevent values to be calculated multiple times (e.g. cosine of an angle). This is especially very helpful for more complex codes, in which there are many 'shared' values, as the user only has to think about it once when setting up the svm-object. Afterwards the svm-object does all the work on its one!

  • NOTES:
    • Runtime is around twice as slow as compared to same code coded straight forward, which is due to the function calling!
private define define_retrun_function( return_fields ){
  if(typeof(return_fields) != Array_Type) return_fields = [return_fields];
  
  variable f;
  foreach f ( return_fields )
    eval(sprintf("private define return_%s(obj) { return obj.data.%s; };", f, f));
}

private define define_calculation_function( field, execute ){
  if(typeof(field) != Array_Type) field = [field];

  variable tempfun = "";
  variable f,ff;
  foreach f (field){
    tempfun += sprintf("private define calculate_%s(obj) {", f);
    tempfun += sprintf("(%s) = %s;", strjoin("obj.data."+field, ","), execute);
    foreach ff (field)
      tempfun += sprintf("obj.%s = &return_%s;", ff, ff);
    tempfun += sprintf("return obj.data.%s;", f);
    tempfun += "}";
    eval(tempfun);
  }
}

private define reset_fields( obj ){
  variable fieldnames = get_struct_field_names( obj.data );
  variable f;
  foreach f (fieldnames){
    set_struct_field( obj, f, eval(sprintf("&calculate_%s", f)));
    set_struct_field( obj.data, f, NULL );
  }
}


define object_init() {
  variable fieldnames = [ "sint","cost","fun" ];
  define_retrun_function( fieldnames );
  define_calculation_function(["sint","cost"], "sincos(obj.input.theta)");
  define_calculation_function( "fun", "obj.cost()+obj.sint()");
  
  % Actual object
  variable obj = struct_combine(struct{
    data = struct_combine(fieldnames), % Storage for field values
    input = struct{ theta = 0. },
    reset = &reset_fields
  },fieldnames); % Adding defined fields

  % Initialize object fields with pointers to calulating functions
  reset_fields( obj );
  
  return obj;
}

Now, let's have a look on the output of the following commands:

isis> variable a = object_init;
isis> print(a);
{data=Struct_Type with 3 fields,
 input=Struct_Type with 1 fields,
 sint=&calculate_sint,
 cost=&calculate_cost,
 fun=&calculate_fun}
isis> a.fun();
1.0
isis> print(a);
{data=Struct_Type with 3 fields,
 input=Struct_Type with 1 fields,
 sint=&return_sint,
 cost=&return_cost,
 fun=&return_fun}
isis>