private static Entity EvalMultiplicationOperator(Entity oa, Entity ob) { NumberEntity na = null, nb = null; VariableEntity va = null, vb = null; if ((oa.IsVariableEntity(out va) || ob.IsVariableEntity(out vb)) && (oa.IsNumberEntity(out na) || ob.IsNumberEntity(out nb))) { return(EvalMultiplicationOperator(va == null ? vb : va, na == null ? nb : na)); } var oaChildren = GetSumOrSubEntities(oa); var obChildren = GetSumOrSubEntities(ob); Entity result = null; foreach (var oaChild in oaChildren) { foreach (var obChild in obChildren) { if (result == null) { result = oaChild * obChild; } else { result = result + (oaChild * obChild); } } } return(result.Eval()); }
public void Assign(VariableEntity variable, NumberEntity number) { var children = new List <VariableEntity>(); GetVariables(variable, children); foreach (var child in children) { child.AssignNumber(number); } }
private Entity EvalNumber(NumberEntity na, NumberEntity nb) { switch (Name) { case Constants.Operators.MUL: return(na.Number * nb.Number); case Constants.Operators.SUM: return(na.Number + nb.Number); case Constants.Operators.DIV: return(na.Number / nb.Number); default: return(na.Number - nb.Number); } }
public override Entity Eval() { VariableEntity va = null, vb = null; NumberEntity na = null, nb = null; OperatorEntity oa = null, ob = null; var a = Children.ElementAt(0).Eval(); var b = Children.ElementAt(1).Eval(); Entity result = this; if ((a.IsNumberEntity(out na) && b.IsNumberEntity(out nb))) { return(EvalNumber(na, nb)); } if (a.IsVariableEntity(out va) && b.IsVariableEntity(out vb)) { return(EvalVariable(Name, va, vb)); } if (Name == Constants.Operators.MUL) { return(EvalMultiplicationOperator(a, b)); } if (Name == Constants.Operators.SUM || Name == Constants.Operators.SUB) { return(EvalSumOrSubOperator(Name, a, b)); } switch (Name) { case Constants.Operators.MUL: return(a * b); case Constants.Operators.DIV: return(a / b); } return(null); }
public bool IsNumberEntity(out NumberEntity result) { result = this as NumberEntity; return(result != null); }
public IEnumerable <Entity> Solve(VariableEntity variable) { var dic = new Dictionary <int, Entity>(); var children = GetSumOrSubEntities(this); foreach (var child in children) { var monomial = ParseMonomial(child, variable); if (dic.ContainsKey(monomial.Key)) { dic[monomial.Key] += monomial.Value; } else { dic.Add(monomial.Key, monomial.Value); } } if (dic.Count() == 1) { dic.Add(0, Number.Create(0)); } var orders = dic.OrderBy(_ => _.Key).ToList(); if (orders.Last().Value.IsNumberEntity(out NumberEntity last)) { if (last.Number.Value < 0) { for (var i = 0; i < orders.Count(); i++) { orders[i] = new KeyValuePair <int, Entity>(orders[i].Key, (Number.Create(-1) * orders[i].Value).Eval()); } } } if (orders.Count() == 2) { var expr = (Number.Create(-1) * orders.ElementAt(orders.ElementAt(0).Key).Value); if (orders.ElementAt(1).Key != 1) { expr /= orders.ElementAt(orders.ElementAt(1).Key).Value; } var value = expr.Eval(); var power = orders.ElementAt(1).Key; for (var i = 2; i <= power; i++) { // value = System.Math.Sqrt(value); } return(new[] { value }); } else if (orders.Count() == 3 && orders.ElementAt(2).Key == 2) { var a = orders.ElementAt(2).Value; var b = orders.ElementAt(1).Value; var c = orders.ElementAt(0).Value; var discriminant = b * b - Number.Create(4) * a * c; var number = discriminant.Eval() as NumberEntity; if (number != null) { if (number.Number.Value == 0) { return(new Entity[] { (Number.Create(-1) * b) / Number.Create(2) * a }); } var x1 = (Number.Create(-1) * b - MathEntity.Sqrt(number)) / Number.Create(2) * a; var x2 = (Number.Create(-1) * b + MathEntity.Sqrt(number)) / Number.Create(2) * a; return(new Entity[] { x1.Eval(), x2.Eval() }); } } else if (orders.Last().Key == 3) { // http://www2.trinity.unimelb.edu.au/~rbroekst/MathX/Cubic%20Formula.pdf var a = orders.ElementAt(3).Value; var b = orders.ElementAt(2).Value; var c = orders.ElementAt(1).Value; var d = orders.ElementAt(0).Value; var pi = Number.Create(System.Math.PI); NumberEntity kos = new NumberEntity(Number.Create(0));; NumberEntity r = new NumberEntity(Number.Create(0)); NumberEntity alpha = new NumberEntity(Number.Create(0)); var vt = ((Number.Create(-1) * b) / Number.Create(3)).Eval(); var p = ((c / a) - (b * b) / (Number.Create(3) * a * a)).Eval() as NumberEntity; var q = ((b * b * b / a / a / a / Number.Create(13.5)) + d / a - b * c / Number.Create(3) / a / a).Eval(); var del = ((q * q) / Number.Create(4) + (p * p * p) / Number.Create(27)).Eval() as NumberEntity; if (del.Number.Value <= 0) { if (p.Number.Value != 0) { kos = ((Number.Create(-1) * q) / Number.Create(2) / MathEntity.Sqrt(Number.Create(-1) * p * p * p / Number.Create(27))).Eval() as NumberEntity; r = MathEntity.Sqrt(Number.Create(-1) * p / Number.Create(3)).Eval() as NumberEntity; } if (kos.Number.Value == 1) { alpha = ((Number.Create(-1) * pi * (kos - Number.Create(1))) / Number.Create(2)).Eval() as NumberEntity; } else { alpha = MathEntity.Acos(kos).Eval() as NumberEntity; } var result = new List <Entity>(); for (int k = 0; k <= 2; k++) { var xk = (Number.Create(2) * r * MathEntity.Cos((alpha + Number.Create(2) * Number.Create(k) * pi) / Number.Create(3)) + vt).Eval() as NumberEntity; result.Add(xk); } return(result.ToArray()); } else { throw new NotImplementedException(); } } return(null); }
private static Entity EvalSumOrSubOperator(string name, Entity a, Entity b) { VariableEntity va = null, vb = null; NumberEntity na = null, nb = null; OperatorEntity oa = null, ob = null; // (x + x2) + 3 // (x + x2) + x5 if ((a.IsOperatorEntity(new string[] { Constants.Operators.SUM, Constants.Operators.SUB }, out oa) || b.IsOperatorEntity(new string[] { Constants.Operators.SUM, Constants.Operators.SUB }, out ob)) && ((a.IsVariableEntity(out va) || b.IsVariableEntity(out vb)) || ((a.IsNumberEntity(out na) || b.IsNumberEntity(out nb))))) { var children = new List <Entity>(); if (ob != null) { children.Add(a); if (name == Constants.Operators.SUB) { ob = (Number.Create(-1) * ob).Eval() as OperatorEntity; } var entities = GetSumOrSubEntities(ob); children.AddRange(GetSumOrSubEntities(ob)); } else { children.AddRange(GetSumOrSubEntities(oa)); if (name == Constants.Operators.SUB) { b = (Number.Create(-1) * b).Eval(); } children.Add(b); } var variables = children.Where(_ => _ is VariableEntity).GroupBy(_ => ((VariableEntity)_).Name + ((VariableEntity)_).Pow); var numbers = children.Where(_ => _ is NumberEntity); Entity variableEntity = null; foreach (var grp in variables) { Entity subVariableEntity = null; foreach (var variable in grp) { if (subVariableEntity == null) { subVariableEntity = variable; } else { subVariableEntity = (subVariableEntity + variable).Eval(); } } if (variableEntity == null) { variableEntity = subVariableEntity; } else { variableEntity = variableEntity + subVariableEntity; } } Entity numberEntity = Number.Create(0); foreach (var number in numbers) { numberEntity = (numberEntity + number).Eval(); } return(variableEntity + numberEntity); } // a == 0 or b == 0 bool isAEmpty = false, isBEmpty = false; if (a.IsNumberEntity(out na) && (isAEmpty = na.Number.Value == 0) || b.IsNumberEntity(out nb) && (isBEmpty = nb.Number.Value == 0)) { return(isAEmpty ? b : a); } switch (name) { case Constants.Operators.SUM: return(a + b); default: return(a - b); } }
private static Entity EvalMultiplicationOperator(VariableEntity va, NumberEntity ne) { return(va.Mul(ne)); }