'Mates8': a .Net math library

xrjf 0 Tallied Votes 399 Views Share

The days when the calculator had almost 3 thousand visits a day have gone. Since then, there have been several major versions and lots of minor versions.
Somehow, I feel pleased in that the present core algorithm follows the rules of the first I read; of course, extending the simplicity of just adding or multiplying to other operations. After many unsuccessful efforts, version #8 has the ability to parse matrix expressions and, at the same time, derivatives or integration symbols.
Mates8 -Spanish or Catalan equivalent to English 'math8'- perhaps isn't the quickest, nor by far the most complete math library but, in my opinion, has several benefits. Mainly, let me point out, is a .Net library of managed code: if something goes wrong, there will be no leaks of memory, no PC hangs. I could have written some unmanaged code boosting critical sections but, again in my opinion, balancing pros and cons would be of less profit.
So, what can it do and how? I will not do an exhaustive explanation; instead I'll give some basic ideas. I suggest the reader, if interested, to dig experiencing but, if understanding the code snippet below gets difficult, please, reconsider another workaround:

Import mates8.dll to your .Net application:

1. Imports mates8

Set the configuration to your needs:

...
17. MathGlobal8.bCaseSensitive = True
18. MathGlobal8.bFractions = True
...

Let mates8 do the math:

11. Dim mP As matrixParser = Nothing
... 
69. Dim strQuery As String = "2*2/3"
70. Dim oVars As VarsAndFns = Nothing
71. Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) 
72.
73. mP = mates8.matrixParser.parse(strQuery, "", Nothing)
74. If mP.errMsg.Length Then
75.   Throw New Exception(mP.errMsg)
76. End If
77. Console.WriteLine("Result: " + mP.ToString) ' Result: ' 4/3 (if mathglobal8.fractions=False => =1.333)
78. Console.WriteLine("")

There is a .Pdf document with a bit more extensive explanation under "Download usage explanation for .Net programming" here
Best regards

1. Imports mates8
2. 
3. Module Module1
4. 
5.     Sub Main()
6.         testMates8()
7.     End Sub
8.     Sub testMates8()
9.         Try
10.             Dim N As Int32 = 1
11.             Dim mP As matrixParser = Nothing
12.             Dim sResult As String = ""
13.             Dim strVarsAndFns As String = ""
14. 
15.             MathGlobal8.bUseEng = True ' exponents multiples of 3 (10.3e3, 1.2e6, ...)
16.             MathGlobal8.bIgnoreSpaces = True
17.             MathGlobal8.bCaseSensitive = True
18.             MathGlobal8.bFractions = True
19. 
20.             ' the following are examined only when 
21.             ' 'ToString" type methods are invoked:
22.             MathGlobal8.bUseRounding = True ' round to 3 decimals 
23.             MathGlobal8.bDetail = False ' no detailed info
24.             MathGlobal8.bBinary = False
25.             MathGlobal8.bOctal = False
26.             MathGlobal8.bHexa = False
27. 
28.             '     INPUT for matrixParser.Parse()
29.             '     ==============================
30.             '     strQuery = the math expression to parse,
31.             '     for example: strQuery="2*2", "2*x+3*x", "∫(cos(x))dx", "roots(x^16-1)"
32.             '                  or a matrix expression with columns delimited by
33.             '                  semicolons and rows by vbCrLf as "A^-1"
34.             '     strVarsAndFns = "" or eventualy variables values or functions
35.             '                    for ex. "x=-1" or  "A=2;3" + vbCrLf + "-1;2"
36.             '                    Dim oVars As VarsAndFns = Nothing
37. 
38.             'OUTPUT:
39.             '     =======
40.             '     1) mP.toString returns the result as a string.
41.             '     2) mP.retCjo() returns a complex or, eventually, an array of complex.
42.             '     3) When the result is a matrix
43.             '       xmP.ret.exprMtx.getExpr(row, column) returns the expression
44.             '       contained at a row and column ((0,0) is the first row and columns)
45. 
46.             ' mP.ret.exprMtx.getExpr(row, column).IsReal will tell
47.             ' if the element's content is a real number and 
48.             ' mP.ret.exprMtx.getExpr(row, column).toDouble its value.
49.             ' mP.ret.exprMtx.rows gives the number of rows in the matrix
50.             ' mP.ret.exprMtx.cols gives the # of columns
51. 
52.             ' As an exxmple, if we want the roots of x^16-1
53.             ' we equal strQuery="roots(x^16-1)", execute
54.             ' mP = matrixParser.parse(strQuery,"", nothing)
55.             ' and, at the output, the roots will be in mP.retCjo(); first, the real
56.             ' roots (if any) and then the complex (if any):
57.             ' 
58.             ' root1:  mp.retCjo(0)  ' = -1 (real)
59.             ' root2:  mp.retCjo(1)  ' =  1 (real)
60.             ' root2:  mp.retCjo(2)  ' = -i (complex)
61.             ' ...
62.             ' root16: mp.retCjo(15) ' = (0.923879532511287 -i*0.38268343236509) (complex)
63. 
64.             ' Real roots, in mP.retCjo(), are ordered from most negative to most positive.
65.             ' If a root is real and not complex, i.e. the imaginary value is zero, 
66.             ' mP.retCjo(0).IsReal will be True.
67. 
68. 
69.             Dim strQuery As String = "2*2/3"
70.             Dim oVars As VarsAndFns = Nothing
71.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) 
72.
73.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
74.             If mP.errMsg.Length Then
75.                 Throw New Exception(mP.errMsg)
76.             End If
77.             Console.WriteLine("Result: " + mP.ToString) ' Result: ' 4/3 (if mathglobal8.fractions=False => 1.333)
78.             Console.WriteLine("")
79.             N += 1
80. 
81.             strQuery = "2*x+3*x"
82.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) ' 2*x+3*x
83.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
84.             If mP.errMsg.Length Then
85.                 Throw New Exception(mP.errMsg)
86.             End If
87.             Console.WriteLine("Result: " + mP.ToString) ' Result: 5*x
88.             Console.WriteLine("")
89.             N += 1
90. 
91.             ' Prefix for hexa numbers &h, for octal &o, binary prefixed by &b
92.             ' 255 as hexadecimal (&hFF),  logical optor. AND, 15 as hexa.(&hF)
93.             ' logical operators valid are "and", "or", "xor", "not", "nand", "nor"
94.             strQuery = "(&hff xor &hf)+3" ' ...and add 3 (decimal)
95.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery)
96.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
97.             If mP.errMsg.Length Then
98.                 Throw New Exception(mP.errMsg)
99.             End If
100.             Console.WriteLine("Result: " + mP.ToString) ' Result: 18
101.             Console.WriteLine("")
102.             N += 1
103. 
104.             strQuery = "∫(cos(x))dx"
105.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) ' integral(cos(x))dx
106.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
107.             If mP.errMsg.Length Then
108.                 Throw New Exception(mP.errMsg)
109.             End If
110.             Console.WriteLine("Result: " + mP.ToString) ' Result: sin(x) + _constant
111.             Console.WriteLine("")
112.             N += 1
113. 
114.             strQuery = "f(3)-f(2)"
115.             strVarsAndFns = "f(x)=x^2-1"
116.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery + _
117.                     " where " + strVarsAndFns)
118.             mP = mates8.matrixParser.parse(strQuery, strVarsAndFns, Nothing)
119.             If mP.errMsg.Length Then
120.                 Throw New Exception(mP.errMsg)
121.             End If
122.             Console.WriteLine("Result: " + mP.ToString) ' Result: 3^2-1-(2^2-1)=8-(3)=5
123.             Console.WriteLine("")
124.             N += 1
125. 
126.             MathGlobal8.bIgnoreSpaces = False ' carrige return (vbCrLf) must be considered
127.             strQuery = "A"
128.             ' semicolons delimit columns, vbCrLf delimits rows:
129.             strVarsAndFns = "A=2;3" + vbCrLf + "-1;-2" ' watch for semicolons and vbCrLf
130.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) ' integral(cos(x))dx
131.             mP = mates8.matrixParser.parse(strQuery, strVarsAndFns, Nothing)
132.             If mP.errMsg.Length Then
133.                 Throw New Exception(mP.errMsg)
134.             End If
135. 
136.             Console.WriteLine("Result: " + vbCrLf + mP.ToString) ' Result: sin(x) + _constant
137.             Console.WriteLine("element at row 2, column 2 is: {0}", _
138.                               mP.ret.exprMtx.getExpr(1, 1).toDouble)
139.             Console.WriteLine("")
140.             N += 1
141. 
142.             strQuery = "A*A^-1"
143.             strVarsAndFns = "A=2;3" + vbCrLf + "-1;-2"
144.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) ' integral(cos(x))dx
145.             mP = mates8.matrixParser.parse(strQuery, strVarsAndFns, Nothing)
146.             If mP.errMsg.Length Then
147.                 Throw New Exception(mP.errMsg)
148.             End If
149.             Console.WriteLine("Result: " + vbCrLf + mP.ToString) ' Result: sin(x) + _constant
150.             Console.WriteLine("element at row 2, column 2 is:  {0}", _
151.                               mP.ret.exprMtx.getExpr(1, 1).toDouble)
152.             Console.WriteLine("")
153.             N += 1
154. 
155. 
156.             strQuery = "roots(x^16-1)"
157.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery) ' roots(x^16-1)
158.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
159.             If mP.errMsg.Length Then
160.                 Throw New Exception(mP.errMsg)
161.             End If
162.             Console.WriteLine("Result: " + vbCrLf + mP.ToString) ' Result: -1, 1, i, -i, ....
163.             Console.WriteLine("The 3rd. root is " + mP.retCjo(2).ToString)
164.             Console.WriteLine("")
165.             N += 1
166. 
167.             ' Example 2:
168.             ' Now we want to evaluate "2x^2+5" for x=-1, x=2, x=3 and x=-i
169.             strQuery = "2x^2+5"
170.             Console.WriteLine(N.ToString + ". Parsing and evaluating: " + strQuery)
171.             ' 1) Call parse() method:
172.             mP = mates8.matrixParser.parse(strQuery, "", Nothing)
173.             If mP.errMsg.Length Then
174.                 Throw New Exception(mP.errMsg)
175.             End If
176. 
177.             ' 2) An AST tree has been created; call the evalExpression() method
178.             '    for each value of x:
179.             Console.Write("  Evaluating " + strQuery + ", for x=-1")
180.             Dim cmplx As Complex = mP.ret.curExpr.evalExpression(New Complex(-1))
181.             Console.WriteLine(": " + cmplx.ToString) ' = 7
182. 
183.             Console.Write("  Evaluating " + strQuery + ", for x=2")
184.             cmplx = mP.ret.curExpr.evalExpression(New Complex(2))
185.             Console.WriteLine(": " + cmplx.ToString) ' = 13
186. 
187.             Console.Write("  Evaluating " + strQuery + ", for x=3")
188.             cmplx = mP.ret.curExpr.evalExpression(New Complex(3))
189.             Console.WriteLine(": " + cmplx.ToString) ' = 23
190. 
191.             Console.Write("  Evaluating " + strQuery + ", for x=-i")
192.             ' note x= -i => real part= 0, imaginary= -1:
193.             cmplx = mP.ret.curExpr.evalExpression(New Complex(0, -1))
194.             Console.WriteLine(": " + cmplx.ToString) ' = 3
195.         Catch ex As Exception
196.             Console.WriteLine(ex.ToString)
197.         End Try
198.         Console.WriteLine("Press 'Enter' to exit.")
199.         Console.ReadLine()
200.     End Sub

End Module