Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Universal Framework for Science and Engineering - Part 11: CodeDom Optimizing Compiler

4.92/5 (10 votes)
27 Jul 2008CPOL8 min read 1   5.5K  
CodeDom Optimizing Compiler for Science and Engineering

Aviation

Introduction

Performance has significant role in IT. However, as rule, rapid application development is more important. This article is devoted to both of these problems. The picture above shows my applications of this development. More profound description of applications you can find in my other CodeProject articles. Also you can visit Universal Framework for Science and Engineering homepage. Additional information contains in my articles The virtual reality framework for engineering objects and The framework for simulation of dynamics of mechanical aggregates. It is not easy to grasp whole framework. Therefore now it has a lot of subversions. You can download three versions from this page. First one devoted to the Aviation it contains commonly used in Aviation math and 3D dynamics. Second version is more advanced Aviation. Besides first version it contains transfer functions of control theory. It can be used for autopilot system development. Third version is devoted to astronomy. It enables us to work with star catalogues (parts 2, 7). There exists real time SCADA version that uses OPC servers. Other versions will be uploaded later.

Background

Theory of compiler optimization is well known. Using CodeDom we can generate effective code. For example The Commonly Used .NET Coding Patterns in CodeDom shows very useful applications of this technology. This article is devoted to CodeDom application for rapid development of high performance engineering applications.

Main idea

Main idea is CodeDom compiling of powerful math editor equations. Now software documentation of this editor is preparing. This article is rather announcement of this big work. Although source code you can download from this page. However source code is Aviation version of Universal Framework for Science and Engineering and CodeDom optimizing compiler is a small part of the framework. But this compiler is very effective in the framework only. Although main idea and the compiler can be used without the framework.

1. Features of formula editor

Formula editor has a lot of advanced math operations. For example in part the editor operates with Galois fields, Euclidean rings and functors. Here we will consider some features related to engeenering problems. Formula editor is case sensitive operates with a lots of types. Result of calculation depends on types of variables.

1.1 Arrays

Let sin(a) be a formula of formula editor. What is its meaning? If a is a real variable then result of formula is a real value. However if a is an array then sin(a) is also an array of componentwise calculation of sin. If a is a real array and b is a real variable then a + b means an array of sums of components of a with b.

1.2 Functions

Any function of formula editor may be a variable or result of calculation. A function as result is not a value of function but the whole function. This fact seems unusual for people who do not know functional analysis. For example if a is a real variable then f(a) means result of calculation of f. If a is function then f(a) is a composition of functions. It is very convenient. For example the series component seriesbtn.jpg provides three variables:

graphvariables.jpg

First variable is an array of abscises of function table. Second one is an array of ordinates. Third one is the function defined by table. Let us consider usage of this function. We have the following situation:

compositionscenario.jpg

The Formula 1 component imports and then exports function f from Plot. The Formula 2 imports one function from Formula 1 and another from Plot. In fact it is the same function. Then Formula 2 composes these functions:

compositionformula.jpg

Later Formula 3 calculates these functions. In result we have:

compositiongraph.jpg

The red curve is the function and teal curve is the composition one.

1.3 Vectors and matrixes

Formula editor supports matrix and vector operations. Examples of usage of vector and matrix operations are presented below :

vectormatrixsample1.jpg

vectormatrixsample2.jpg

vectormatrixsample3.jpg

These examples contains transposition of matrixes, products of matrixes, inversion of matrixes and vector product of 3D vectors.

1.4 Dirac delta function

The formula editor supports Dirac delta function. The presence of the delta function at the right part of the ordinary differential equation shows that the result function is not continuous. Following picture shows presence of delta function in formula editor:
deltafunctionformula.jpg.

Its usage is considered at Part 3 and Part 4.

2. Examples of formla compilation

2.1 Matrix product

Matrix product in math editor is presented below:

Picrure_1.jpg

Equation is placed at brown background. Variables a and b are matrixes. Types of a and b is shown at right bottom corner of the picture. The types are Double[4, 5] and Double[5, 6] respectively. The editor defines product of these types objects as matrix product. The result of compilation is presented below:

var_2[0, 0] = var_0[0, 0] * var_1[0, 0] + var_0[0, 1] * var_1[1, 0] + var_0[0, 2] * 
var_1[2, 0] + var_0[0, 3] * var_1[3, 0] + var_0[0, 4] * var_1[4, 0];

var_2[0, 1] = var_0[0, 0] * var_1[0, 1] + var_0[0, 1] * var_1[1, 1] + var_0[0, 2] * 
var_1[2, 1] + var_0[0, 3] * var_1[3, 1] + var_0[0, 4] * var_1[4, 1];

var_2[0, 2] = var_0[0, 0] * var_1[0, 2] + var_0[0, 1] * var_1[1, 2] + var_0[0, 2] * 
var_1[2, 2] + var_0[0, 3] * var_1[3, 2] + var_0[0, 4] * var_1[4, 2];

var_2[0, 3] = var_0[0, 0] * var_1[0, 3] + var_0[0, 1] * var_1[1, 3] + var_0[0, 2] * 
var_1[2, 3] + var_0[0, 3] * var_1[3, 3] + var_0[0, 4] * var_1[4, 3];

var_2[0, 4] = var_0[0, 0] * var_1[0, 4] + var_0[0, 1] * var_1[1, 4] + var_0[0, 2] * 
var_1[2, 4] + var_0[0, 3] * var_1[3, 4] + var_0[0, 4] * var_1[4, 4];

var_2[0, 5] = var_0[0, 0] * var_1[0, 5] + var_0[0, 1] * var_1[1, 5] + var_0[0, 2] * 
var_1[2, 5] + var_0[0, 3] * var_1[3, 5] + var_0[0, 4] * var_1[4, 5];

var_2[1, 0] = var_0[1, 0] * var_1[0, 0] + var_0[1, 1] * var_1[1, 0] + var_0[1, 2] * 
var_1[2, 0] + var_0[1, 3] * var_1[3, 0] + var_0[1, 4] * var_1[4, 0];

var_2[1, 1] = var_0[1, 0] * var_1[0, 1] + var_0[1, 1] * var_1[1, 1] + var_0[1, 2] * 
var_1[2, 1] + var_0[1, 3] * var_1[3, 1] + var_0[1, 4] * var_1[4, 1];

var_2[1, 2] = var_0[1, 0] * var_1[0, 2] + var_0[1, 1] * var_1[1, 2] + 
var_0[1, 2] * var_1[2, 2] + var_0[1, 3] * var_1[3, 2] + var_0[1, 4] * var_1[4, 2];

var_2[1, 3] = var_0[1, 0] * var_1[0, 3] + var_0[1, 1] * var_1[1, 3] + var_0[1, 2] * 
var_1[2, 3] + var_0[1, 3] * var_1[3, 3] + var_0[1, 4] * var_1[4, 3];

var_2[1, 4] = var_0[1, 0] * var_1[0, 4] + var_0[1, 1] * var_1[1, 4] + var_0[1, 2] * 
var_1[2, 4] + var_0[1, 3] * var_1[3, 4] + var_0[1, 4] * var_1[4, 4];

var_2[1, 5] = var_0[1, 0] * var_1[0, 5] + var_0[1, 1] * var_1[1, 5] + var_0[1, 2] * 
var_1[2, 5] + var_0[1, 3] * var_1[3, 5] + var_0[1, 4] * var_1[4, 5];

var_2[2, 0] = var_0[2, 0] * var_1[0, 0] + var_0[2, 1] * var_1[1, 0] + var_0[2, 2] * 
var_1[2, 0] + var_0[2, 3] * var_1[3, 0] + var_0[2, 4] * var_1[4, 0];

var_2[2, 1] = var_0[2, 0] * var_1[0, 1] + var_0[2, 1] * var_1[1, 1] + var_0[2, 2] * 
var_1[2, 1] + var_0[2, 3] * var_1[3, 1] + var_0[2, 4] * var_1[4, 1];

var_2[2, 2] = var_0[2, 0] * var_1[0, 2] + var_0[2, 1] * var_1[1, 2] + var_0[2, 2] * 
var_1[2, 2] + var_0[2, 3] * var_1[3, 2] + var_0[2, 4] * var_1[4, 2];

var_2[2, 3] = var_0[2, 0] * var_1[0, 3] + var_0[2, 1] * var_1[1, 3] + var_0[2, 2] * 
var_1[2, 3] + var_0[2, 3] * var_1[3, 3] + var_0[2, 4] * var_1[4, 3];

var_2[2, 4] = var_0[2, 0] * var_1[0, 4] + var_0[2, 1] * var_1[1, 4] + var_0[2, 2] * 
var_1[2, 4] + var_0[2, 3] * var_1[3, 4] + var_0[2, 4] * var_1[4, 4];

var_2[2, 5] = var_0[2, 0] * var_1[0, 5] + var_0[2, 1] * var_1[1, 5] + var_0[2, 2] * 
var_1[2, 5] + var_0[2, 3] * var_1[3, 5] + var_0[2, 4] * var_1[4, 5];

var_2[3, 0] = var_0[3, 0] * var_1[0, 0] + var_0[3, 1] * var_1[1, 0] + var_0[3, 2] * 
var_1[2, 0] + var_0[3, 3] * var_1[3, 0] + var_0[3, 4] * var_1[4, 0];

var_2[3, 1] = var_0[3, 0] * var_1[0, 1] + var_0[3, 1] * var_1[1, 1] + var_0[3, 2] * 
var_1[2, 1] + var_0[3, 3] * var_1[3, 1] + var_0[3, 4] * var_1[4, 1];

var_2[3, 2] = var_0[3, 0] * var_1[0, 2] + var_0[3, 1] * var_1[1, 2] + var_0[3, 2] *
var_1[2, 2] + var_0[3, 3] * var_1[3, 2] + var_0[3, 4] * var_1[4, 2];

var_2[3, 3] = var_0[3, 0] * var_1[0, 3] + var_0[3, 1] * var_1[1, 3] + var_0[3, 2] * 
var_1[2, 3] + var_0[3, 3] * var_1[3, 3] + var_0[3, 4] * var_1[4, 3];

var_2[3, 4] = var_0[3, 0] * var_1[0, 4] + var_0[3, 1] * var_1[1, 4] + var_0[3, 2] * 
var_1[2, 4] + var_0[3, 3] * var_1[3, 4] + var_0[3, 4] * var_1[4, 4];

var_2[3, 5] = var_0[3, 0] * var_1[0, 5] + var_0[3, 1] * var_1[1, 5] + var_0[3, 2] * 
var_1[2, 5] + var_0[3, 3] * var_1[3, 5] + var_0[3, 4] * var_1[4, 5];

Excuse me for such long listing. But I could not avoid my very much admiration of the fact that very simple math formula had been compiled to very effective code without cycles.

2.2 Vector calculations

Formula of vector calculations is presented below:

Picrure_2.jpg

var_5[0] = Math.Sin((double)var_4[0]);

var_5[1] = Math.Sin((double)var_4[1]);

var_5[2] = Math.Sin((double)var_4[2]);

var_5[3] = Math.Sin((double)var_4[3]);

var_5[4] = Math.Sin((double)var_4[4]);

var_6[0] = (var_3) * ((double)var_5[0]);

var_6[1] = (var_3) * ((double)var_5[1]);

var_6[2] = (var_3) * ((double)var_5[2]);

var_6[3] = (var_3) * ((double)var_5[3]);

var_6[4] = (var_3) * ((double)var_5[4]);

var_7 = Math.Cos(var_3);

var_8[0] = ((double)var_6[0]) + (var_7);

var_8[1] = ((double)var_6[1]) + (var_7);

var_8[2] = ((double)var_6[2]) + (var_7);

var_8[3] = ((double)var_6[3]) + (var_7);

var_8[4] = ((double)var_6[4]) + (var_7);

var_10[0] = Math.Tan((double)var_9[0]);

var_10[1] = Math.Tan((double)var_9[1]);

var_10[2] = Math.Tan((double)var_9[2]);

var_10[3] = Math.Tan((double)var_9[3]);

var_10[4] = Math.Tan((double)var_9[4]);

var_11[0] = ((double)var_8[0]) + ((double)var_10[0]);

var_11[1] = ((double)var_8[1]) + ((double)var_10[1]);

var_11[2] = ((double)var_8[2]) + ((double)var_10[2]);

var_11[3] = ((double)var_8[3]) + ((double)var_10[3]);

var_11[4] = ((double)var_8[4]) + ((double)var_10[4]);

var_12[0] = (var_2) * ((double)var_11[0]);

var_12[1] = (var_2) * ((double)var_11[1]);

var_12[2] = (var_2) * ((double)var_11[2]);

var_12[3] = (var_2) * ((double)var_11[3]);

var_12[4] = (var_2) * ((double)var_11[4]);

var_13[0] = Math.Exp((double)var_12[0]);

var_13[1] = Math.Exp((double)var_12[1]);

var_13[2] = Math.Exp((double)var_12[2]);

var_13[3] = Math.Exp((double)var_12[3]);

var_13[4] = Math.Exp((double)var_12[4]);

I could not avoid my admiration once again.

2.3. Cyclic sum

Cyclic sum looks like:

Picrure_3.jpg

Compilation result is presented below:

var_1 = (double)var_0[0] + /* 100000 terms */;

At last I can avoid my admiration.

2.4 Symbolic Differentiation

Symbolic differentiation is one of important features of formula editor. For example d/dt differentiation is presented below:

Symbolic_Differentiation.jpg

First arrow is function, second one is its d/dt derivation. OMG this calculation is not optimal since it contains products of constants. I am being development of formula editor more than 10 years and I have no optimal solution yet. Earlier Java versions of editor you can find at http://www.mathframe.com/applets/mathonline/indexE.htm. But I am not alone. You can insert complicated fraction Mathcad. The nominator of the fraction is equal to denominator. And instead zero Mathcad gives you complicated formula. Indeed you have no need insert bottom formula. You can insert following expression:

Symbolic_Differentiation_dt.jpg

Optimization result is:

currentTree = trees[1];

currentArray = treeArray_1;

var_1 = (double)currentTree.Calculate(currentArray);

currentTree = trees[2];

currentArray = treeArray_2;

var_2 = (double)currentTree.Calculate(currentArray);

var_4 = Math.Pow(var_2, var_3);

var_5 = (var_1) * (var_4);

var_6 = Math.Sin(var_5);

var_8 = Math.Pow(var_6, var_7);

var_9 = (var_0) * (var_8);

currentTree = trees[10];

currentArray = treeArray_10;

var_10 = (double)currentTree.Calculate(currentArray);

currentTree = trees[11];

currentArray = treeArray_11;

var_11 = (double)currentTree.Calculate(currentArray);

var_13 = Math.Pow(var_11, var_12);

var_14 = (var_10) * (var_13);

var_15 = Math.Cos(var_14);

currentTree = trees[16];

currentArray = treeArray_16;

var_16 = (double)currentTree.Calculate(currentArray);

currentTree = trees[18];

currentArray = treeArray_18;

var_18 = (double)currentTree.Calculate(currentArray);

var_19 = (var_17) * (var_18);

currentTree = trees[20];

currentArray = treeArray_20;

var_20 = (double)currentTree.Calculate(currentArray);

var_21 = (var_19) * (var_20);

var_22 = (var_16) * (var_21);

var_23 = (var_15) * (var_22);

var_24 = (var_9) * (var_23);

I do not now whether this result is optimal. Moreover I do not know that this result is correct. But CPOL says: "NO WARRANTY". Despite license I need to know whether result is correct. However even my mind cannot check correctness of compilation result. Can you check it? But the framework can plot results. The plot is presented below:

Symbolic_Differentiation_Graph.jpg

The blue curve is the function and red one is its derivation. Even my mind understands that result is correct. So compiler has no sense without visualization. 3D visualization is described at part 7.

3 Advanced example. Doppler velocity of artificial Earth satellite

3.1 Export of libraries

Simulation of artificial Earth satellite motion requires models of Earth's gravity and Earth's atmosphere one. So we need export libraries those contains these libraries. This problem was considered at part 6. Export can be performed by the following way. First of all we set on framework desktop library element:

interface.JPG

Right click on it opens its editor of properties:

interface_selection.JPG

Then we select necassary library and have following result:

gravity.JPG

The component becomes Earth's gravity model. Similarly we can upload atmosphere model.

3.2 Construction of full model.

Using uploaded components and framework ones we can construct full problem model. It is presented below:

Doppler_project.JPG

Besides gravity and atmospher it contaians such helper component as Motion equations that solves system of ordinary differential equations. Final components are Distance and Doppler. Properties of distance are presented below:

distance_formula.JPG

It is standard formula of 3D analytic geometry. The a, b and c are coorrdinates of observer. This editor sets Derivation order equal to 1. So compiler provides distance and its first devivation. Compilation result is presented below:

currentTree = trees[0];

currentArray = treeArray_0;

var_0 = (double)currentTree.Calculate(currentArray);

currentTree = trees[1];

currentArray = treeArray_1;

var_1 = (double)currentTree.Calculate(currentArray);

var_2 = (var_0) - (var_1);

var_4 = Math.Pow(var_2, var_3);

currentTree = trees[5];

currentArray = treeArray_5;

var_5 = (double)currentTree.Calculate(currentArray);

currentTree = trees[6];

currentArray = treeArray_6;

var_6 = (double)currentTree.Calculate(currentArray);

var_7 = (var_5) - (var_6);

var_9 = Math.Pow(var_7, var_8);

var_10 = (var_4) + (var_9);

currentTree = trees[11];

currentArray = treeArray_11;

var_11 = (double)currentTree.Calculate(currentArray);

currentTree = trees[12];

currentArray = treeArray_12;

var_12 = (double)currentTree.Calculate(currentArray);

var_13 = (var_11) - (var_12);

var_15 = Math.Pow(var_13, var_14);

var_16 = (var_10) + (var_15);

var_17 = Math.Sqrt(var_16);

var_19 = (var_3) * (var_2);

currentTree = trees[20];

currentArray = treeArray_20;

var_20 = (double)currentTree.Calculate(currentArray);

var_21 = (var_19) * (var_20);

var_22 = (var_8) * (var_7);

currentTree = trees[23];

currentArray = treeArray_23;

var_23 = (double)currentTree.Calculate(currentArray);

var_24 = (var_22) * (var_23);

var_25 = (var_21) + (var_24);

var_26 = (var_14) * (var_13);

currentTree = trees[27];

currentArray = treeArray_27;

var_27 = (double)currentTree.Calculate(currentArray);

var_28 = (var_26) * (var_27);

var_29 = (var_25) + (var_28);

var_30 = (var_18) * (var_29);

var_31 = (var_30) / (var_17);

The var_17 is the distance and var_31 is its time derivation. We can access Doppler velocity by the Doppler component:

Doppler_formula.JPG

Where d provides Distance.

3.3 Results

Results of simulation are presented on the following charts

Distance.JPG

Doppler.JPG

First chart indicates distance and second one Doppler Velocity. It is clear that second chart represents time derivation of second one.

4 Additional Features

The compiler is not very significant as itself. It is much more very powerful in the framework. Math editor of the framework provides symbolic differentiation. Formula editor contains also has some important features. All elements of framework has no very significance. Very significant is the framework as integrated object.

Points of Interest

There are a lot of myths devoted to engineering software:

- the best engineering software language is Fortran;

- the .NET is useful for computer nets and WWW only;

- object oriented programming is not applicable for engineers since they operate with real numbers only;

- garbage collection technologies have a slow performance;

I hope that my articles help to get rid of these myths.

History

History of this software is described at my previous articles. Main disadvantage is the shortage of software documentation. Now I am preparing it. But it needs a lot of work. Prospects are rather much more significant than history.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)