symexpress3 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. symexpress3/__init__.py +26 -0
  2. symexpress3/__main__.py +10 -0
  3. symexpress3/optFunctionBase.py +88 -0
  4. symexpress3/optSymAny/optSymAnyArrayPower.py +84 -0
  5. symexpress3/optSymAny/optSymAnyExpandArray.py +163 -0
  6. symexpress3/optSymAny/symRegisterOptSymAny.py +60 -0
  7. symexpress3/optSymFunction/__init__.py +5 -0
  8. symexpress3/optSymFunction/optSymFunctionCosAtanDiv3.py +139 -0
  9. symexpress3/optSymFunction/optSymFunctionCosAtanDivNToSinICos.py +124 -0
  10. symexpress3/optSymFunction/optSymFunctionCosToSum.py +84 -0
  11. symexpress3/optSymFunction/optSymFunctionCosXplusYtoSinCos.py +102 -0
  12. symexpress3/optSymFunction/optSymFunctionSinAtanDivNToSinICos.py +121 -0
  13. symexpress3/optSymFunction/optSymFunctionSinToSum.py +85 -0
  14. symexpress3/optSymFunction/optSymFunctionSinXplusYtoSinCos.py +103 -0
  15. symexpress3/optSymFunction/symRegisterOptSymFunction.py +83 -0
  16. symexpress3/optSymNumber/__init__.py +7 -0
  17. symexpress3/optSymNumber/optSymNumberNegRootToI.py +184 -0
  18. symexpress3/optSymNumber/optSymNumberPower.py +94 -0
  19. symexpress3/optSymNumber/optSymNumberRadicalDenominatorToCounter.py +98 -0
  20. symexpress3/optSymNumber/symRegisterOptSymNumber.py +68 -0
  21. symexpress3/optSymVariable/__init__.py +6 -0
  22. symexpress3/optSymVariable/optSymVariableI.py +224 -0
  23. symexpress3/optSymVariable/optSymVariableRootIToSinCos.py +162 -0
  24. symexpress3/optSymVariable/symRegisterOptSymVariable.py +60 -0
  25. symexpress3/optTypeBase.py +85 -0
  26. symexpress3/optimize/__init__.py +4 -0
  27. symexpress3/optimize/optimizeAdd.py +481 -0
  28. symexpress3/optimize/optimizeBase.py +86 -0
  29. symexpress3/optimize/optimizeExpandArrays.py +118 -0
  30. symexpress3/optimize/optimizeImaginairDenominator.py +214 -0
  31. symexpress3/optimize/optimizeMultiply.py +994 -0
  32. symexpress3/optimize/optimizeNestedRadicals.py +146 -0
  33. symexpress3/optimize/optimizeOnlyOneRoot.py +288 -0
  34. symexpress3/optimize/optimizePower.py +126 -0
  35. symexpress3/optimize/optimizePowerArrays.py +96 -0
  36. symexpress3/optimize/optimizeRootOfImagNumToCosISin.py +389 -0
  37. symexpress3/optimize/optimizeRootToPrincipalRoot.py +148 -0
  38. symexpress3/optimize/optimizeSinTwoCosTwo.py +185 -0
  39. symexpress3/optimize/optimizeSplitDenominator.py +117 -0
  40. symexpress3/optimize/optimizeUnnestingRadicals.py +378 -0
  41. symexpress3/optimize/symRegisterOptimize.py +94 -0
  42. symexpress3/primefactor.py +256 -0
  43. symexpress3/symexp3cmd.py +276 -0
  44. symexpress3/symexpress3.py +3622 -0
  45. symexpress3/symfunc/__init__.py +6 -0
  46. symexpress3/symfunc/symFuncAbs.py +185 -0
  47. symexpress3/symfunc/symFuncAtan.py +152 -0
  48. symexpress3/symfunc/symFuncAtan2.py +183 -0
  49. symexpress3/symfunc/symFuncBase.py +236 -0
  50. symexpress3/symfunc/symFuncBinomial.py +123 -0
  51. symexpress3/symfunc/symFuncCeilFloor.py +176 -0
  52. symexpress3/symfunc/symFuncCos.py +148 -0
  53. symexpress3/symfunc/symFuncExp.py +129 -0
  54. symexpress3/symfunc/symFuncFactorial.py +105 -0
  55. symexpress3/symfunc/symFuncSin.py +142 -0
  56. symexpress3/symfunc/symFuncSum.py +208 -0
  57. symexpress3/symfunc/symFuncTan.py +114 -0
  58. symexpress3/symfunc/symFuncTrigonoBase.py +578 -0
  59. symexpress3/symfunc/symRegisterFunctions.py +128 -0
  60. symexpress3/symfunc/symTrigonometricData.py +79 -0
  61. symexpress3/symtables.py +43 -0
  62. symexpress3/version.py +16 -0
  63. symexpress3-0.0.5.dist-info/METADATA +856 -0
  64. symexpress3-0.0.5.dist-info/RECORD +66 -0
  65. symexpress3-0.0.5.dist-info/WHEEL +4 -0
  66. symexpress3-0.0.5.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,26 @@
1
+ """
2
+ Initilization of the functions and modules symexpress3
3
+ """
4
+
5
+ from .symexpress3 import *
6
+ from .version import __version__,__author__,__copyright__,__credits__,__license__,__maintainer__,__email__,__status__
7
+
8
+
9
+ from .symfunc.symRegisterFunctions import SymRegisterFunctions
10
+ from .optimize.symRegisterOptimize import SymRegisterOptimize
11
+ from .optSymNumber.symRegisterOptSymNumber import SymRegisterOptimize as SymRegisterOptSymNumber
12
+ from .optSymVariable.symRegisterOptSymVariable import SymRegisterOptimize as SymRegisterOptSymVariable
13
+ from .optSymFunction.symRegisterOptSymFunction import SymRegisterOptimize as SymRegisterOptSymFunction
14
+ from .optSymAny.symRegisterOptSymAny import SymRegisterOptimize as SymRegisterOptSymAny
15
+
16
+
17
+ SymRegisterFunctions()
18
+ SymRegisterOptimize()
19
+ SymRegisterOptSymNumber()
20
+ SymRegisterOptSymVariable()
21
+ SymRegisterOptSymFunction()
22
+ SymRegisterOptSymAny()
23
+
24
+ RegisterOptimzeActions()
25
+
26
+ # print( "Symexpress3.__init__ name: " + __name__ )
@@ -0,0 +1,10 @@
1
+ # pylint: disable=invalid-name
2
+ """
3
+ Commandline handling
4
+ """
5
+
6
+ import sys
7
+
8
+ if __name__ == '__main__':
9
+ from symexpress3 import symexp3cmd
10
+ symexp3cmd.CommandLine( sys.argv )
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Abstract class for optimze variable type` implementation symexpress3
6
+
7
+ Copyright (C) 2024 Gien van den Enden - swvandenenden@gmail.com
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+
24
+ """
25
+
26
+ from symexpress3 import symexpress3
27
+ from symexpress3 import optTypeBase
28
+
29
+ #
30
+ # base class for a specific sym function type
31
+ #
32
+ class OptFunctionBase( optTypeBase.OptTypeBase ):
33
+ """
34
+ Base class for type function optimization
35
+ """
36
+ def __init__( self ):
37
+ super().__init__()
38
+ self._name = None # must be set by in the real class
39
+ self._symtype = symexpress3.SymFunction # symexpress type class, example symexpress3.SymNumber, symexpress3.SymVariable, symexpress3.SymFunction
40
+ self._desc = "" # description of the optimization
41
+ self._funcName = None # name of the function
42
+ self._minparams = 1 # minimum number of parameters
43
+ self._maxparams = 1 # maximum number of parameters
44
+
45
+
46
+ @property
47
+ def functionName(self):
48
+ """
49
+ Name of the function
50
+ """
51
+ return self._funcName
52
+
53
+ @property
54
+ def minimumNumberOfParameters(self):
55
+ """
56
+ Minimum number of parameters
57
+ """
58
+ return self._minparams
59
+
60
+ @property
61
+ def maximumNumberOfParameters(self):
62
+ """
63
+ Maximum number of parameters
64
+ """
65
+ return self._maxparams
66
+
67
+
68
+ def checkType( self, elem, action ):
69
+ """
70
+ Check if the given elem
71
+ """
72
+ if super().checkType( elem, action ) != True:
73
+ # print("Name: " + self.name )
74
+ # print("Type: " + str( self._symtype ))
75
+ # print( "test 1")
76
+ return False
77
+
78
+ if elem.name != self.functionName:
79
+ return False
80
+
81
+ numElem = elem.numElements()
82
+ if numElem < self._minparams :
83
+ return False
84
+
85
+ if numElem > self._maxparams :
86
+ return False
87
+
88
+ return True
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Sym Express 3
6
+
7
+ Copyright (C) 2024 Gien van den Enden - swvandenenden@gmail.com
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+ """
24
+
25
+ from symexpress3 import symexpress3
26
+ from symexpress3 import optTypeBase
27
+
28
+ class OptSymAnyArrayPower( optTypeBase.OptTypeBase ):
29
+ """
30
+ Put the power of an array into his elements
31
+ """
32
+ def __init__( self ):
33
+ super().__init__()
34
+ self._name = "arrayPower"
35
+ self._desc = "Put the power of an array into his elements"
36
+
37
+ def optimize( self, elem, action ):
38
+ if self.checkType( elem, action ) != True:
39
+ return None
40
+
41
+ if not isinstance( elem, symexpress3.SymArray) :
42
+ return None
43
+
44
+ if elem.power == 1 and elem.onlyOneRoot == 1 :
45
+ return None
46
+
47
+ newArray = symexpress3.SymArray()
48
+
49
+ for iCnt, elemsub in enumerate( elem.elements ):
50
+ symSub = symexpress3.SymExpress( '*' )
51
+ symSub.powerCounter = elem.powerCounter
52
+ symSub.powerDenominator = elem.powerDenominator
53
+ symSub.powerSign = elem.powerSign
54
+ symSub.onlyOneRoot = elem.onlyOneRoot
55
+ symSub.add( elemsub )
56
+ newArray.add( symSub )
57
+
58
+ return newArray
59
+
60
+ #
61
+ # Test routine (unit test), see testsymexpress3.py
62
+ #
63
+ def Test( display = False):
64
+ """
65
+ Unit test
66
+ """
67
+ symTest = symexpress3.SymFormulaParser( "[ 4 | 2 ]^^2" )
68
+ symTest.optimize()
69
+ symTest = symTest.elements[ 0 ]
70
+ testClass = OptSymAnyArrayPower()
71
+ symNew = testClass.optimize( symTest, "arrayPower" )
72
+
73
+ if display == True :
74
+ print( f"naam : {testClass.name}" )
75
+ print( f"orginal : {str( symTest )}" )
76
+ print( f"optimized : {str( symNew )}" )
77
+
78
+ if str( symNew ).strip() != "[ (4)^^2 | (2)^^2 ]":
79
+ print( f"Error unit test {testClass.name} function" )
80
+ raise NameError( f'SymAny optimze {testClass.name}, unit test error: {str( symTest )}, value: {symNew}' )
81
+
82
+
83
+ if __name__ == '__main__':
84
+ Test( True )
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Sym Express 3
6
+
7
+ Copyright (C) 2024 Gien van den Enden - swvandenenden@gmail.com
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+ """
24
+
25
+ from symexpress3 import symexpress3
26
+ from symexpress3 import optTypeBase
27
+
28
+ class OptSymAnyExpandArray( optTypeBase.OptTypeBase ):
29
+ """
30
+ If the expression containts at least 1 array then make the hole expression an array element.
31
+ """
32
+ def __init__( self ):
33
+ super().__init__()
34
+ self._name = "expandArrays"
35
+ self._desc = "If the expression containts at least 1 array then make the hole expression an array element."
36
+
37
+ def optimize( self, elem, action ):
38
+
39
+ def _subExpandSymArray( elem ):
40
+ if elem.power != 1 or elem.onlyOneRoot != 1 : # use arrayPower first
41
+ return None
42
+
43
+ result = None
44
+ # for iCnt, elemsub in enumerate( elem.elements ):
45
+ for elemsub in elem.elements:
46
+ if isinstance( elemsub, symexpress3.SymArray ):
47
+ if elemsub.power != 1 or elemsub.onlyOneRoot != 1:
48
+ continue
49
+ result = symexpress3.SymArray()
50
+ break
51
+ if result != None:
52
+ # power is always 1 on this point
53
+ for iCnt, elemsub in enumerate( elem.elements ):
54
+ if isinstance( elemsub, symexpress3.SymArray ) and elemsub.power == 1 and elemsub.onlyOneRoot == 1:
55
+ # get the sub elements
56
+ for elemsub2 in elemsub.elements :
57
+ result.add( elemsub2 )
58
+ else:
59
+ result.add( elemsub )
60
+
61
+ return result
62
+
63
+ def _subExpandSymFunction( elem ):
64
+ result = None
65
+ iArrPos = -1
66
+ for iCnt, elemsub in enumerate( elem.elements ):
67
+ if isinstance( elemsub, symexpress3.SymArray ):
68
+ if elemsub.power != 1 or elemsub.onlyOneRoot != 1:
69
+ continue
70
+ iArrPos = iCnt
71
+ if iArrPos == -1:
72
+ return None
73
+
74
+ result = symexpress3.SymArray()
75
+ arrElem = elem.elements[ iArrPos ].copy()
76
+ iNumArray = arrElem.numElements()
77
+ elem.elements[ iArrPos ] = symexpress3.SymNumber() # place holder
78
+
79
+ for iCnt in range( 0, iNumArray ):
80
+ elemSub = elem.copy()
81
+ elemSub.elements[ iArrPos ] = arrElem.elements[ iCnt ]
82
+ result.add( elemSub )
83
+
84
+ return result
85
+
86
+ def _subExpandSymSymExpress( elem ):
87
+ return _subExpandSymFunction( elem )
88
+
89
+
90
+ if self.checkType( elem, action ) != True:
91
+ return None
92
+
93
+ # if not isinstance( elem, ( symexpress3.SymArray, symexpress3.SymFunction, symexpress3.SymExpress)) :
94
+ if not isinstance( elem, ( symexpress3.SymArray, symexpress3.SymFunction)) :
95
+ return None
96
+
97
+ result = None
98
+ if isinstance( elem, symexpress3.SymArray ):
99
+ result = _subExpandSymArray( elem )
100
+ elif isinstance( elem, symexpress3.SymFunction ):
101
+ result = _subExpandSymFunction( elem )
102
+ # elif isinstance( elem, symexpress3.SymExpress ):
103
+ # result = _subExpandSymSymExpress( elem )
104
+ return result
105
+
106
+
107
+ #
108
+ # Test routine (unit test), see testsymexpress3.py
109
+ #
110
+ def Test( display = False):
111
+ """
112
+ Unit test
113
+ """
114
+ symTest = symexpress3.SymFormulaParser( "[ 4 | [ a | b ] | 4 ]" )
115
+ symTest.optimize()
116
+ symTest = symTest.elements[ 0 ]
117
+ testClass = OptSymAnyExpandArray()
118
+ symNew = testClass.optimize( symTest, "expandArrays" )
119
+
120
+ if display == True :
121
+ print( f"naam : {testClass.name}" )
122
+ print( f"orginal : {str( symTest )}" )
123
+ print( f"optimized : {str( symNew )}" )
124
+
125
+ if str( symNew ).strip() != "[ 4 | a | b | 4 ]":
126
+ print( f"Error unit test {testClass.name} function" )
127
+ raise NameError( f'SymAny optimze {testClass.name}, unit test error: {str( symTest )}, value: {symNew}' )
128
+
129
+
130
+ symTest = symexpress3.SymFormulaParser( "cos( 1, [ 2 | 3 ], 4)" )
131
+ symTest.optimize()
132
+ symTest = symTest.elements[ 0 ]
133
+ testClass = OptSymAnyExpandArray()
134
+ symNew = testClass.optimize( symTest, "expandArrays" )
135
+
136
+ if display == True :
137
+ print( f"naam : {testClass.name}" )
138
+ print( f"orginal : {str( symTest )}" )
139
+ print( f"optimized : {str( symNew )}" )
140
+
141
+ if str( symNew ).strip() != "[ cos( 1,2,4 ) | cos( 1,3,4 ) ]":
142
+ print( f"Error unit test {testClass.name} function" )
143
+ raise NameError( f'SymAny optimze {testClass.name}, unit test error: {str( symTest )}, value: {symNew}' )
144
+
145
+
146
+ # symTest = symexpress3.SymFormulaParser( "4 + [ 5 | 6 ]" )
147
+ # symTest.optimize()
148
+ # # symTest = symTest.elements[ 0 ]
149
+ # testClass = OptSymAnyExpandArray()
150
+ # symNew = testClass.optimize( symTest, "expandArrays" )
151
+
152
+ # if display == True :
153
+ # print( f"naam : {testClass.name}" )
154
+ # print( f"orginal : {str( symTest )}" )
155
+ # print( f"optimized : {str( symNew )}" )
156
+
157
+ # if str( symNew ).strip() != "[ 4 + 5 | 4 + 6 ]":
158
+ # print( f"Error unit test {testClass.name} function" )
159
+ # raise NameError( f'SymAny optimze {testClass.name}, unit test error: {str( symTest )}, value: {symNew}' )
160
+
161
+
162
+ if __name__ == '__main__':
163
+ Test( True )
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Registration any optimze for symexpress3
6
+
7
+ Copyright (C) 2024 Gien van den Enden - swvandenenden@gmail.com
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+ Example documentenion:
24
+ pdoc3 --html symFuncCeilFloor.py
25
+
26
+ """
27
+
28
+ from symexpress3 import symtables
29
+ from symexpress3.optSymAny import optSymAnyArrayPower
30
+ from symexpress3.optSymAny import optSymAnyExpandArray
31
+
32
+ #
33
+ # automatic called from symepxress3
34
+ #
35
+ def SymRegisterOptimize():
36
+ """
37
+ Register all the any optimize classes
38
+ """
39
+ symtables.RegisterTableEntry( 'optSymAny', optSymAnyArrayPower.OptSymAnyArrayPower() )
40
+ symtables.RegisterTableEntry( 'optSymAny', optSymAnyExpandArray.OptSymAnyExpandArray() )
41
+
42
+ #
43
+ # Get all the modules from the optSymVariable, used in testsymexpress3.py
44
+ #
45
+ def SymRegisterGetModuleNames():
46
+ """
47
+ Get all the modules of the any optimizes
48
+ """
49
+
50
+ symModules = []
51
+
52
+ symModules.append( optSymAnyArrayPower )
53
+ symModules.append( optSymAnyExpandArray )
54
+
55
+ return symModules
56
+
57
+ if __name__ == '__main__':
58
+ SymRegisterOptimize()
59
+ print( "Modules: " + str( ( SymRegisterGetModuleNames() )))
60
+ # print( "globals: " + str( globals() ))
@@ -0,0 +1,5 @@
1
+ """
2
+ Optimze functions
3
+ """
4
+ # from .symRegisterOptSymFunction import SymRegisterOptimize
5
+ # SymRegisterOptimize()
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Sym Express 3
6
+
7
+ Copyright (C) 2024 Gien van den Enden - swvandenenden@gmail.com
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+
24
+ """
25
+
26
+ from symexpress3 import symexpress3
27
+ from symexpress3 import optFunctionBase
28
+
29
+ class OptSymFunctionCosAtanDiv3( optFunctionBase.OptFunctionBase ):
30
+ """
31
+ sin(atan(x)/n) to sin i cos
32
+ """
33
+ def __init__( self ):
34
+ super().__init__()
35
+ self._name = "cosAtanDiv3"
36
+ self._desc = "Convert cos(atan(x)/3) to value"
37
+ self._funcName = "cos" # name of the function
38
+ self._minparams = 1 # minimum number of parameters
39
+ self._maxparams = 1 # maximum number of parameters
40
+
41
+
42
+ def optimize( self, elem, action ):
43
+ # https://www.quora.com/Is-there-a-method-to-calculate-cos-%CF%80-7-and-sin-%CF%80-7
44
+ if self.checkType( elem, action ) != True:
45
+ return None
46
+
47
+ elem1 = elem.elements[0]
48
+ if not isinstance( elem1, symexpress3.SymExpress ):
49
+ return None
50
+
51
+ if elem1.symType != '*':
52
+ return None
53
+
54
+ if elem1.numElements() != 2: # can be any number greater as 1 but for the moment only atan
55
+ return None
56
+
57
+ elemA = elem1.elements[0]
58
+ elemB = elem1.elements[1]
59
+ # one must be a function, second must be number
60
+
61
+ if not isinstance( elemA, symexpress3.SymFunction):
62
+ elemB = elem1.elements[0]
63
+ elemA = elem1.elements[1]
64
+
65
+ if not isinstance( elemA, symexpress3.SymFunction):
66
+ return None
67
+
68
+ if not isinstance( elemB, symexpress3.SymNumber):
69
+ return None
70
+
71
+ if elemA.name != "atan": # can be anything but for the moment only atan
72
+ return None
73
+
74
+ if elemB.power != 1:
75
+ return None
76
+
77
+ if elemB.factSign != 1:
78
+ return None
79
+
80
+ if elemB.factCounter != 1:
81
+ return None
82
+
83
+ if elemB.factDenominator != 3:
84
+ return None
85
+
86
+ # elemA = atan(x)
87
+ # elemB = 1/3
88
+
89
+ # "(( ((cos(x)^^2 - 1)^^(1/2) + cos(x))^^(1/3) + ( ((cos(x)^^2 - 1)^^(1/2) + cos(x))^^(1/3) )^^(-1))) * 1/2"
90
+
91
+ convertFrm = "(( ((cos(" + str( elemA ) + ")^^2 - 1)^^(1/2) + cos(" + str(elemA) + "))^^(1/3) + (( ((cos(" + str( elemA ) + ")^^2 - 1)^^(1/2) + cos(" + str(elemA) + "))^^(1/3) )^^(-1))) * 1/2"
92
+
93
+ exprResult = symexpress3.SymFormulaParser( convertFrm )
94
+
95
+ return exprResult
96
+ # https://www.quora.com/What-is-the-formula-for-sin-x-3-one-third-angle-formula
97
+ # sin(x/3) =
98
+ # (
99
+ # ( -1 * sin( x ) + (sin(x)^^2 - 1)^^(1/2) ) / 8
100
+ # )^^(1/3)
101
+ # +
102
+ # (
103
+ # ( -1 * sin( x ) - (sin(x)^^2 - 1)^^(1/2) ) / 8
104
+ # )^^(1/3)
105
+ #
106
+ # incorrecte antwoorden in de volgende situaties:
107
+ # x = pi / 2 - 1/10 -> fout antwoord, dezelfde als pi / 2 + 1/10
108
+ # x = pi / 2 + 1/10 -> goed antwoord
109
+ # x = pi / 2 -> goed antwoord -> dit lijkt een spiegel (mirror) te zijn,
110
+ # Alles hieronder is fout, alles hierboven is goed`
111
+
112
+ #
113
+ # Test routine (unit test), see testsymexpress3.py
114
+ #
115
+ def Test( display = False):
116
+ """
117
+ Unit test
118
+ """
119
+ symTest = symexpress3.SymFormulaParser( "cos(atan(x)/3)" )
120
+ symTest.optimize()
121
+ symTest = symTest.elements[ 0 ]
122
+
123
+ # print( "symTest: " + str( symTest ))
124
+
125
+ testClass = OptSymFunctionCosAtanDiv3()
126
+ symNew = testClass.optimize( symTest, "cosAtanDiv3" )
127
+
128
+ if display == True :
129
+ print( f"naam : {testClass.name}" )
130
+ print( f"orginal : {str( symTest )}" )
131
+ print( f"optimized : {str( symNew )}" )
132
+
133
+ if str( symNew ).strip() != "((( cos( atan( x ) )^^2 + (-1) * 1)^^(1/2) + cos( atan( x ) ))^^(1/3) + ((( cos( atan( x ) )^^2 + (-1) * 1)^^(1/2) + cos( atan( x ) ))^^(1/3))^^-1) * 1 * 2^^-1":
134
+ print( f"Error unit test {testClass.name} function" )
135
+ raise NameError( f'SymFunction optimze {testClass.name}, unit test error: {str( symTest )}, value: {str( symNew )}' )
136
+
137
+
138
+ if __name__ == '__main__':
139
+ Test( True )