/// <summary> /// Separates factors in a product that depend on x from those that do not. /// </summary> /// <returns> /// A signal array [a,b], where a is the product of the factors not /// depending on x, and b the product of those depending on x. /// </returns> /// <remarks><see cref="product"/> is assumed to be automatic simplified</remarks> public static Signal[] SeparateFactors(Context context, Signal product, Signal x) { SignalSet freePart = new SignalSet(); SignalSet dependentPart = new SignalSet(); if(product.IsDrivenByPortEntity("Multiply", "Std")) { ReadOnlySignalSet factors = product.DrivenByPort.InputSignals; foreach(Signal s in factors) { if(s.DependsOn(x)) dependentPart.Add(s); else freePart.Add(s); } } else if(product.DependsOn(x)) dependentPart.Add(product); else freePart.Add(product); Signal freeSignal = context.Builder.MultiplySimplified(freePart); Signal dependentSignal = context.Builder.MultiplySimplified(dependentPart); return new Signal[] { freeSignal, dependentSignal }; }
public static ValueStructure MonomialDegree(Signal signal, Signal[] generalizedVariables) { if(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); }
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(IsAlwaysRational(factors[j])) continue; if(factors[j].IsDrivenByPortEntity("Power", "Std")) { Signal b = factors[j].DrivenByPort.InputSignals[0]; if(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 bool IsPolynomial(Signal signal, Signal[] generalizedVariables) { if(!signal.IsDrivenByPortEntity("Add", "Std")) return IsMonomial(signal, generalizedVariables); if(Array.Exists<Signal>(generalizedVariables, signal.Equals)) return true; return signal.DrivenByPort.InputSignals.TrueForAll(delegate(Signal s) { return IsMonomial(s, generalizedVariables); }); }
public static bool IsMonomial(Signal signal, Signal[] generalizedVariables) { if(signal.IsDrivenByPortEntity("Multiply", "Std")) return signal.DrivenByPort.InputSignals.TrueForAll(delegate(Signal s) {return IsMonomialFactor(s, generalizedVariables);}); else return IsMonomialFactor(signal, generalizedVariables); }
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; }
public static Signal Numerator(Signal signal) { if(signal == null) throw new ArgumentNullException("signal"); if(signal.IsDrivenByPortEntity("Divide", "Std")) return signal.DrivenByPort.InputSignals[0]; return signal; }
public static Signal Numerator(Signal signal) { if(signal.IsDrivenByPortEntity("Divide", "Std")) return signal.DrivenByPort.InputSignals[0]; return signal; }
/// <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 ValueStructure degree) { if(IsConstantAdditiveIdentity(signal)) { degree = NegativeInfinitySymbol.Instance; return signal; } if(IsAlwaysRational(signal)) { degree = IntegerValue.Zero; return signal; } Signal coeff = IntegerValue.ConstantOne(signal.Context); if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && 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(signal.Context); }
/// <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 ValueStructure MonomialDegree(Signal signal, Signal variable) { if(IsConstantAdditiveIdentity(signal)) return NegativeInfinitySymbol.Instance; if(IsAlwaysRational(signal)) return IntegerValue.Zero; if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && 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; }
/// <summary> /// Checks whether a signal is a signle 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.IsDrivenByPortEntity("Divide", "Std")) return IsPolynomial(Numerator(signal), variable) && IsPolynomial(Denominator(signal), variable); else return IsPolynomial(signal, variable); }
/// <summary> /// Checks whether a signal is a single variable polynomial, e.g. '3*x^2+4*x-1' /// </summary> /// <remarks><see cref="signal"/> is assumed to be automatic simplified.</remarks> public static bool IsPolynomial(Signal signal, Signal variable) { if(signal.IsDrivenByPortEntity("Add", "Std")) return signal.DrivenByPort.InputSignals.TrueForAll(delegate(Signal s) { return IsMonomial(s, variable); }); else return IsMonomial(signal, variable); }
/// <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(IsAlwaysRational(signal)) return true; if(signal.IsDrivenByPortEntity("Multiply", "Std") && signal.DrivenByPort.InputSignalCount == 2 && 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> /// Evaluates the degree of the single-variable polynomial <see cref="signal"/>. /// </summary> /// <returns> /// <see cref="UndefinedSymbol"/> if <see cref="signal"/> is not a single-variable polynomial. /// <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 ValueStructure PolynomialDegree(Signal signal, Signal variable) { if(signal == null) throw new ArgumentNullException("signal"); if(signal.IsDrivenByPortEntity("Add", "Std")) { IntegerValue d = IntegerValue.Zero; ReadOnlySignalSet inputs = signal.DrivenByPort.InputSignals; for(int i = 0; i < inputs.Count; i++) { ValueStructure f = MonomialDegree(inputs[i],variable); if(f is UndefinedSymbol) return f; else if(!(f is NegativeInfinitySymbol)) d = d.Max((IntegerValue)f); } return d; } else return MonomialDegree(signal, variable); }
public static ValueStructure PolynomialDegree(Signal signal, Signal[] generalizedVariables) { if(signal.IsDrivenByPortEntity("Add", "Std")) { IntegerValue d = IntegerValue.Zero; ReadOnlySignalSet inputs = signal.DrivenByPort.InputSignals; for(int i = 0; i < inputs.Count; i++) { ValueStructure f = MonomialDegree(inputs[i], generalizedVariables); if(f is UndefinedSymbol) return f; else if(!(f is NegativeInfinitySymbol)) d = d.Max((IntegerValue)f); } return d; } else return MonomialDegree(signal, generalizedVariables); }
/// <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) { ValueStructure 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(signal.Context); } if(signal.IsDrivenByPortEntity("Add", "Std")) { ReadOnlySignalSet 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 signal.Context.Builder.AddSimplified(coeffs); } return UndefinedSymbol.Constant(signal.Context); }
/// <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) { ValueStructure 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(signal.Context) }; } else if(signal.IsDrivenByPortEntity("Add", "Std")) { ReadOnlySignalSet 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] = signal.Context.Builder.AddSimplified(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]; Signal zero = IntegerValue.ConstantZero(signal.Context); for(int i = 0; i < ret.Length; i++) if(polynom.ContainsKey(i)) ret[i] = polynom[i]; else ret[i] = zero; return ret; }
public static Signal Denominator(Signal signal) { if(signal.IsDrivenByPortEntity("Divide", "Std") && signal.DrivenByPort.InputSignalCount > 1) { if(signal.DrivenByPort.InputSignals.Count == 2) return signal.DrivenByPort.InputSignals[1]; List<Signal> factors = new List<Signal>(); ReadOnlySignalSet inputs = signal.DrivenByPort.InputSignals; for(int i = 1; i < inputs.Count; i++) //all but first element factors.Add(inputs[i]); return signal.Context.Builder.MultiplySimplified(factors); } return IntegerValue.ConstantOne(signal.Context); }
/// <summary> /// Checks whether a signal is a signle 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(Numerator(signal), variable) && IsPolynomial(Denominator(signal), variable); else return IsPolynomial(signal, variable); }