internal static Entity FindCD(Entity expr, VariableEntity x) { var terms = TreeAnalyzer.LinearChildren(expr, "sumf", "minusf", Const.FuncIfSum); var denominators = new Dictionary <string, (Entity den, RealNumber pow)>(); var fracs = new List <(Entity numerator, List <(Entity den, RealNumber pow)> denominatorMultipliers)>(); foreach (var term in terms) { var oneInfo = FindFractions(term, x); foreach (var denMp in oneInfo.denominatorMultipliers) { var(den, pow) = denMp; var name = den.ToString(); // TODO: Replace with faster hashing if (!denominators.ContainsKey(name)) { denominators[name] = (den, 0); } denominators[name] = (den, Number.Max(denominators[name].pow, -pow)); } fracs.Add(oneInfo); } if (denominators.Count == 0) { return(null); // If there's no denominators or it's equal to 1, then we don't have to try to solve yet anymore } Dictionary <string, (Entity den, RealNumber pow)> ToDict(List <(Entity den, RealNumber pow)> list) { var res = new Dictionary <string, (Entity den, RealNumber pow)>(); foreach (var el in list) { res[el.den.ToString()] = (el.den, -el.pow); } return(res); } var newTerms = new List <Entity>(); foreach (var frac in fracs) { var(num, dens) = frac; var denDict = ToDict(dens); Entity invertDenominator = 1; foreach (var mp in denominators) { if (denDict.ContainsKey(mp.Key)) { invertDenominator *= MathS.Pow(mp.Value.den, denominators[mp.Key].pow - denDict[mp.Key].pow); } else { invertDenominator *= MathS.Pow(mp.Value.den, denominators[mp.Key].pow); } } newTerms.Add(invertDenominator * num); } return(TreeAnalyzer.MultiHangBinary(newTerms, "sumf", Const.PRIOR_SUM).InnerSimplify()); }
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()); }
/// <summary> /// Performs a grid search with each iteration done by NewtonIter /// </summary> /// <param name="expr"> /// The equation with one variable to be solved /// </param> /// <param name="v"> /// The variable to solve over /// </param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="stepCount"> /// A complex number, thus, if stepCount.Im == 0, no operations will be performed at all. If you /// need to iterate over real numbers only, set it to 1, i. e. new Number(your_number, 1) /// </param> /// <param name="precision"> /// How many approximations we need to do before we reach the most precise result. /// </param> /// <returns></returns> internal static Set SolveNt(Entity expr, VariableEntity v, NewtonSetting settings) { if (MathS.Utils.GetUniqueVariables(expr).Count != 1) { throw new MathSException("Two or more or less than one variables in SolveNt is prohibited"); } MathS.Settings.FloatToRationalIterCount.Set(0); var res = new Set(); var df = expr.Derive(v).Simplify().Compile(v); var f = expr.Simplify().Compile(v); for (int x = 0; x < settings.StepCount.Re; x++) { for (int y = 0; y < settings.StepCount.Im; y++) { var xShare = ((EDecimal)x) / settings.StepCount.Re; var yShare = ((EDecimal)y) / settings.StepCount.Im; var value = Number.Create(settings.From.Re * xShare + settings.To.Re * (1 - xShare), settings.From.Im * yShare + settings.To.Im * (1 - yShare)); var root = NewtonIter(f, df, value.AsComplex(), settings.Precision); if (root.IsDefinite() && f.Call(root.AsComplex()).ToComplexNumber().Abs() < MathS.Settings.PrecisionErrorCommon.Value) { res.Add(root); } } } MathS.Settings.FloatToRationalIterCount.Unset(); return(res); }
private static Entity TryDowncast(Entity equation, VariableEntity x, Entity root) { if (!MathS.CanBeEvaluated(root)) { return(root); } var preciseValue = root.Eval(); MathS.Settings.PrecisionErrorZeroRange.Set(1e-7m); MathS.Settings.FloatToRationalIterCount.Set(20); var downcasted = Number.Functional.Downcast(preciseValue) as ComplexNumber; MathS.Settings.FloatToRationalIterCount.Unset(); MathS.Settings.PrecisionErrorZeroRange.Unset(); var errorExpr = equation.Substitute(x, downcasted); if (!MathS.CanBeEvaluated(errorExpr)) { return(root); } var error = errorExpr.Eval(); bool ComplexRational(ComplexNumber a) => a.Real.IsRational() && a.Imaginary.IsRational(); var innerSimplified = root.InnerSimplify(); return(Number.IsZero(error) && ComplexRational(downcasted) ? downcasted : innerSimplified); }
// solves equation f(sin(x), cos(x), tan(x), cot(x)) for x internal static Set SolveLinear(Entity expr, VariableEntity variable) { var replacement = Utils.FindNextIndex(expr, variable.Name); expr = ReplaceTrigonometry(expr, variable, replacement); // if there is still original variable after replacements, // equation is not in a form f(sin(x), cos(x), tan(x), cot(x)) if (expr.FindSubtree(variable) != null) { return(null); } var solutions = EquationSolver.Solve(expr, replacement); if (solutions == null) { return(null); } var actualSolutions = new Set(); // TODO: make check for infinite solutions foreach (var solution in solutions.FiniteSet()) { var sol = TreeAnalyzer.FindInvertExpression(MathS.Pow(MathS.e, MathS.i * variable), solution, variable); if (sol != null) { actualSolutions.AddRange(sol); } } return(actualSolutions); }
private static KeyValuePair <int, Entity> ParseMonomial(Entity monomialExpr, VariableEntity variable) { Func <Entity, VariableEntity> extractVariableEntity = (ent) => { if (ent.IsVariableEntity(out VariableEntity varEnt) && varEnt.Name == variable.Name) { return(varEnt); } return(null); }; if (!monomialExpr.Children.Any()) { var varEnt = extractVariableEntity(monomialExpr); if (varEnt != null) { return(new KeyValuePair <int, Entity>(varEnt.Pow, Number.Create(varEnt.NbTimes))); } return(new KeyValuePair <int, Entity>(0, monomialExpr)); } int pow = 0; Entity result = null; foreach (var child in monomialExpr.Children.SelectMany(_ => GetMulOrDivEntities(_))) { var varEnt = extractVariableEntity(child); if (varEnt != null) { pow += varEnt.Pow; if (result == null) { result = Number.Create(varEnt.NbTimes); } else { result *= Number.Create(varEnt.NbTimes); } } else { if (monomialExpr.IsOperatorEntity(new[] { Constants.Operators.MUL }, out OperatorEntity op)) { if (result == null) { result = child; } else { result *= child; } } } } return(new KeyValuePair <int, Entity>(pow, result)); }
/// <summary> /// Solves one equation /// </summary> /// <param name="equation"></param> /// <param name="x"></param> /// <returns></returns> internal static Set Solve(Entity equation, VariableEntity x) { var res = new Set(); equation = equation.DeepCopy(); MathS.Settings.PrecisionErrorZeroRange.Set(1e-12m); MathS.Settings.FloatToRationalIterCount.Set(0); /* * try * { * AnalyticalSolver.Solve(equation, x, res); * } * catch (Exception e) * { * MathS.Settings.FloatToRationalIterCount.Unset(); * MathS.Settings.PrecisionErrorZeroRange.Unset(); * throw e; * }*/ AnalyticalSolver.Solve(equation, x, res); MathS.Settings.FloatToRationalIterCount.Unset(); MathS.Settings.PrecisionErrorZeroRange.Unset(); if (res.Power == Set.PowerLevel.FINITE) { res.FiniteApply(entity => entity.InnerSimplify()); Func <Entity, Entity> simplifier = entity => entity.InnerSimplify(); Func <Entity, Entity> evaluator = entity => entity.InnerEval(); Entity collapser(Entity expr) { if (MathS.Utils.GetUniqueVariables(equation).Count == 1) { return(expr.InnerEval()); } else { return(expr.InnerSimplify()); } } var finalSet = new Set(); finalSet.FastAddingMode = true; foreach (var elem in res.FiniteSet()) { if (TreeAnalyzer.IsDefinite(elem) && TreeAnalyzer.IsDefinite(collapser(equation.Substitute(x, elem))) ) { finalSet.Add(elem); } } finalSet.FastAddingMode = false; res = finalSet; } return(res); }
public void When_Solve_Addition() { VariableEntity x1 = "x1"; var equation = Number.Create(-61) + x1 + Number.Create(60) + x1; var result = equation.Eval(); Assert.Equal("2x1 + -1", result.ToString()); }
public void When_Derive_Equation() { VariableEntity x = "x"; Entity firstEquation = Number.Create(1) * x + Number.Create(2) * Number.Create(5); var firstResult = firstEquation.Derive().Eval(); Assert.NotNull(firstResult); Assert.Equal("1", firstResult.ToString()); }
public CompiledFuncTest() { x = MathS.Var("x"); multiFuncNotCompiled = (MathS.Log(3, x) + MathS.Sqr(x)) * MathS.Sin(x + MathS.Cosec(x)); multiFunc = multiFuncNotCompiled.Compile(x); Expression <Func <Complex, Complex> > expr = x => (Complex.Log(x, 3) + Complex.Pow(x, 2)) * Complex.Sin(x + 1 / Complex.Sin(x)); linqFunc = expr.Compile(); }
public void When_Solve_Integral_With_SimpsonEstimate() { VariableEntity x = "x"; var function = MathEntity.Sqrt(x); var estimate = new SimpsonEstimate(); var estimation = estimate.Estimate(function, x, 4, 0, 8); Assert.Equal(14.855493563580854, estimation); }
public void When_Solve_Monomial() { VariableEntity x = "x"; Entity eq = Number.Create(2) * x + Number.Create(3) * x; var result = eq.Solve(x).ElementAt(0) as NumberEntity; Assert.NotNull(result); Assert.Equal(0, result.Number.Value); }
public void TestMethod1() { VariableEntity entity1 = new VariableEntity( new ItemName("ABC"), new Attribute("数値"), new InitValue("1", new Attribute("数値")), new Comment("コメントです") ); VariableEntity entity2 = new VariableEntity( new ItemName("ABC"), new Attribute("数値"), new InitValue("1", new Attribute("数値")), new Comment(null) ); VariableEntity entity3 = new VariableEntity( new ItemName("ABC"), new Attribute("文字"), new InitValue("1", new Attribute("文字")), new Comment(null) ); VariableEntity entity4 = new VariableEntity( new ItemName("ABC"), new Attribute("文字", true), new InitValue("0x1234", new Attribute("文字", true)), new Comment(null) ); List <VariableEntity> list = new List <VariableEntity>(); list.Add(entity1); list.Add(entity2); list.Add(entity3); list.Add(entity4); AreaEntity obj = new AreaEntity(list); obj.OutputValue().Is( "[変数開始]\r\n項目名=\"ABC\"" + "\r\n" + "属性=数値" + "\r\n" + "初期値=1" + "\r\n" + "コメント=\"コメントです\"" + "\r\n" + "項目名=\"ABC\"" + "\r\n" + "属性=数値" + "\r\n" + "初期値=1" + "\r\n" + "項目名=\"ABC\"" + "\r\n" + "属性=文字" + "\r\n" + "初期値=\"1\"" + "\r\n" + "項目名=\"ABC\"" + "\r\n" + "属性=文字" + "\r\n" + "初期値=0x1234" + "\r\n" + "[変数終了]"); }
public Entity GetEquation() { VariableEntity µ = _avgVariableName; VariableEntity σ = _standardDeviationVariableName; VariableEntity x = _variableName; var firstEntity = Number.Create(1) / (σ * MathEntity.Sqrt(Number.Create(2) * Number.Create(System.Math.PI))); var secondEntity = (Number.Create(-1) * MathEntity.Pow(x - µ, Number.Create(2))) / (Number.Create(2) * MathEntity.Pow(σ, Number.Create(2))); return(MathEntity.Pow(firstEntity, secondEntity)); }
public void Assign(VariableEntity variable, NumberEntity number) { var children = new List <VariableEntity>(); GetVariables(variable, children); foreach (var child in children) { child.AssignNumber(number); } }
/// <summary> /// expr must contain only VariableEntity x as a variable /// </summary> /// <param name="expr"></param> /// <param name="x"></param> /// <param name="sign"> /// ">" /// "<" /// ">=" /// "<=" /// </param> /// <returns></returns> internal static Set _Solve(Entity expr, VariableEntity x, string sign) { bool Corresponds(RealNumber val) => sign switch { ">" => val > 0, "<" => val < 0, ">=" => val >= 0, "<=" => val <= 0, _ => throw new SysException("Uknown sign") }
public void When_Solve_Complex_Equation() { VariableEntity x = "x"; var equation = (Number.Create(13) - x) * ((Number.Create(13) - x) * (Number.Create(8) - x) - Number.Create(4)) - Number.Create(12) * (Number.Create(12) * (Number.Create(8) - x) + Number.Create(4)) + Number.Create(2) * (Number.Create(12) * Number.Create(-2) - (Number.Create(13) - x) * Number.Create(2)); var result = equation.Evaluate(x); var solved = result.Solve(x); Assert.NotNull(solved); }
public static decimal CheckRoots(Entity equation, VariableEntity toSub, Entity varValue) { equation = equation.Substitute(toSub, varValue); var allVars = MathS.Utils.GetUniqueVariables(equation); foreach (var vr in allVars.FiniteSet()) { equation = equation.Substitute(vr.Name, 3 /* MUST be integer to correspond to integer coefficient of periodic roots*/); } return(Number.Abs(equation.Eval())); }
public void When_Solve_Equation_With_Variables() { VariableEntity x1 = "x1"; VariableEntity x2 = "x2"; VariableEntity x3 = "x3"; var firstEquation = x1 - x2 + Number.Create(0) * x3; var secondEquation = x1 + x2; var firstResult = firstEquation.Solve(x1); var secondResult = secondEquation.Solve(x1); Assert.Equal("x2", firstResult.ElementAt(0).ToString()); Assert.Equal("-1x2", secondResult.ElementAt(0).ToString()); }
protected void GetVariables(VariableEntity variable, ICollection <VariableEntity> result) { if (IsVariableEntity(out VariableEntity var) && var.Name == variable.Name) { result.Add(var); return; } foreach (var child in Children) { child.GetVariables(variable, result); } }
/// <summary> /// Solves an equation, useful once InSolveSystem reaches equations.Count == 1 /// </summary> /// <param name="eq"> /// The equation to solve /// </param> /// <param name="var"> /// Variable to solve for /// </param> /// <returns></returns> internal static List <List <Entity> > InSolveSystemOne(Entity eq, VariableEntity var) { var result = new List <List <Entity> >(); foreach (var sol in eq.InnerSimplify().SolveEquation(var).FiniteSet()) { result.Add(new List <Entity>() { sol }); } return(result); }
private void AddVariableToArchive(object parameter) { var nodeId = _selectedNode.NodeId.ToString(); var type = _uaClientApi.GetBuiltInTypeOfVariableNodeId(nodeId); var interval = SelectedArchiveInfo.ArchiveInterval; var tmp = new VariableEntity() { Archive = interval, Name = nodeId, DataType = type, ProjectId = IoC.AppManager.ProjectId }; _unitOfWork.Variables.Add(tmp); var variableModel = Mapper.VariableEntityToVariableModel(tmp); _messenger.Send(new SendManageArchivedValue(false, variableModel)); ArchiveVariables.Add(variableModel); try { if (interval != ArchiveInterval.None) { var registeredNode = _uaClientApi.RegisterNode(nodeId); _registeredNodesForRead.Add(new ArchiveReadVariableModel() { Interval = interval, RegisteredNodeId = registeredNode, Type = type, VariableId = tmp.Id }); } else { var item = _uaClientApi.CreateMonitoredItem($"{nodeId} [{ArchiveInterval.None}]", nodeId, 100, null, 2, MonitoringMode.Disabled); item.Notification += Notification_MonitoredItem; _uaClientApi.AddMonitoredItem(item, _subscription); } } catch (Exception e) { Utils.Trace(Utils.TraceMasks.Error, $"{e.Message}"); IoC.AppManager.ShowExceptionErrorMessage(e); } SelectedArchiveInfo.VariablesCount++; }
/// <summary> /// Realiza la adaptación de los campos del request al entity de variable /// </summary> /// <param name="variableRequest">Request de Variable</param> /// <returns>Entity de Variable</returns> public static VariableEntity ObtenerVariableEntityDesdeVariableRequest(VariableRequest variableRequest) { var variableEntity = new VariableEntity(); variableEntity.CodigoVariable = variableRequest.CodigoVariable != null ? new Guid(variableRequest.CodigoVariable) : Guid.NewGuid(); variableEntity.CodigoPlantilla = !Convert.ToBoolean(variableRequest.IndicadorGlobal) ? (variableRequest.CodigoPlantilla != null ? new Guid(variableRequest.CodigoPlantilla) : Guid.Empty) : (Guid?)null; variableEntity.Identificador = variableRequest.Identificador; variableEntity.Nombre = variableRequest.Nombre; variableEntity.CodigoTipo = variableRequest.CodigoTipo; variableEntity.IndicadorGlobal = Convert.ToBoolean(variableRequest.IndicadorGlobal); variableEntity.IndicadorVariableSistema = Convert.ToBoolean(variableRequest.IndicadorVariableSistema); variableEntity.Descripcion = variableRequest.Descripcion; return(variableEntity); }
public double ComputeLowerCumulative(double tStat, double degreeOfFreedom) { VariableEntity x = _variableName; VariableEntity v = _degreeOfFreedomName; var betaFunction = new BetaFunction(); var betaResult = betaFunction.Evaluate(0.5, degreeOfFreedom / 2); var firstEntity = MathEntity.Pow(Number.Create(1) + (MathEntity.Pow(x, Number.Create(2)) / v), Number.Create(-1) * ((v + Number.Create(1)) / Number.Create(2))); var secondEntity = MathEntity.Sqrt(v) * Number.Create(betaResult); var result = (firstEntity / secondEntity); result.Assign(v, (NumberEntity)Number.Create(degreeOfFreedom)); var simpsonEstimate = new SimpsonEstimate(); return(simpsonEstimate.Estimate(result, x, _n, _a, tStat)); }
public void When_Solve_Second_Degree_Equation() { VariableEntity x = "x"; Entity eq = x * x - Number.Create(34) * x + Number.Create(225); eq = eq.Evaluate(x); var result = eq.Solve(x); var firstNumber = result.ElementAt(0) as NumberEntity; var secondNumber = result.ElementAt(1) as NumberEntity; Assert.NotNull(firstNumber); Assert.NotNull(secondNumber); Assert.Equal(9, firstNumber.Number.Value); Assert.Equal(25, secondNumber.Number.Value); }
/// <summary> /// Solves one equation /// </summary> /// <param name="equation"></param> /// <param name="x"></param> /// <returns></returns> internal static Set Solve(Entity equation, VariableEntity x) { var res = new Set(); equation = equation.DeepCopy(); MathS.Settings.PrecisionErrorZeroRange.Set(1e-12m); MathS.Settings.FloatToRationalIterCount.Set(0); AnalyticalSolver.Solve(equation, x, res); MathS.Settings.FloatToRationalIterCount.Unset(); MathS.Settings.PrecisionErrorZeroRange.Unset(); res.FiniteApply(entity => entity.InnerSimplify()); return(res); }
public void 文字16進数() { VariableEntity entity = new VariableEntity( new ItemName("ABC"), new Attribute("文字", true), new InitValue("0x1234", new Attribute("文字", true)), new Comment(null) ); entity.OutputValue().Is( "項目名=\"ABC\"" + "\r\n" + "属性=文字" + "\r\n" + "初期値=0x1234" + "\r\n" ); }
public void 文字() { VariableEntity entity = new VariableEntity( new ItemName("ABC"), new Attribute("文字"), new InitValue("1", new Attribute("文字")), new Comment(null) ); entity.OutputValue().Is( "項目名=\"ABC\"" + "\r\n" + "属性=文字" + "\r\n" + "初期値=\"1\"" + "\r\n" ); }
private static Entity EvalVariable(string name, VariableEntity va, VariableEntity vb) { switch (name) { case Constants.Operators.MUL: return(va.Mul(vb)); case Constants.Operators.SUM: return(va.Sum(vb)); case Constants.Operators.DIV: return(va.Div(vb)); default: return(va.Sub(vb)); } }
public double ComputeLowerCumulative(double average, double standardDeviation, double value) { VariableEntity µ = _avgVariableName; VariableEntity σ = _standardDeviationVariableName; VariableEntity x = _variableName; var exponent = Number.Create(-0.5) * MathEntity.Pow((x - µ) / σ, Number.Create(2)); var integralEquation = MathEntity.Pow(Number.Create(System.Math.E), exponent); integralEquation.Assign(µ, new NumberEntity(Number.Create(average))); integralEquation.Assign(σ, new NumberEntity(Number.Create(standardDeviation))); var estimate = new SimpsonEstimate(); var estimation = estimate.Estimate(integralEquation, x, _n, _a, value); var equation = (Number.Create(1) / (σ * MathEntity.Sqrt(Number.Create(2) * Number.Create(System.Math.PI)))) * Number.Create(estimation); equation.Assign(σ, new NumberEntity(Number.Create(standardDeviation))); return((equation.Eval() as NumberEntity).Number.Value); }