**USING ***paceval.* – A SIMPLE CODE EXAMPLE

*paceval.*– A SIMPLE CODE EXAMPLE

If you want to work with a mathematical function like

i.e. in a computer readable format

** f(x,y) = -sin(x*cos(x))^(1/y)**

using two variables **x** and **y**.

You only have to create a * paceval.*-Computation object with this code for one time:

#### Programming with **pace**val. – C/C++

**pace**val.

**PACEVAL_HANDLE** handle_pacevalComputation = **paceval_CreateComputation**(“-sin(x*cos(x))^(1/y)”, 2, “x y”, false);

###### (see also the **paceval. Application programming interface (API)**)

**paceval_CreateComputation**(…) will create an object that identifies the sub-functions and sub-calculations in the given function and return the handle of the * paceval.*-Computation object. This one-time precompilation including parsing of the function takes time: less than 1 millisecond on a standard processor used for Internet of Things (IoT) and even less on a standard computer.

This might already seem very fast but think of the accumulated time if you had to create an object for any values you would like to calculate results for (maybe thousands if you want to plot the function). Therefore, you can declare the variables by calling **paceval_CreateComputation**(…) once which caches all sub-functions and sub-calculations and creates a small size and speed optimized binary image of the function. Ideally, you just run **paceval_CreateComputation**(…) at the very beginning of your program for all your static mathematical models to speed up future calculations. You get the result for concrete values of the variables with **paceval_GetComputationResult**(…).

In this example, if you want to get the result for **x = 0.5** and **y = 2** you simply use this code:

#### Programming with **pace**val. – C/C++

**pace**val.

long double valuesVariablesArray[2];

long double ldResult;

valuesVariablesArray[0] = 0.5; //the x-value

valuesVariablesArray[1] = 2; //the y-value

ldResult = **paceval_ldGetComputationResult**(handle_pacevalComputation, valuesVariablesArray, NULL, NULL);

//ldResult is approximately -0.65180178245228

###### (see also the **paceval. Application programming interface (API)**)

The return value is the result of the calculation. **paceval_GetComputationResult**(…) uses the cached sub-functions and sub-calculations created earlier by **paceval_CreateComputation**(…). The required time for this calculation result is as little as the required time using compiled standard C++ source code (or even less depending on the function).

Below, you will find the corresponding standard C++ source code to the example above:

#### Standard programming – C/C++

long double valuesVariablesArray[2];

long double ldResult;

valuesVariablesArray[0] = 0.5; //the x-value

valuesVariablesArray[1] = 2; //the y-value

ldResult = -1*powl(sinl(valuesVariablesArray[0]*cosl(valuesVariablesArray[0])), 1/valuesVariablesArray[1]);

//ldResult is approximately -0.65180178245228

The obvious advantage of * paceval.* against standard C++ code is the readability of the source code and error handling functionality. In this example, an error would occur in the C++ code if

**y**is set to

**0**or close to

**0**, as the term would be divided by

**0**. The user would not know why the calculation fails.

* paceval.* recognises automatically this error and locates it. For detailed information, just get further information on

**paceval_GetIsError**(…) and

**paceval_GetErrorInformation**(…) in the

**pace**val.**Application programming interface (API)**. In addition, the maintenance of the mathematical model is easier. You could collect all string representations of the mathematical functions and variables in a central area of the code or a database. Furthermore, the implementation of long functions can easily be handled since

*sets no limit in the length and number of variables of the function*

**pace**val.*.*The limit is only set by the memory of the underlying system. Just imagine a mathematical model consisting of 50 very complex single functions each with a minimum length of 50.000 characters and 100 variables. You will find these scenarios easily in cars having more than 100 sensors to watch, watchdog applications for sensitive products or stock watch and trading applications.

But, with * paceval.* you can do much more which helps you to interpret your results in a better way. In particular, when you are using a very complex mathematical model consisting of long functions as this will lead to rounding errors which are not handled by standard programming. Here

*is the perfect solution. You can easily enable the Trusted Interval Computation, TINC™. TINC is a*

**pace**val.*specific*

**pace**val.**Interval arithmetic**optimized for speed.

In the above example simply do the changes marked in **green **to use TINC and get the interval covering the real result:

#### Programming with **pace**val. – C/C++

**pace**val.

**PACEVAL_HANDLE** handle_pacevalComputation = **paceval_CreateComputation**(“-sin(x*cos(x))^(1/y)”, 2, “x y”, **true**);

###### (see also the **paceval. Application programming interface (API)**)

#### Programming with **pace**val. – C/C++

**pace**val.

long double valuesVariablesArray[2];

long double ldResult;**long double minResultInterval; ****long double maxResultInterval;**

valuesVariablesArray[0] = 0.5; //the x-value

valuesVariablesArray[1] = 2; //the y-value

ldResult = **paceval_ldGetComputationResult**(handle_pacevalComputation, valuesVariablesArray, **&minResultInterval**, **&maxResultInterval**);

// ldResult is approximately -0.65180178245228

// minResultInterval as lower confidence bound is -0.6518017824522809982

// maxResultInterval as upper confidence bound is -0.6518017824522740538

###### (see also the **paceval. Application programming interface (API)**)

# With *pace**val**.*, approximations can be displayed quickly and accurately.

*pace*

*.*

With *pace**val**., ***within seconds**, you can create **unlimitedly long mathematical functions as approximation throughout measurement series**. A **precise mathematical model** is derived and can be used in **separate programs**. This way, imprecise error-prone models are eliminated, and critical time of the development process is saved and used for immediate further development.

It often happens in engineering mathematics that complex products require sizeable measurement series. Subsequently, one has to derive a mathematical model with the help of approximations to be able to describe it in the software. This step without *pace**val**. *requires a lot of effort and becomes very time-consuming. Due to the size of the relevant points inside a measurement series, it may be impossible to find a simple descriptive mathematical function.

A good example can be a turbine that presents various parameters based on duration and size. Small deviations originating from the manufacturing process and material properties result in individual differences and specific adjustments for each turbine. Thus, the approximation must also be customized and be extremely precise and readily available.

A simple example: you want to create an approximation for the measurement values (1,5; 6), (2,5; 3) and (3,5; 25), where the values are directly connected. This function can be immediately delivered to *pace**val**.*:

f(x)= **((x>=1.5) AND (x<=2.5))***(((3-6)/(2.5-1.5))*(x-1.5)+6)

+ **((x>2.5) AND (x<=3.5))***(((25-3)/(3.5-2.5))*(x-2.5)+3)

You can easily have it parallelised. The same also works, if, for instance, other approximations (trigonometric, polynomial or other) are more suitable for this segment.

# Further calculation examples of *pace**val**.*

*pace*

*.*

As you can see, *pace**val**.***offers many advantages **thanks to its readability, high-grade parallelizability, unlimited length of functions or number of variables. Further examples are decision trees involving costs per decision and matrix multiplication with variables.

As an example, let us take a decision tree with two branches and variables a and b as presented on the left. You can create a single function for all paths that *pace**val**.* can calculate depending on the variables a and b. The function can be immediately provided to *pace**val**.*:

f(a, b)=

**((a<0) AND (b<30)) *** (2+6) +** ((a<0) AND (b>=30)) *** (2+9)

+ **((a>=0) AND (b<10)) *** (6+1) + **((a>=0) AND (b>=10))** * (6+3)

This can also be very well parallelised. The example can be expanded to include multiple branches and variables. The function will grow in length, depending on the number of variables. Should there be values from 20 sensors in a system, and should each sensor need two decisions, it would result in 2^20= 1.048.576 possible decision paths. If you had to write a program for all these decision paths, it would be very sizeable and hard to maintain. Also, it would be extremely complex and prone to failure, if the costs change, sensors are added, or decisions should be dynamically made. *pace**val**. *eliminates all these problems. In other words, instead of hundreds of thousands or millions of source code lines, *pace**val**.* makes it possible with fewer than 50 lines.

Multiplying two matrices, with *pace**val**.,* you would create one calculation object per entry. In the given example, there are 9 such objects that are then calculated with values of variables x,y,z,u,v and w. Again, you can expand this example, since there is no limit to the number of objects.

These are only two examples. Further examples would be weighted directed graphs, scalar products, vector multiplication, Hidden Markov Model for quick gesture recognition, transformations (DCT, FFT), polynomials, intrinsic values and a lot more.