@@ -59,7 +59,7 @@ private MathFuncNode Precompile(MathFuncNode parent, MathFuncNode node)
5959 break ;
6060 }
6161
62- if ( node . Childs . All ( child => child . Type == MathNodeType . Value || child . Type == MathNodeType . Calculated ) )
62+ if ( node . Childs . Count > 0 && node . Childs . All ( child => child . Type == MathNodeType . Value || child . Type == MathNodeType . Calculated ) )
6363 return ( MathFuncNode ) CalculateValues ( ( ( FuncNode ) node ) . FunctionType , node . Childs ) ?? ( MathFuncNode ) node ;
6464 else
6565 return node ;
@@ -68,61 +68,66 @@ private MathFuncNode Precompile(MathFuncNode parent, MathFuncNode node)
6868 return node ;
6969 }
7070
71- private FuncNode PrecompileAddFunc ( FuncNode funcNode )
71+ private MathFuncNode PrecompileAddFunc ( FuncNode funcNode )
7272 {
7373 MathFuncNode firstItem ;
7474 MathFuncNode result = null ;
7575
76- firstItem = funcNode . Childs . FirstOrDefault ( node =>
76+ var funcNode2 = FoldCalculatedSummands ( funcNode ) ;
77+
78+ firstItem = funcNode2 . Childs . FirstOrDefault ( node =>
7779 {
7880 var func = node as FuncNode ;
7981 return ! ( func != null && func . LessThenZero ( ) ) ;
8082 } ) ;
8183
8284 if ( firstItem == null )
83- firstItem = funcNode . Childs [ 0 ] ;
85+ firstItem = funcNode2 . Childs [ 0 ] ;
8486
8587 result = firstItem ;
8688
87- for ( int i = 0 ; i < funcNode . Childs . Count ; i ++ )
89+ for ( int i = 0 ; i < funcNode2 . Childs . Count ; i ++ )
8890 {
89- if ( funcNode . Childs [ i ] == firstItem )
91+ if ( funcNode2 . Childs [ i ] == firstItem )
9092 continue ;
9193
92- if ( funcNode . Childs [ i ] . LessThenZero ( ) )
93- result = new FuncNode ( KnownFuncType . Sub , result , funcNode . Childs [ i ] . Abs ( ) ) ;
94+ if ( funcNode2 . Childs [ i ] . LessThenZero ( ) )
95+ result = new FuncNode ( KnownFuncType . Sub , result , funcNode2 . Childs [ i ] . Abs ( ) ) ;
9496 else
95- result = new FuncNode ( KnownFuncType . Add , result , funcNode . Childs [ i ] ) ;
97+ result = new FuncNode ( KnownFuncType . Add , result , funcNode2 . Childs [ i ] ) ;
9698 }
9799
98- return ( FuncNode ) result ;
100+ return result ;
99101 }
100102
101- private FuncNode PrecompileMultFunc ( FuncNode funcNode )
103+ private MathFuncNode PrecompileMultFunc ( FuncNode funcNode )
102104 {
103105 MathFuncNode firstItem ;
104106 MathFuncNode result = null ;
105107
106- firstItem = funcNode . Childs . FirstOrDefault ( node =>
108+ var funcNode2 = MultCalculatedFactors ( funcNode ) ;
109+ //var funcNode2 = funcNode;
110+
111+ firstItem = funcNode2 . Childs . FirstOrDefault ( node =>
107112 {
108113 var func = node as FuncNode ;
109114 return ! ( func != null && func . FunctionType == KnownFuncType . Exp && func . Childs [ 1 ] . LessThenZero ( ) ) ;
110115 } ) ;
111116
112117 if ( firstItem == null )
113118 {
114- firstItem = funcNode . Childs [ 0 ] ;
115- result = PrecompileExpFunc ( null , ( FuncNode ) funcNode . Childs [ 0 ] ) ;
119+ firstItem = funcNode2 . Childs [ 0 ] ;
120+ result = PrecompileExpFunc ( null , ( FuncNode ) funcNode2 . Childs [ 0 ] ) ;
116121 }
117122 else
118123 result = firstItem ;
119124
120- for ( int i = 0 ; i < funcNode . Childs . Count ; i ++ )
125+ for ( int i = 0 ; i < funcNode2 . Childs . Count ; i ++ )
121126 {
122- if ( funcNode . Childs [ i ] == firstItem )
127+ if ( funcNode2 . Childs [ i ] == firstItem )
123128 continue ;
124129
125- FuncNode funcChildNode = funcNode . Childs [ i ] as FuncNode ;
130+ FuncNode funcChildNode = funcNode2 . Childs [ i ] as FuncNode ;
126131 if ( funcChildNode != null && funcChildNode . FunctionType == KnownFuncType . Exp && funcChildNode . Childs [ 1 ] . LessThenZero ( ) )
127132 {
128133 if ( ! funcChildNode . Childs [ 1 ] . IsValueOrCalculated || funcChildNode . Childs [ 1 ] . DoubleValue != - 1.0 )
@@ -140,10 +145,10 @@ private FuncNode PrecompileMultFunc(FuncNode funcNode)
140145 result = new FuncNode ( KnownFuncType . Div , result , funcChildNode . Childs [ 0 ] ) ;
141146 }
142147 else
143- result = new FuncNode ( KnownFuncType . Mult , result , funcNode . Childs [ i ] ) ;
148+ result = new FuncNode ( KnownFuncType . Mult , result , funcNode2 . Childs [ i ] ) ;
144149 }
145150
146- return ( FuncNode ) result ;
151+ return result ;
147152 }
148153
149154 private FuncNode PrecompileExpFunc ( MathFuncNode parent , FuncNode funcNode )
@@ -277,6 +282,43 @@ private CalculatedNode CalculateValues(KnownFuncType? funcType, IList<MathFuncNo
277282 }
278283 }
279284
285+ private FuncNode FoldCalculatedSummands ( FuncNode sum )
286+ {
287+ var result = sum . Childs
288+ . Where ( child => child . Type == MathNodeType . Calculated || child . Type == MathNodeType . Value )
289+ . Select ( summand => summand . DoubleValue )
290+ . Aggregate ( 0.0 , ( t , factor ) => t += factor ) ;
291+
292+ if ( result != 0.0 )
293+ {
294+ var newChilds = new List < MathFuncNode > ( ) { new CalculatedNode ( result ) } ;
295+ newChilds . AddRange ( sum . Childs . Where ( c => c . Type != MathNodeType . Calculated && c . Type != MathNodeType . Value ) ) ;
296+
297+ return new FuncNode ( KnownFuncType . Sub , newChilds ) ;
298+ }
299+ else
300+ return sum ;
301+ }
302+
303+ private FuncNode MultCalculatedFactors ( FuncNode mult )
304+ {
305+ var result = mult . Childs
306+ . Where ( child => child . Type == MathNodeType . Calculated || child . Type == MathNodeType . Value )
307+ . Select ( factor => factor . DoubleValue )
308+ . Aggregate ( 1.0 , ( t , factor ) => t *= factor ) ;
309+
310+ if ( result != 1.0 )
311+ {
312+ var newChilds = new List < MathFuncNode > ( ) { new CalculatedNode ( result ) } ;
313+ newChilds . AddRange ( mult . Childs . Where ( c => c . Type != MathNodeType . Calculated && c . Type != MathNodeType . Value ) ) ;
314+
315+ return new FuncNode ( KnownFuncType . Mult , newChilds ) ;
316+ }
317+ else
318+ return mult ;
319+ }
320+
321+
280322 #endregion
281323 }
282324}
0 commit comments