py4sci

Table Of Contents

Previous topic

Using PUQ Read

Next topic

Handling Output

This Page

Making PUQ Work With Your Code

PUQ makes no assumptions about how your test program (or simulation) code works. However it does need a way to pass parameter values into the test program and read results.

C Programs

In this example, we use a test program compiled in C. The point of this is to show how to pass parameters to test programs that do not use the “–varname=value” pattern we have been using.

The test program is puq/examples/rosen/rosen_cprog.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include "dump_hdf5.h"

int main(int argc, char *argv[]) {
	int c;
	double x, y, z;
	while ((c = getopt(argc, argv, "x:y:")) != -1)
		switch (c) {
		case 'x':
			x = atof(optarg);
			break;
		case 'y':
			y = atof(optarg);
			break;
		default:
			printf("Usage: %s -x val -y val\n", argv[0]);
			return(1);
		}

	/* compute rosenbrock function */
	z = 100.0 * (y - x*x)*(y - x*x) + (1.0 - x)*(1.0 - x);

	dump_hdf5_d("z", z, "f(x,y)");

	/* important! return code of 0 indicates success */
	return 0;
}

Note

dump_hdf5_d() dumps a double in our output format. It is included in dump_hdf5.h.

You can compile it and test it out:

~/puq/examples/rosen> gcc -o rosen_cprog rosen_cprog.c
~/puq/examples/rosen> ./rosen_cprog -x 0 -y 1
HDF5:{'name':'z','value':1.0100000000000000e+02,'desc':'f(x,y)'}:5FDH

It works the same as the python version. To use it, we need to make a simple change to our control script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from puq import *

def run(lev=2):
    # Declare our parameters here
    p1 = Parameter('x', 'x', min=-2, max=2)
    p2 = Parameter('y', 'y', min=-2, max=2)

    # Create a host
    host = InteractiveHost()

    # Declare a UQ method.
    uq = Smolyak([p1, p2], level=lev)

    prog = TestProgram(desc='Rosenbrock Function (C)',
        exe="./rosen_cprog -x $x -y $y")

    return Sweep(uq, host, prog)

The important line is where it says:

exe="./rosen_cprog -x $x -y $y"

See also

TestProgram

Finally, do ‘puq start rosen_c’ and try it out.

Matlab Programs

In this example, we use a test program written in Matlab and executed either by Matab or Octave. The example is very much like the previous one using C.

The test program is puq/examples/rosen/rosen.m

1
2
3
4
5
function[]=rosen(x,y)

z = 100*(y-x^2)^2 + (1-x)^2;

fprintf('HDF5:{"name": "z", "value": %.16g, "desc": ""}:5FDH\n', z);

The biggest difference between this and our other example is that we do not (yet) have a dump_hdf5() function for Matlab. Instead we must write out output variable(s) in carefully formatted fprintfs. This puts our data in a tagged format such that PUQ can recognize it.

You should test the test program:

~/puq/examples/rosen> octave -q --eval 'rosen(1,.5)'
HDF5:{"name": "z", "value": 25, "desc": ""}:5FDH

It works the same as the python version. To use it, we need to make a simple change to our control script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from puq import *

def run(lev=4):
    # Declare our parameters here. Both are uniform on [-2, 2]
    p1 = UniformParameter('x', 'x', min=-2, max=2)
    p2 = UniformParameter('y', 'y', min=-2, max=2)

    # Create a host
    host = InteractiveHost()

    # Declare a UQ method.
    uq = Smolyak([p1, p2], level=lev)

    prog = TestProgram(
      exe="octave -q --eval 'rosen($x, $y)'",
      # exe="matlab -nodisplay -r 'rosen($x, $y);quit()'",
      desc='Rosenbrock Function (octave)')

    return Sweep(uq, host, prog)

The syntax to execute a function from the command line differs between Octave and Matlab. If you have Matlab, you can comment the Octave line out and uncomment the Matlab line.

Finally, do ‘puq start rosen_ml’ and try it out.

See also

TestProgram

Fortran Programs

There is a Fortran version of the Rosenbrock test in examples/fortran. It works very much like the C version.