/// <summary> /// e. g. Pow(2, 5) = 32 /// </summary> /// <param name="base"> /// The base of the exponential, base^power /// </param> /// <param name="power"> /// The power of the exponential, base^power /// </param> /// <returns></returns> public static ComplexNumber Pow(ComplexNumber @base, ComplexNumber power) { // TODO: make it more detailed (e. g. +oo ^ +oo = +oo) if (power.IsInteger()) { return(Functional.Downcast(Functional.BinaryIntPow(@base as ComplexNumber, power.AsInt())) as ComplexNumber); } if (power.IsRational() && ((power as RationalNumber).Denominator.Value).Abs() < 10) // there should be a minimal threshold to avoid long searches { return(Number.Pow(FindGoodRoot(@base, (power as RationalNumber).Denominator), (power as RationalNumber).Numerator)); } var baseCom = @base.AsComplexNumber(); var powerCom = power.AsComplexNumber(); if (baseCom.IsDefinite() && powerCom.IsDefinite()) { try { return(Functional.Downcast( Complex.Pow(baseCom.AsComplex(), powerCom.AsComplex()) ) as ComplexNumber); } catch (OverflowException) { return(RealNumber.NaN()); } } else { return(ComplexNumber.Indefinite(RealNumber.UndefinedState.NAN)); } }
internal static ComplexNumber FindGoodRoot(ComplexNumber @base, IntegerNumber power) { var list = new List <ComplexNumber>(); foreach (var root in GetAllRoots(@base, (long)power.Value).FiniteSet()) { MathS.Settings.FloatToRationalIterCount.Set(15); MathS.Settings.PrecisionErrorZeroRange.Set(1e-6m); var downcasted = Functional.Downcast((root as NumberEntity).Value) as ComplexNumber; MathS.Settings.PrecisionErrorZeroRange.Unset(); MathS.Settings.FloatToRationalIterCount.Unset(); if (downcasted.IsRational() && Number.IsZero(Number.Pow(downcasted, power) - @base)) // To keep user's desired precision { return(downcasted); } list.Add(downcasted); } foreach (var el in list) { if (el.IsReal() && (el as RealNumber) > 0) { return(el); } } foreach (var el in list) { if (el.IsReal()) { return(el); } } return(list[0]); }