public static Signal PolynomialDivision(Signal numerator, Signal denominator, Signal variable, out Signal remainder) { Signal[] R = PolynomialCoefficients(numerator, variable); Signal[] B = PolynomialCoefficients(denominator, variable); int degB = B.Length - 1; Signal lcB = B[degB]; Signal[] Q = new Signal[R.Length - degB]; for (int delta = R.Length - 1 - degB; delta >= 0; delta--) { int degR = degB + delta; if (Std.IsConstantAdditiveIdentity(R[degR])) { Q[delta] = R[degR]; continue; } Signal T = Std.Divide(R[degR], lcB); Q[delta] = T; R[degB + delta] = IntegerValue.ConstantZero; for (int i = delta; i < degB + delta; i++) { R[i] = Std.Subtract(R[i], Std.Multiply(B[i - delta], T)); } } remainder = ConstructPolynomial(variable, R); return(ConstructPolynomial(variable, Q)); }
/// <summary> /// Checks whether a signal is a single variable monomial, e.g. '2*x^3' /// </summary> /// <remarks><see cref="signal"/> is assumed to be automatic simplified</remarks> public static bool IsMonomial(Signal signal, Signal variable) { if (signal == null) { throw new ArgumentNullException("signal"); } if (Std.IsAlwaysRational(signal)) { return(true); } if (signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && Std.IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) { signal = signal.DrivenByPort.InputSignals[1]; } if (signal.Equals(variable)) { return(true); } if (signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if (b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) { return(true); } } return(false); }
/// <summary> /// Returns the coefficient u[exponent] of x^exponent in the polynomial <see cref="signal"/> /// </summary> /// <returns> /// Constant UndefinedSymbol if <see cref="signal"/> is not a single-variable polynomial. /// Constant <see cref="IntegerValue.Zero"/> if there's no summand with the given exponent. /// Otherwise the sum of all coefficient factors of the term with the given exponent. /// </returns> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static Signal PolynomialCoefficient(Signal signal, Signal variable, int exponent) { IValueStructure vs; Signal c = MonomialCoefficient(signal, variable, out vs); if (!(vs is UndefinedSymbol)) { IntegerValue iv = vs as IntegerValue; if (iv == null || iv.Value == exponent) { return(c); } else { return(IntegerValue.ConstantZero); } } if (signal.IsDrivenByPortEntity("Add", "Std")) { ISignalSet inputs = signal.DrivenByPort.InputSignals; List <Signal> coeffs = new List <Signal>(4); for (int i = 0; i < inputs.Count; i++) { c = MonomialCoefficient(inputs[i], variable, out vs); IntegerValue iv = vs as IntegerValue; if (iv != null && iv.Value == exponent) { coeffs.Add(c); } } return(Std.Add(coeffs)); } return(UndefinedSymbol.Constant); }
/// <summary> /// Evaluates the degree of the single-variable monomial <see cref="signal"/>. /// </summary> /// <returns> /// <see cref="UndefinedSymbol"/> if <see cref="signal"/> is not a single-variable monomial. /// <see cref="NegativeInfinitySymbol"/> if <see cref="signal"/> is zero. /// Otherwise an <see cref="IntegerValue"/> representing the asked degree. /// </returns> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static IValueStructure MonomialDegree(Signal signal, Signal variable) { if (signal == null) { throw new ArgumentNullException("signal"); } if (Std.IsConstantAdditiveIdentity(signal)) { return(NegativeInfinitySymbol.Instance); } if (Std.IsAlwaysRational(signal)) { return(IntegerValue.Zero); } if (signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && Std.IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) { signal = signal.DrivenByPort.InputSignals[1]; } if (signal.Equals(variable)) { return(IntegerValue.One); } if (signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if (b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) { return(e.Value); } } return(UndefinedSymbol.Instance); }
public static Signal[] PolynomialVariables(Signal signal) { List <Signal> variables = new List <Signal>(); ISignalSet monomials; if (signal.IsDrivenByPortEntity("Add", "Std")) { monomials = signal.DrivenByPort.InputSignals; } else { monomials = new SignalSet(signal); } for (int i = 0; i < monomials.Count; i++) { ISignalSet factors; if (monomials[i].IsDrivenByPortEntity("Multiply", "Std")) { factors = monomials[i].DrivenByPort.InputSignals; } else { factors = new SignalSet(monomials[i]); } for (int j = 0; j < factors.Count; j++) { if (Std.IsAlwaysRational(factors[j])) { continue; } if (factors[j].IsDrivenByPortEntity("Power", "Std")) { Signal b = factors[j].DrivenByPort.InputSignals[0]; if (Std.IsAlwaysPositiveInteger(factors[j].DrivenByPort.InputSignals[1])) { if (!variables.Contains(b)) { variables.Add(b); } } else { if (!variables.Contains(signal)) { variables.Add(signal); } } } else if (!variables.Contains(factors[j])) { variables.Add(factors[j]); } } } return(variables.ToArray()); }
public static Signal ConstructPolynomial <TCoeff>(Signal variable, params TCoeff[] coefficients) where TCoeff : IAlgebraicRingWithUnity <TCoeff>, IValueStructure { Signal zero = null; Signal[] summands = new Signal[coefficients.Length]; for (int i = 0; i < summands.Length; i++) { TCoeff c = coefficients[i]; if (c.IsAdditiveIdentity) { if (zero == null) { zero = Std.DefineConstant(c); } summands[i] = zero; continue; } Signal coeff = Std.DefineConstant(c); if (i == 0) { summands[0] = coeff; } else if (i == 1) { if (c.IsMultiplicativeIdentity) { summands[1] = variable; } else { summands[1] = StdBuilder.Multiply(coeff, variable); } } else { if (c.IsMultiplicativeIdentity) { summands[i] = StdBuilder.Power(variable, IntegerValue.Constant(i)); } else { summands[i] = StdBuilder.Multiply(coeff, StdBuilder.Power(variable, IntegerValue.Constant(i))); } } } return(Std.Add(summands)); }
/// <summary> /// Checks whether a signal is a single variable rational, a fraction of polynomials. /// </summary> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static bool IsRational(Signal signal, Signal variable) { if (signal == null) { throw new ArgumentNullException("signal"); } if (signal.IsDrivenByPortEntity("Divide", "Std")) { return(IsPolynomial(Std.Numerator(signal), variable) && IsPolynomial(Std.Denominator(signal), variable)); } else { return(IsPolynomial(signal, variable)); } }
public static IValueStructure MonomialDegree(Signal signal, Signal[] generalizedVariables) { if (Std.IsConstantAdditiveIdentity(signal)) { return(NegativeInfinitySymbol.Instance); } if (Array.Exists <Signal>(generalizedVariables, signal.Equals)) { return(IntegerValue.One); } if (!Array.Exists <Signal>(generalizedVariables, signal.DependsOn)) { return(IntegerValue.Zero); } ISignalSet factors; long deg = 0; if (signal.IsDrivenByPortEntity("Multiply", "Std")) { factors = signal.DrivenByPort.InputSignals; } else { factors = new SignalSet(signal); } for (int i = 0; i < factors.Count; i++) { if (Array.Exists <Signal>(generalizedVariables, factors[i].Equals)) { deg++; } else if (factors[i].IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; IntegerValue v; if (Array.Exists <Signal>(generalizedVariables, b.Equals) && (v = e.Value as IntegerValue) != null && v.Value > 0) { deg += v.Value; } } } return(new IntegerValue(deg)); }
/// <summary> /// Returns the coefficient factor in the monomial <see cref="signal"/> /// </summary> /// <returns> /// Constant UndefinedSymbol if <see cref="signal"/> is not a single-variable monomial. /// Otherwise the coefficient factor of the term. /// </returns> /// </returns> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static Signal MonomialCoefficient(Signal signal, Signal variable, out IValueStructure degree) { if (signal == null) { throw new ArgumentNullException("signal"); } if (Std.IsConstantAdditiveIdentity(signal)) { degree = NegativeInfinitySymbol.Instance; return(signal); } if (Std.IsAlwaysRational(signal)) { degree = IntegerValue.Zero; return(signal); } Signal coeff = IntegerValue.ConstantOne; if (signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && Std.IsAlwaysRational(signal.DrivenByPort.InputSignals[0])) { coeff = signal.DrivenByPort.InputSignals[0]; signal = signal.DrivenByPort.InputSignals[1]; } if (signal.Equals(variable)) { degree = IntegerValue.One; return(coeff); } if (signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if (b.Equals(variable) && Std.IsAlwaysPositiveInteger(e)) { degree = e.Value; return(coeff); } } degree = UndefinedSymbol.Instance; return(UndefinedSymbol.Constant); }
public static Signal ConstructPolynomial(Signal variable, params Signal[] coefficients) { Signal[] summands = new Signal[coefficients.Length]; for (int i = 0; i < summands.Length; i++) { Signal coeff = coefficients[i]; if (Std.IsConstantAdditiveIdentity(coeff)) { summands[i] = coeff; continue; } if (i == 0) { summands[0] = coeff; } else if (i == 1) { if (Std.IsConstantMultiplicativeIdentity(coeff)) { summands[1] = variable; } else { summands[1] = StdBuilder.Multiply(coeff, variable); } } else { if (Std.IsConstantMultiplicativeIdentity(coeff)) { summands[i] = StdBuilder.Power(variable, IntegerValue.Constant(i)); } else { summands[i] = StdBuilder.Multiply(coeff, StdBuilder.Power(variable, IntegerValue.Constant(i))); } } } return(Std.Add(summands)); }
private static bool IsMonomialFactor(Signal signal, Signal[] generalizedVariables) { if (Array.Exists <Signal>(generalizedVariables, signal.Equals)) { return(true); } if (!Array.Exists <Signal>(generalizedVariables, signal.DependsOn)) { return(true); } if (signal.IsDrivenByPortEntity("Power", "Std")) { Signal b = signal.DrivenByPort.InputSignals[0]; Signal e = signal.DrivenByPort.InputSignals[1]; if (Array.Exists <Signal>(generalizedVariables, b.Equals) && Std.IsAlwaysPositiveInteger(e)) { return(true); } } return(false); }
/// <summary> /// Extracts all coefficients of the polynomial <see cref="signal"/>. /// </summary> /// <returns>A signal array [c0,c1,c2,..] where ci ist the coefficient of x^i.</returns> public static Signal[] PolynomialCoefficients(Signal signal, Signal variable) { IValueStructure vs; SortedList <long, Signal> polynom = new SortedList <long, Signal>(); Signal c = MonomialCoefficient(signal, variable, out vs); if (!(vs is UndefinedSymbol)) { IntegerValue iv = vs as IntegerValue; if (iv != null) { polynom.Add(iv.Value, c); } else { return new Signal[] { IntegerValue.ConstantZero } }; } else if (signal.IsDrivenByPortEntity("Add", "Std")) { ISignalSet inputs = signal.DrivenByPort.InputSignals; for (int i = 0; i < inputs.Count; i++) { c = MonomialCoefficient(inputs[i], variable, out vs); IntegerValue iv = vs as IntegerValue; if (iv != null) { if (!polynom.ContainsKey(iv.Value)) { polynom.Add(iv.Value, c); } else { polynom[iv.Value] = Std.Add(polynom[iv.Value], c); } } } } if (polynom.Keys.Count == 0) { return new Signal[] { } } ; long deg = polynom.Keys[polynom.Keys.Count - 1]; Signal[] ret = new Signal[deg + 1]; Signal zero = IntegerValue.ConstantZero; for (int i = 0; i < ret.Length; i++) { if (polynom.ContainsKey(i)) { ret[i] = polynom[i]; } else { ret[i] = zero; } } return(ret); }