// Find the best pivot in column j. private KeyValuePair <int, Real> PartialPivot(int i1, int i2, Expression j) { int row = -1; Real max = -1; for (int i = i1; i < i2; ++i) { Expression ij = equations[i][j]; if (!ij.EqualsZero()) { // If we don't a pivot yet, just grab this one. if (row == -1) { row = i; } // Select the larger pivot if this is a constant. if (ij is Constant && Real.Abs((Real)ij) > max) { row = i; max = Real.Abs((Real)ij); } } } return(new KeyValuePair <int, Real>(row, max)); }
public override bool Matches(Expression E, MatchContext Matched) { Expression matched; if (Matched.TryGetValue(Right, out matched)) { if (Left.Matches(E ^ Binary.Divide(1, matched), Matched)) { return(true); } } // x^0 = 1. if (E.EqualsOne() && Right.Matches(0, Matched)) { return(true); } // 0^x = 0. if (E.EqualsZero() && Left.Matches(0, Matched)) { return(true); } Binary PE = E as Power; if (!ReferenceEquals(PE, null) && Matched.TryMatch(() => Left.Matches(PE.Left, Matched) && Right.Matches(PE.Right, Matched))) { return(true); } // If the exponent matches 1, E can match left. if (Matched.TryMatch(() => Right.Matches(1, Matched) && Left.Matches(E, Matched))) { return(true); } if (Right.IsInteger() && Left.Matches(ComputerAlgebra.Power.New(E, Binary.Divide(1, Right)).Evaluate(), Matched)) { return(true); } return(false); }
// Find the best pivot in column j. private KeyValuePair <int, Real> PartialPivot(int i1, int i2, Expression j, IEnumerable <Arrow> PivotConditions) { int row = -1; Real max = -1; for (int i = i1; i < i2; ++i) { Expression ij = equations[i][j]; if (!ij.EqualsZero()) { // If we don't a pivot yet, just grab this one. if (row == -1) { row = i; } // Select the larger pivot if this is a constant, using the PivotConditions. Expression ijc; if (ij is Constant || PivotConditions is null) { ijc = ij; } else { ijc = ij.Evaluate(PivotConditions); } if (ijc is Constant && Real.Abs((Real)ijc) > max) { row = i; max = Real.Abs((Real)ijc); } } } return(new KeyValuePair <int, Real>(row, max)); }
public override bool Matches(Expression E, MatchContext Matched) { // if E is zero, any term can match to zero to succeed. if (E.EqualsZero()) { return(Terms.Any(i => i.Matches(0, Matched))); } // Move the constants in this pattern to E. IEnumerable <Expression> PTerms = Terms; IEnumerable <Expression> Constants = PTerms.OfType <Constant>(); if (Constants.Any()) { E = Binary.Divide(E, New(Constants)).Evaluate(); PTerms = PTerms.Except(Constants, RefComparer); } IEnumerable <Expression> ETerms = TermsOf(E); // Try starting the match at each term of the pattern. foreach (Expression p in PTerms) { // Remaining terms of the pattern. Expression P = New(PTerms.ExceptUnique(p, RefComparer)); // If p is a variable, we have to handle the possibility that more than one term of E might match this term. if (p is Variable) { // Check if p has already been matched. If it has, treat it as a constant and match the rest of the terms. Expression matched; if (Matched.TryGetValue(p, out matched)) { // p has already been matched. Remove it out of E and match the remainder of the pattern. if (P.Matches(E / matched, Matched)) { return(true); } } else { // Try matching p to the various combinations of the terms of E. for (int i = 1; i <= ETerms.Count(); ++i) { foreach (IEnumerable <Expression> e in ETerms.Combinations(i)) { if (Matched.TryMatch(() => p.Matches(New(e), Matched) && P.Matches(New(ETerms.ExceptUnique(e, RefComparer)), Matched))) { return(true); } } } // Try matching p to identity. if (Matched.TryMatch(() => p.Matches(1, Matched) && P.Matches(E, Matched))) { return(true); } } } else { // If p is not a variable, try matching it to any of the terms of E. foreach (Expression e in ETerms) { if (Matched.TryMatch(() => p.Matches(e, Matched) && P.Matches(New(ETerms.ExceptUnique(e, RefComparer)), Matched))) { return(true); } } } } return(false); }