Evaluate Math Expression

Evaluate Math Expression

eryar@163.comjava

摘要Abstract:本文簡要介紹了數學表達式解析求值的幾款開源軟件,並結合程序代碼說明了OpenCascade中表達式包的用法。也簡要介紹了表達式解析求值在AVEVA Paragon模塊中的應用。ios

關鍵字Key Words:Expression, Paragon, OpenCascade Expr package, muParser, MTParser算法

1、引言 Introduction

算術表達式中最多見的表示法形式有中綴、前綴和後綴表示法。中綴表示法(Infix notation)是書寫表達式的常見方式,而前綴(prefix notation)、後綴表示法(postfix notation)主要用於計算機科學領域。算術表達式只包含操做數(operands)、二元操做符(binary operators)和一種括號(one kind of parentheses)。express

Knuth將編寫程序計算表達式的方法歸納爲三個步驟:設計模式

l 對中綴表達式進行語法分析;數據結構

l 中綴表達式到後綴表達式的轉換;ide

l 對後綴表達式求值;工具

在《數據結構與算法》等相關的書籍中,還有如何將中綴表達式轉換爲後綴表達式的具體算法。post

在AVEAV Plant(PDMS)的Paragon模塊定義部件時,使用了參數化的表達式,從而實現了參數化的部件定義。其中參數化表達式的解析計算是其一個關鍵技術點。最近在寫模型導出程序(Model Data Exchange Addin)時就遇到了這個問題,即參數化表達式的計算。好在AVEVA .Net給出了表達式計算類DbExpression,能夠對PML的表達式進行解析計算,順利解決了問題。ui

若想在本身的程序中實現數學表達式的解析求值,也有一些開源的工具可供選用。有些C++的數學表達式計算程序速度、效率仍是很高的。在查看OpenCascade的文檔時,發現其也有表達式求值的包,可用來對錶達式進行計算。

發現OpenCascade已經有不少功能與AVEVA產品PDMS中的功能很相似,也難怪OpenCascade的前身Matra-Data Vision公司早期也有個集機械設計與工廠設計於一身的企業級並行工程解決方案Euclid集成系統。在1998年時Dassault Systèmes收購了EUCLID QUANTUM。

2、幾款開源軟件介紹 Introduce some tools

網上有不少開源的數學表達式解析求值的庫,如:

l fparser

l muParser

l MTParse

在開源的二維CAD軟件LibreCAD中就使用了muParser來對輸入命令中的表達式進行解析。早期版本中使用了fparser。muParser小巧精幹,提供LIB、DLL及源代碼入方式。muParser最大的優勢就是速度較快,更適合於實時性要求較高的環境,如Unix系統和單片機環境。源程序下載及文檔說明可參考:

http://www.codeproject.com/cpp/FastMathParser.asp

MTParser優雅簡潔,提供LIB、COM、源代碼三種引入方式,是用典型C++風格編寫的解析器,和muParser不一樣,它引入了多種設計模式,於是可擴展性的可維護性都很強。如做者所說,速度並非TMParser最優先考慮的,也許文中所說的可擴展、可維護、易於使用、健壯性纔是它的最大優點。源程序下載及設計文檔可參考:

http://www.codeproject.com/Articles/7335/An-extensible-math-expression-parser-with-plug-ins

下面以一個具體實例來講明muParser的用法:(將muParser以源代碼引入的方式加入到項目中),再編譯以下代碼:

1  /*
2  *    Copyright (c) 2013 eryar All Rights Reserved.
3  *
4  *        File    : Main.cpp
5  *        Author  : eryar@163.com
6  *        Date    : 2013-10-09
7  *        Version : 1.0v
8  *
9  *    Description : Evaluate expression in muParser.
10  *                 
11  */
12 
13  #include < iostream >
14 
15  #include " muParser.h "
16 
17  int main()
18  {
19      mu::Parser parser;
20      parser.DefineNameChars( " 0123456789_ "
21                         " abcdefghijklmnopqrstuvwxyz "
22                         " ABCDEFGHIJKLMNOPQRSTUVWXYZ "
23                         " [] " );
24 
25      double dParam1 =   2.0 ;
26      double dParam2 =   3.1415926   /   2.0 ;
27 
28      parser.DefineVar( " PARA[1] " , & dParam1);
29      parser.DefineVar( " PARA[2] " , & dParam2);
30 
31      parser.SetExpr( " 10 * (PARA[1] + sin(PARA[2])) " );
32 
33      std::cout << parser.Eval() << std::endl;
34 
35  }

程序運行結果以下所示:

1  30  
2  Press any key to continue . . .

如上程序所示,使用muParser可實現參數化表達式的計算,功能與AVEVA Plant(PDMS)中的Paragon模塊中參數化表達式的計算方式已經很相近了。使用方法很簡單。

3、Evaluate Expression in OpenCascade

在OpenCascade的TKAdvTools中有Expr包和ExprIntrp包,這兩個包可用來對錶達式進行解析和求值。可是在其文檔《Foundation Classes User’s Guide》中並無對TKAdvTools的工具進行說明。下面只給出一個簡單實例來講明其應用,有興趣的讀者能夠結合源程序對其具體實現進行研究。示例代碼以下所示:

1  /*
2  *    Copyright (c) 2013 eryar All Rights Reserved.
3  *
4  *        File    : Main.cpp
5  *        Author  : eryar@163.com
6  *        Date    : 2013-10-09
7  *        Version : 1.0v
8  *
9  *    Description : Evaluate expression in OpenCascade.
10  *                 
11  */
12 
13  #define WNT
14  #include < TCollection_AsciiString.hxx >
15  #include < Expr_GeneralExpression.hxx >
16  #include < ExprIntrp_GenExp.hxx >
17 
18  #pragma comment(lib, " TKernel.lib " )
19  #pragma comment(lib, " TKAdvTools.lib " )
20 
21  int main( void )
22  {
23      TCollection_AsciiString strExpr( " sin(3.1415926 / 6) * 2 " );
24      Handle_ExprIntrp_GenExp exprIntrp = ExprIntrp_GenExp::Create();
25      Handle_Expr_GeneralExpression genExpr = NULL;
26 
27      exprIntrp -> Process(strExpr);
28 
29      genExpr = exprIntrp -> Expression();
30 
31      std::cout << genExpr -> EvaluateNumeric() << std::endl;
32 
33      return   0 ;
34  }

程序運行結果以下所示:

1  1  
2  Press any key to continue . . .

OpenCascade的表達式求值功能也很強大,這裏只以一個簡單示例來拋磚引玉啦。感受OpenCascade的表達式包也能夠像muParser, MTParser同樣做爲一個獨立的工具來使用。

4、結論 Conclusion

由於AVEVA Plant(PDMS)的Paragon模塊中的參數化部件定義方式,注意到了參數表達式的解析與求值。因爲ModelDataExchangeAddin程序的須要,纔去找尋開源的表達式解析與求值的庫,誰知最後仍是使用了AVEVA .Net中現成的DbExpression類,簡化了程序的開發。

OpenCascade中居然也有表達式解析與求值的工具,做爲早期機械設計與工廠設計軟件系統,可能都考慮過參數化這種方式。深刻挖掘其源代碼,對相似PDMS的工廠設計系統實現原理的理解有很大幫助。

5、參考資料 Bibliography

1. http://www.ibm.com/developerworks/cn/java/j-w3eva/

2. http://en.wikipedia.org/wiki/Euclid_(computer_program)

相關文章
相關標籤/搜索