@@ -9,21 +9,25 @@ namespace SpiceSharpBehavioral.Builders
99 /// </summary>
1010 public static class HelperFunctions
1111 {
12+ /// <summary>
13+ /// Gets or sets a fudge factor for avoid edge cases (like division by 0).
14+ /// </summary>
15+ public static double FudgeFactor { get ; set ; } = 1e-32 ;
16+
1217 /// <summary>
1318 /// Divides two numbers while avoiding division by 0 using a fudge factor.
1419 /// </summary>
1520 /// <param name="left">The left argument.</param>
1621 /// <param name="right">The right argument.</param>
17- /// <param name="fudgeFactor">The fudge factor.</param>
1822 /// <returns>
1923 /// The division.
2024 /// </returns>
21- public static double SafeDivide ( double left , double right , double fudgeFactor )
25+ public static double SafeDivide ( double left , double right )
2226 {
2327 if ( right < 0 )
24- right -= fudgeFactor ;
28+ right -= FudgeFactor ;
2529 else
26- right += fudgeFactor ;
30+ right += FudgeFactor ;
2731 if ( right . Equals ( 0.0 ) )
2832 return double . PositiveInfinity ;
2933 return left / right ;
@@ -34,18 +38,17 @@ public static double SafeDivide(double left, double right, double fudgeFactor)
3438 /// </summary>
3539 /// <param name="left">The left argument.</param>
3640 /// <param name="right">The right argument.</param>
37- /// <param name="fudgeFactor">The fudge factor.</param>
3841 /// <returns>
3942 /// The division.
4043 /// </returns>
41- public static Complex SafeDivide ( Complex left , Complex right , double fudgeFactor )
44+ public static Complex SafeDivide ( Complex left , Complex right )
4245 {
43- if ( Math . Abs ( right . Imaginary ) < fudgeFactor )
46+ if ( Math . Abs ( right . Imaginary ) . Equals ( 0.0 ) )
4447 {
4548 if ( right . Real < 0 )
46- right -= fudgeFactor ;
49+ right -= FudgeFactor ;
4750 else
48- right += fudgeFactor ;
51+ right += FudgeFactor ;
4952 }
5053 if ( right . Real . Equals ( 0.0 ) && right . Imaginary . Equals ( 0.0 ) )
5154 return double . PositiveInfinity ;
@@ -82,7 +85,11 @@ public static bool Equals(double left, double right, double relTol, double absTo
8285 /// </returns>
8386 public static bool Equals ( Complex left , Complex right , double relTol , double absTol )
8487 {
85- if ( ! Equals ( left . Real , right . Real ) || ! Equals ( left . Imaginary , right . Imaginary ) )
88+ var tol = Math . Max ( Math . Abs ( left . Real ) , Math . Abs ( right . Real ) ) * relTol + absTol ;
89+ if ( Math . Abs ( left . Real - right . Real ) > tol )
90+ return false ;
91+ tol = Math . Max ( Math . Abs ( left . Imaginary ) , Math . Abs ( right . Imaginary ) ) * relTol + absTol ;
92+ if ( Math . Abs ( left . Imaginary - right . Imaginary ) > tol )
8693 return false ;
8794 return true ;
8895 }
@@ -135,13 +142,31 @@ public static Complex Log10(Complex arg)
135142 return Complex . Log10 ( arg ) ;
136143 }
137144
145+ /// <summary>
146+ /// Raises a number to a power.
147+ /// </summary>
148+ /// <param name="left">The left argument.</param>
149+ /// <param name="right">The right argument.</param>
150+ /// <returns></returns>
151+ public static double Pow ( double left , double right )
152+ {
153+ if ( left . Equals ( 0.0 ) && right <= 0.0 )
154+ left += FudgeFactor ;
155+ return Math . Pow ( left , right ) ;
156+ }
157+
138158 /// <summary>
139159 /// Raises a number to a power. The function is made symmetrical. Also known as "pwr".
140160 /// </summary>
141161 /// <param name="left">The left argument.</param>
142162 /// <param name="right">The right argument.</param>
143163 /// <returns>The result.</returns>
144- public static double Power ( double left , double right ) => Math . Pow ( Math . Abs ( left ) , right ) ;
164+ public static double Power ( double left , double right )
165+ {
166+ if ( left . Equals ( 0.0 ) && right <= 0.0 )
167+ left += FudgeFactor ;
168+ return Math . Pow ( Math . Abs ( left ) , right ) ;
169+ }
145170
146171 /// <summary>
147172 /// Raises a number to a power. The function is made radially symmetrical. Also known as "pwr".
@@ -162,7 +187,11 @@ public static double Power2(double left, double right)
162187 if ( left < 0 )
163188 return - Math . Pow ( - left , right ) ;
164189 else
190+ {
191+ if ( left . Equals ( 0.0 ) && right < 0.0 )
192+ left += FudgeFactor ;
165193 return Math . Pow ( left , right ) ;
194+ }
166195 }
167196
168197 /// <summary>
@@ -178,7 +207,12 @@ public static Complex Power2(Complex left, Complex right)
178207 if ( left . Real < 0 )
179208 return - Complex . Pow ( - left . Real , right ) ;
180209 else
181- return Complex . Pow ( left . Real , right ) ;
210+ {
211+ double r = left . Real ;
212+ if ( r . Equals ( 0.0 ) && right . Real < 0.0 )
213+ r += FudgeFactor ;
214+ return Complex . Pow ( r , right ) ;
215+ }
182216 }
183217
184218 /// <summary>
0 commit comments