Tutorial 2d – Likelihood function evaluated with external application

In this tutorial we use an external application to evaluate the likelihood function. In Tutorial 1g we showed already how to couple an external application with Fesslix. However, in Tutorial 1g the files used for input and output of the external application are quite primitive. In this tutorial, we show you how to couple external applications that require more complex input and output files.

This tutorial is based on Tutorial 2a. Please perform Tutorial 2a before you start with this tutorial. The code given in this tutorial (Tutorial 2d) replaces the code given in Section 1.3 of Tutorial 2a. The code given in Sections 1.1 and 1.2 of Tutorial 2a precedes all code given in this tutorial (Tutorial 2d); and the code given in Sections 1.4 and 1.5 of Tutorial 2a succeedes all code given in this tutorial (Tutorial 2d).

1   Step by Step Instruction

1.1   Create the external application

In this tutorial we use an external application written in C++ that has source code:

C++-file main.cpp
#define _USE_MATH_DEFINES
#include <iostream>
#include <fstream>
#include <cmath>

int main(int argc, char **argv) {

  std::ifstream ifile("tutorial_2d_input.dat");
  char tmpstr[256];
  char tmpchar;
  ifile.getline(tmpstr,256);
  ifile.getline(tmpstr,256);
  for (int i=0;i<5;++i) {
    ifile.get(tmpchar);
  }
  double x1, x2;
  ifile >> x1;
  ifile.getline(tmpstr,256);
  for (int i=0;i<5;++i) {
    ifile.get(tmpchar);
  }
  ifile >> x2;

  double h1 = 3.13; // the 1st observed eigenfrequency
  double h2 = 9.83; // the 2nd observed eigenfrequency
  double sgma_e = 1./16.; // the standard deviation associated with the observation errors
  double k = 29.7e6; // multiplying this value with the random variables x1 and x2 gives the stiffness values
  double m1 = 16.531e3; // the lumped mass associated with the 1st DOF
  double m2 = 16.131e3; // the lumped mass associated with the 2nd DOF
  double a = m1*m2; // a constant that is needed in the model

  double k1 = x1*k;
  double k2 = x2*k;
  double b = -m1*k2-m2*(k1+k2);
  double c = sqrt(b*b-4*a*k1*k2);
  double f1 = sqrt((-b-c)/(2*a))/2/M_PI;
  double f2 = sqrt((-b+c)/(2*a))/2/M_PI;
  double J = pow(pow(f1/h1,2)-1,2)+pow(pow(f2/h2,2)-1,2);
  double res = exp(-J/(2*pow(sgma_e,2)));

  std::ofstream ofile("tutorial_2d_output.dat");
  ofile << "Placeholder text ..." << std::endl;
  ofile << " x1 is " << x1 << std::endl;
  ofile << " likelihood is " << res << std::endl;
  ofile << " x2 is " << x2 << std::endl;
  ofile << "Goodbye!" << std::endl;

  return 0;
}

If you want to compile the application by yourself, name the final executable tutorial_2d_extapp. Alternatively, pre-build are available for download (see download-link at bottom of this page).

The application expects as input a file named tutorial_2d_input.dat and writes the result of the limit-state evaluation to a file named tutorial_2d_output.dat. An example of a potential input and output file is given in the following:

File tutorial_2d_input.dat
Some arbitrary text.
Even more text.
x1 = 6.073741493047e-01;
x2 = 7.852643585504e-01 another text
Hello World!


File tutorial_2d_output.dat
Placeholder text ...
x1 is 0.607374
likelihood is 0.0117616
x2 is 0.785264
Goodbye!

1.2   Fesslix parameter file

Before we start with the actual parameter file, we create a template (named tutorial_2d_input.dat_template) for the input file that our external application expects:

File tutorial_2d_input.dat_template
Some arbitrary text.
Even more text.
x1 = @{x1};
x2 = @{x2} another text
Hello World!

Note: we inserted @{VARNAME} at the positions in the file where the current realizations of the random variables should be placed. We will tell Fesslix to parse this template-file and replace all occurrences of this type with the value of the scalar variable that has name VARNAME.

The likelihood function that employs the external application tutorial_1g_extapp can be stated as follows:

Fesslix parameter file
fun likeli(2) = objexec(:res,{
  # Open the file to which the imput should be written:
    filestream fs ("tutorial_2d_input.dat");
  # write values of input parameters to x1 and x2:
    const x1 = $1;
    const x2 = $2;
  # We prepared a template-input file with special syntax:
    file_filter_cv ( "tutorial_2d_input.dat_template" ) { stream=fs; };
    # please have a look at this template file to grasp how it works!
  # execute external application
    if (is_win) {
      run_external "tutorial_2d_extapp.exe";
    } else {
      run_external "./tutorial_2d_extapp";
    };
  # read result from file
    strconst ostr = $strfromfile("tutorial_2d_output.dat");
      # 'strfromfile' stores the content of 'tutorial_2d_output.dat'
      # in string-variable 'ostr'
    strconst ostr = $substr($strconst(ostr),s:"likelihood is");
      # truncates everything before 'likelihood is' from string variable 'ostr'
    const res = numberfromstring(ostr);
      # retrieves the next number in string variable 'ostr'
  }::{x1,x2});

2   The complete input files of this tutorial

fesslix.org – Home  |  Contact  |  Impressum  |  © 2015-2017 Wolfgang Betz