MC++
Structure Detection for Factorable Functions
Author:
Benoit C. Chachuat
Version:
0.1
Date:
2011-2012
Bug:
No known bugs.

mc::Structure is a C++ class that determines the structure of mathematical expressions, namely their sparsity pattern and linearity, for a given set of participating variables. It relies on the operator overloading and function overloading mechanisms of C++. The overloaded operators are: `+', `-', `*', and `/'; the overloaded functions are: `exp', `log', `sqr', `pow', `sqrt', `fabs', `xlog', `min', `max', `cos', `sin', `tan', `acos', `asin' and `atan'.

How Do I Determine the Structure of a Factorable Function?

Suppose you are given 4 variables \(x_1,\ldots,x_4\) and want to determine the sparsity pattern and linearity of the vector following function

\begin{eqnarray*} {\bf f}({\bf x}) = \left(\begin{array}{c} f_1({\bf x})\\ f_2({\bf x})\end{array}\right) = \left(\begin{array}{c} x_3 x_4+x_1\\x_1(\exp(x_3-x_4))^2+x_2 \end{array}\right) \end{eqnarray*}

First, define the variables \(x_1,\ldots,x_4\) as

      const int NX = 4;
      Structure X[NX];
      for( int i=0; i<NX; i++ ) X[i].indep(i);

Essentially, the first line means that X is an array of mc::Structure class objects, and the second line defines X[0],...X[NX-1] as independent variables with indices 0,...,NX-1, respectively.

Once the independent variables \({\bf x}\) have been defined, determine the structure of \({\bf f}({\bf x})\) simply as

      const int NF = 2;
      Structure F[NF] = { X[2]*X[3]+X[0],
                          X[0]*pow(exp(X[2]-X[3]),2)+X[1] };

Retrieve the structure - both the sparsity pattern and the linearity - of \(f_1\) and \(f_2\) as

      std::map<int,bool> F0_dep = F[0].dep();
      std::map<int,bool> F1_dep = F[1].dep();

You can also display the structure as

      std::cout << "Variable dependence of F[0]: " << F[0] << std::endl;
      std::cout << "Variable dependence of F[1]: " << F[1] << std::endl;

The corresponding output is

      Variable dependence of F[0]: { 0L 2NL 3NL }
      Variable dependence of F[1]: { 0NL 1L 2NL 3NL }

which indicates that X[0], X[2] and X[3] participate in F[0], but not X[1]. Moreover, X[0] participates linearly, unlike X[2] and X[3].

Errors Encountered in Determining the Structure of a Factorable Function?

Errors are managed based on the exception handling mechanism of the C++ language. Each time an error is encountered, a class object of type Structure::Exceptions is thrown, which contains the type of error. It is the user's responsibility to test whether an exception was thrown during a calculation, and then make the appropriate changes. Should an exception be thrown and not caught by the calling program, the execution will stop.

Possible errors encountered in determining the structure of a factorable function are:

Errors during Structure Determination
Number Description
-33 Error due to calling a feature not yet implemented in mc::Structure
Author:
Benoit C. Chachuat
Version:
0.1
Date:
2011-2012
Bug:
No known bugs.

mc::Structure is a C++ class that determines the structure of mathematical expressions, namely their sparsity pattern and linearity, for a given set of participating variables. It relies on the operator overloading and function overloading mechanisms of C++. The overloaded operators are: `+', `-', `*', and `/'; the overloaded functions are: `exp', `log', `sqr', `pow', `sqrt', `fabs', `xlog', `min', `max', `cos', `sin', `tan', `acos', `asin' and `atan'.

How Do I Determine the Structure of a Factorable Function?

Suppose you are given 4 variables \(x_1,\ldots,x_4\) and want to determine the sparsity pattern and linearity of the vector following function

\begin{eqnarray*} {\bf f}({\bf x}) = \left(\begin{array}{c} f_1({\bf x})\\ f_2({\bf x})\end{array}\right) = \left(\begin{array}{c} x_3 x_4+x_1\\x_1(\exp(x_3-x_4))^2+x_2 \end{array}\right) \end{eqnarray*}

First, define the variables \(x_1,\ldots,x_4\) as

      const int NX = 4;
      Structure X[NX];
      for( int i=0; i<NX; i++ ) X[i].indep(i);

Essentially, the first line means that X is an array of mc::Structure class objects, and the second line defines X[0],...X[NX-1] as independent variables with indices 0,...,NX-1, respectively.

Once the independent variables \({\bf x}\) have been defined, determine the structure of \({\bf f}({\bf x})\) simply as

      const int NF = 2;
      Structure F[NF] = { X[2]*X[3]+X[0],
                          X[0]*pow(exp(X[2]-X[3]),2)+X[1] };

Retrieve the structure - both the sparsity pattern and the linearity - of \(f_1\) and \(f_2\) as

      std::map<int,bool> F0_dep = F[0].dep();
      std::map<int,bool> F1_dep = F[1].dep();

You can also display the structure as

      std::cout << "Variable dependence of F[0]: " << F[0] << std::endl;
      std::cout << "Variable dependence of F[1]: " << F[1] << std::endl;

The corresponding output is

      Variable dependence of F[0]: { 0L 2NL 3NL }
      Variable dependence of F[1]: { 0NL 1L 2NL 3NL }

which indicates that X[0], X[2] and X[3] participate in F[0], but not X[1]. Moreover, X[0] participates linearly, unlike X[2] and X[3].

Errors Encountered in Determining the Structure of a Factorable Function?

Errors are managed based on the exception handling mechanism of the C++ language. Each time an error is encountered, a class object of type Structure::Exceptions is thrown, which contains the type of error. It is the user's responsibility to test whether an exception was thrown during a calculation, and then make the appropriate changes. Should an exception be thrown and not caught by the calling program, the execution will stop.

Possible errors encountered in determining the structure of a factorable function are:

Errors during Structure Determination
Number Description
-33 Error due to calling a feature not yet implemented in mc::Structure