Ejemplo n.º 1
0
 void StartEquationRender(object sender, EventArgs e)
 {
     string s = LatexConverter.ToLatex(EquationEntryTextBox.Text);
     //_latexConverter.QueueNewUpdate(s); //feature disabled for now
 }
        public void Calculate(Object stateInfo)
        {
            var input = (UncertCalcInput)stateInfo;
            UncertCalcResults output = new UncertCalcResults();

            string equation = input.Equation;

            //split equation into two sides
            var sides     = equation.Split('=');
            var leftSide  = sides[0] + "=";
            var rightSide = sides[1];

            var symbolAliases = ExpressionManip.GenerateEquationAliases(rightSide);

            string aliasEquation = ExpressionManip.ConvertSymbolsIntoAliases(symbolAliases, rightSide);

            string[] partialDerivs      = new string[symbolAliases.Count];
            var      dependentVariables = new char[symbolAliases.Count];

            //need to change log to log(10,x)
            //convert log to log base 10
            string wolframEquation;

            wolframEquation = aliasEquation.Replace("log", "&"); //placeholder character
            int pos;

            while ((pos = wolframEquation.IndexOf('&')) != -1)
            {
                var right = ExpressionManip.SplitEquation(wolframEquation, pos, ExpressionManip.SplitType.RightSide);
                var left  = ExpressionManip.SplitEquation(wolframEquation, pos, ExpressionManip.SplitType.LeftSide);

                wolframEquation = wolframEquation.Remove(left.StartIndex, right.EndIndex - left.StartIndex);
                wolframEquation = wolframEquation.Insert(left.StartIndex, "Log(10," + right.Segment + ")");
            }



            StatusUpdate("Beginning wolfram alpha queries");
            int si = 0;

            foreach (var reference in symbolAliases)
            {
                StatusUpdate("Sending query " + (si + 1) + " of " + symbolAliases.Count + "...");
                partialDerivs[si]      = _wolframEval.CalculatePartialDeriv(wolframEquation, reference.Value[0]);
                dependentVariables[si] = reference.Value[0];
                si++;
                StatusUpdate("Response recieved");
            }
            StatusUpdate("Finalizing calculations");

            //wolfram alpha does this mindblowingly retarded thing where it will change scientific notation from *10^n to x10^n
            for (int i = 0; i < partialDerivs.Length; i++)
            {
                for (int letter = 0; letter < partialDerivs[i].Length - 2; letter++)
                {
                    if (Char.IsDigit(partialDerivs[i][letter]) && Char.IsDigit(partialDerivs[i][letter + 2]) && partialDerivs[i][letter + 1] == 'x')
                    {
                        partialDerivs[i] = partialDerivs[i].Remove(letter + 1, 1);
                        partialDerivs[i] = partialDerivs[i].Insert(letter + 1, "*");
                    }
                }
            }

            //when wolfram alpha returns "log", it actually means "ln"
            for (int i = 0; i < partialDerivs.Length; i++)
            {
                partialDerivs[i] = partialDerivs[i].Replace("log", "ln");
            }

            for (int i = 0; i < partialDerivs.Length; i++)
            {
                partialDerivs[i] = "(∂/∂" + dependentVariables[i] + ")=" + partialDerivs[i];
                partialDerivs[i] = ExpressionManip.ConvertAliasesIntoSymbols(symbolAliases, partialDerivs[i]);
            }

            string[] librePartialDerivs = new string[symbolAliases.Count];

            for (int i = 0; i < symbolAliases.Count; i++)
            {
                if (input.UseLibreConverter)
                {
                    librePartialDerivs[i] = LibreMathConverter.EquationToLibre(partialDerivs[i]);
                }
                else
                {
                    librePartialDerivs[i] = LatexConverter.ToLatex(partialDerivs[i]);
                }
            }

            output.PartialDerivs = librePartialDerivs;

            var symbolValues = new Dictionary <string, string>();

            for (int i = 0; i < input.VariableValues.Count; i++)
            {
                symbolValues.Add(input.VariableNames[i], input.VariableValues[i]);
            }

            string[] partialSolutions;

            PlugIntoEquationAndSolve(partialDerivs, symbolValues, out output.PluggedPartialDerivs, out partialSolutions);

            for (int i = 0; i < partialDerivs.Length; i++)
            {
                if (input.UseLibreConverter)
                {
                    output.PluggedPartialDerivs[i] = LibreMathConverter.EquationToLibre(output.PluggedPartialDerivs[i]);
                }
                else
                {
                    output.PluggedPartialDerivs[i] = LatexConverter.ToLatex(output.PluggedPartialDerivs[i]);
                }
            }

            string propogationStr = "δ" + leftSide.Substring(0, leftSide.Count() - 1);

            propogationStr += "=sqrt{";

            si = 0;
            foreach (var data in input.VariableUncertainties)
            {
                propogationStr += "(" + partialSolutions[si] + "*" + data + ")^2+";
                si++;
            }
            propogationStr  = propogationStr.Substring(0, propogationStr.Count() - 1);
            propogationStr += "}";

            var dResults   = new double[partialSolutions.Count()];
            var dConstants = new double[partialSolutions.Count()];


            for (int i = 0; i < partialSolutions.Count(); i++)
            {
                dResults[i] = double.Parse(partialSolutions[i]);
            }


            for (int i = 0; i < partialSolutions.Count(); i++)
            {
                dConstants[i] = double.Parse(input.VariableUncertainties[i]);
            }

            double uncertainty = 0;

            for (int i = 0; i < partialSolutions.Count(); i++)
            {
                uncertainty += Math.Pow(dResults[i] * dConstants[i], 2);
            }
            uncertainty = Math.Sqrt(uncertainty);

            string sUncertain = uncertainty.ToString();

            if (input.UseLibreConverter)
            {
                output.PropEquation = "size 16{" + propogationStr + "=" + sUncertain + "}";
            }
            else
            {
                output.PropEquation = "${" + propogationStr + "=" + sUncertain + "}$";
                output.PropEquation = output.PropEquation.Replace("δ", @"\delta ");
                output.PropEquation = output.PropEquation.Replace("∂", @"\partial ");
                output.PropEquation = output.PropEquation.Replace("sqrt", @"\sqrt ");
            }
            output.Result = sUncertain;

            for (int i = 0; i < partialSolutions.Count(); i++)
            {
                if (input.UseLibreConverter)
                {
                    output.PartialDerivs[i]        = "size 16{" + output.PartialDerivs[i] + "}";
                    output.PluggedPartialDerivs[i] = "size 16{" + output.PluggedPartialDerivs[i] + "}";
                }
                else
                {
                    output.PartialDerivs[i]        = "{" + output.PartialDerivs[i] + "}";
                    output.PluggedPartialDerivs[i] = "{" + output.PluggedPartialDerivs[i] + "}";
                    output.PartialDerivs[i]        = output.PartialDerivs[i].Replace("δ", @"\delta ");
                    output.PluggedPartialDerivs[i] = output.PluggedPartialDerivs[i].Replace("δ", @"\delta ");
                    output.PartialDerivs[i]        = output.PartialDerivs[i].Replace("∂", @"\partial ");
                    output.PluggedPartialDerivs[i] = output.PluggedPartialDerivs[i].Replace("∂", @"\partial ");
                }
            }
            StatusUpdate("Calculation complete");
            if (_onComplete != null)
            {
                _onComplete.Invoke(output);
            }
        }