// // Wątek odpowiadający za działanie algorytmu // void worker_DoWork(object sender, DoWorkEventArgs e) { // Główna pętla wątku - wykonuje się tyle razy ile iteracji wprowadził użytkownik for (int k = 0; k < algorithm.iterations; k++) { // Zmienna definiująca postęp w postaci procentowej int progressPercentage = Convert.ToInt32(((double)k / algorithm.iterations) * 100); // Sortowanie według najlepszych rozwiązań if (minmax == 0) { population.subjects = population.subjects.OrderBy(o => o.solution).ToList(); } else { population.subjects = population.subjects.OrderByDescending(o => o.solution).ToList(); } // Uruchomienie algorytmu population = algorithm.RunAlgorithm(population); org.mariuszgromada.math.mxparser.Expression equa = new org.mariuszgromada.math.mxparser.Expression(); // Tworzenie wyrażeń oraz obliczanie rozwiązań aktualnej populacji foreach (var sub in population.subjects) { equa = new org.mariuszgromada.math.mxparser.Expression("f(" + string.Join(", ", sub.stringValues) + ")", f); sub.solution = equa.calculate(); } // Reportowanie postępu do aktualizacja progressbara (sender as BackgroundWorker).ReportProgress(progressPercentage, population.subjects[0]); } // Po wykonaniu algorytmu zapisujemy najlepszy obiekt w wyniku wątku e.Result = population.subjects[0]; }
public static List <TaylorSeries> CalculateTaylorSeries(List <String> TaylorFormula, double lnrealvalue, int x) { var TaylorValueList = new List <TaylorSeries>(); double LNRealValue = lnrealvalue; Parallel.ForEach(TaylorFormula, i => { // mxparser needs to be isntalled additionally in nuget: mxparser from http://mathparser.org string form = i.ToString(); double calcvalue; form.Replace('x', Convert.ToChar(x)); mXparser parsi = new mXparser(); Expression expr = new Expression(form); calcvalue = expr.calculate(); int itera = i.Count(x => x == '/'); double diffrealvalue = lnrealvalue - calcvalue; double absdiffrealval = Math.Abs(diffrealvalue); double lnitera = Math.Log(itera); double lniteradiff = Math.Log(diffrealvalue); TaylorSeries ts = new TaylorSeries(itera, calcvalue, diffrealvalue, absdiffrealval, lnitera, lniteradiff); TaylorValueList.Add(ts); } ); return(TaylorValueList); }
private async void HandleIntegralSolvingClick(object sender, RoutedEventArgs e) { if (_ctx.IntegralStrategy == null) { return; } Spinner.Visibility = Visibility.Visible; var vars = FormulaVariablesStack.Children.OfType <TextBox>().Select(t => t.Text).ToList(); var func = new Math.Expression(_ctx.Formula.Representation); for (var i = 0; i < vars.Count; i++) { func.addConstants(new Math.Constant($"{_ctx.Formula.VariableNames[i]} = {Convert.ToDouble(vars[i]).ToString(CultureInfo.InvariantCulture)}")); } var from = Convert.ToInt32(_ctx.From); var to = Convert.ToInt32(_ctx.To); if (to <= from) { MessageBox.Show("From number must be lower then to number!"); } else { await CalculateIntegral(from, to, func); } Spinner.Visibility = Visibility.Hidden; }
private async Task CalculateIntegral(double from, double to, Math.Expression func) { var result = await _ctx.IntegralStrategy.Calculate(from, to, Convert.ToInt32(_ctx.SubdivisionsCount), func); await RefreshPlot(func, from, to); ResultLabel.Content = result.ToString(CultureInfo.InvariantCulture); }
public static double solveString(string anMxParserString) { org.mariuszgromada.math.mxparser.Expression expr = new org.mariuszgromada.math.mxparser.Expression(anMxParserString); double result = expr.calculate(); if (double.IsNaN(result)) { //throw new Exception(expr.getErrorMessage()); throw new Exception("Couldn't calculate: {\n"+anMxParserString+"\n}, mxparser error: \n---\n"+expr.getErrorMessage()+"---\n" ); } return result; }
private void FtoC_click(object sender, RoutedEventArgs e) { if (MathExp.Any()) { Expression fTOc = new Expression($"(({MathExp}) - 32) * 5/9"); var ans = fTOc.calculate().ToString(); DisplayResult(ans); ClearAll(); } }
private void CtoF_click(object sender, RoutedEventArgs e) { if (MathExp.Any()) { Expression cToF = new Expression($"(({MathExp}) * 9/5) + 32"); var ans = cToF.calculate().ToString(); DisplayResult(ans); ClearAll(); } }
private Function ParseFunction(string function) { double Func(double x) { var arg = new Argument("x", x); var e = new Expression(function, arg); return(e.calculate()); } return(new Function(Func, function)); }
public static double solveString(string anMxParserString) { org.mariuszgromada.math.mxparser.Expression expr = new org.mariuszgromada.math.mxparser.Expression(anMxParserString); double result = expr.calculate(); if (double.IsNaN(result)) { //throw new Exception(expr.getErrorMessage()); throw new Exception("Couldn't calculate: {\n" + anMxParserString + "\n}, mxparser error: \n---\n" + expr.getErrorMessage() + "---\n"); } return(result); }
private void Sqrt_Click(object sender, RoutedEventArgs e) { if (MathExp.Any()) { Expression sqrtMath = new Expression($"sqrt(({MathExp}))"); var ans = sqrtMath.calculate().ToString(); DisplayResult(ans); ClearAll(); } else { DisplayResult("Need a number at first!"); } }
private async Task RefreshPlot(Math.Expression func, double from, double to) { _ctx.Points.Clear(); await Task.Run(() => { for (var i = from; i <= to; i++) { func.addArguments(new Math.Argument($"x = {i}")); _ctx.Points.Add(new DataPoint(i, func.calculate())); func.removeAllArguments(); } }); FuncPlot.InvalidatePlot(); }
// // Funkcja wywoływana po wykonaniu wątku algorytmu // void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Działania na progressbar pbProgress.Value = 100; txtProgress.Text = "100%"; // Zapisanie najlepszego rozwiązania do nowej zmiennej var sol = (Subject)e.Result; // Sortowanie według najlepszych rozwiązań if (minmax == 0) { population.subjects = population.subjects.OrderBy(o => o.solution).ToList(); allSolutions = allSolutions.OrderBy(o => o.solution).ToList(); } else { population.subjects = population.subjects.OrderByDescending(o => o.solution).ToList(); allSolutions = allSolutions.OrderByDescending(o => o.solution).ToList(); } // Rysowanie najlepszego rozwiązania plotPoint(allSolutions[0]); // Wypisanie najlepszego znalezionego rozwiązania tmpSolution.Text = "Znalezione rozwiązania przy końcowej populacji wielkości " + population.populationSize + ":\n"; tmpSolution.Text += "#######################################\n"; tmpSolution.Text += "(" + commaSeparatedArguments + ") = " + "(" + string.Join(", ", allSolutions[0].stringValues) + ")" + "\n"; tmpSolution.Text += "Rozwiązanie: " + allSolutions[0].solution + "\n"; tmpSolution.Text += "#######################################\n"; // Czyszczenie przed kolejnym wywołaniem argumentsString.Clear(); argumentsString = new List <string>(); eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); population.subjects.Clear(); // Aktywowanie ponownie przycisków btnEquation.IsEnabled = true; plotRefresh.IsEnabled = true; plotOnlyBest.IsEnabled = true; plotSurfaceBtn.IsEnabled = true; // MessageBox informujący o ukończeniu działania algorytmu MessageBox.Show("Obliczono rozwiązania", "Ukończono", MessageBoxButton.OK, MessageBoxImage.Information); }
private void Result_click(object sender, RoutedEventArgs e) { if (InsultUsers() == false) { Expression regularMath = new Expression(MathExp); var ans = regularMath.calculate().ToString(); DisplayResult(ans); ClearAll(); InputString.Append(ans); } else { var warningMsg = "Do you know how to use a calculator?"; DisplayResult(warningMsg); } }
private void EqualsButton_Click(object sender, RoutedEventArgs e) { if (CurrentSumDisplay.Content != null) // Equals button only does something if there's already an active sum { if (IODisplay.Text != "") // where there is new input { // clean up input then add input to current sum display CleanUpInput(); CurrentSumDisplay.Content += IODisplay.Text; // parse current sum display, calculate result, then output to IODisplay MathParser.Expression expression = new MathParser.Expression(CurrentSumDisplay.Content.ToString()); double result = expression.calculate(); IODisplay.Text = result.ToString(); } } }
public static double declaraFuncao(string func, double x) { string num_str = doubleToStr(x); //Escrevendo argumento string x1_str = $"x1 = {num_str}"; Argument x1 = new Argument(x1_str); // Até o momento usaremos sempre a mesma função //Function f = new Function("f(x) = 0.65 - (0.75 / (1 + x^2)) - 0.65 * x * atan(1/x)"); Function f = new Function($"f(x)= {func}"); org.mariuszgromada.math.mxparser.Expression e = new org.mariuszgromada.math.mxparser.Expression("f(x1)", f, x1); double res = e.calculate(); return(res); }
public async Task <double> Calculate(double from, double to, int n, Math.Expression func) { var area = 0.0; var dx = (to - from) / n; await Task.Run(() => { area += func.CalculateWith(from) / 2; area += func.CalculateWith(to) / 2; for (var i = 1; i < n; i++) { area += func.CalculateWith(from + dx *i); } }); return(dx * area); }
// // Zmiana wpisanego równania // private void TxtEquation_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) { // Inicjowanie zmiennych arguments = new ObservableCollection <Arguments>(); equationString = txtEquation.Text; // Tymczasowe równanie - jest nadpisywane w różnych miejscach kodu eq = new org.mariuszgromada.math.mxparser.Expression(equationString); // Odczytywanie argumentów wpisanego równania List <Token> tokensList = eq.getCopyOfInitialTokens(); tmpSolution.Text = ""; arguments.Clear(); foreach (Token t in tokensList) { if (t.tokenTypeId == Token.NOT_MATCHED) { if (!argumentsString.Contains(t.tokenStr)) { argumentsString.Add(t.tokenStr); arguments.Add(new Arguments { Argument = t.tokenStr, Minimum = -5, Maximum = 5 }); } } } // Ustawienia listy argumentów variablesGrid.AutoGenerateColumns = true; variablesGrid.ItemsSource = null; variablesGrid.ItemsSource = arguments; variablesGrid.Items.Refresh(); // Czyszczenie po wykonaniu funkcji argumentsString.Clear(); tokensList.Clear(); }
private void Button_Click2(object sender, RoutedEventArgs e) { labelResult.Content = ""; a = Convert.ToInt32(textBoxA.Text); b = Convert.ToInt32(textBoxB.Text); n = Convert.ToInt32(textBoxN.Text); Argument nInt = new Argument("n", n); IntExpression = new Expression("int(" + textBox3.Text + ", x, -3.14, 3.14)"); intAexpresstion = new Expression("int((" + textBox3.Text + ")*(cos(n*x)), x, -3.14, 3.14)", nInt); intBexpresstion = new Expression("int((" + textBox3.Text + ")*(sin(n*x)), x, -3.14, 3.14)", nInt); res.Clear(); FourierSeries fourier = Fourier(n); for (double x = a; x < b; x += 0.1) { double fx = 0; fx += fourier.a0 / 2; for (int i = 0; i < fourier.a.Count; i++) { fx += (fourier.a[i] * Math.Cos((i + 1) * x)) + (fourier.b[i] * Math.Sin((i + 1) * x)); } res.Add(new Point(x, fx)); } CreateBigGraph("Ряд Фурье"); }
private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.NumPad0 || (IsKeyboardShift && e.Key == Key.D0)) { calc("0"); } else if (e.Key == Key.NumPad1 || (IsKeyboardShift && e.Key == Key.D1)) { calc("1"); } else if (e.Key == Key.NumPad2 || (IsKeyboardShift && e.Key == Key.D2)) { calc("2"); } else if (e.Key == Key.NumPad3 || (IsKeyboardShift && e.Key == Key.D3)) { calc("3"); } else if (e.Key == Key.NumPad4 || (IsKeyboardShift && e.Key == Key.D4)) { calc("4"); } else if (e.Key == Key.NumPad5 || (IsKeyboardShift && e.Key == Key.D5)) { calc("5"); } else if (e.Key == Key.NumPad6 || (IsKeyboardShift && e.Key == Key.D6)) { calc("6"); } else if (e.Key == Key.NumPad7 || (IsKeyboardShift && e.Key == Key.D7)) { calc("7"); } else if (e.Key == Key.NumPad8 || (IsKeyboardShift && e.Key == Key.D8)) { calc("8"); } else if (e.Key == Key.NumPad9 || (IsKeyboardShift && e.Key == Key.D9)) { calc("9"); } else if (e.Key == Key.D5) { calc("("); } else if (e.Key == Key.Oem4) { calc(")"); } else if (e.Key == Key.OemPlus || e.Key == Key.Add) { calc("+"); } else if (e.Key == Key.OemMinus || e.Key == Key.Subtract) { calc("-"); } else if (e.Key == Key.Multiply || e.Key == Key.Oem5) { calc("*"); } else if (e.Key == Key.Divide || (IsKeyboardShift && e.Key == Key.Oem2)) { calc("/"); } else if (e.Key == Key.OemComma || (IsKeyboardShift && e.Key == Key.OemPeriod) || e.Key == Key.Decimal) { calc(","); } else if (e.Key == Key.S) { org.mariuszgromada.math.mxparser.Expression expression = new org.mariuszgromada.math.mxparser.Expression("sin(90)"); double result = expression.calculate(); } else if (e.Key == Key.Enter) { calc("="); } else if (IsKeyboardShift && e.Key == Key.Oem3) { calc("#"); } else if (e.Key == Key.Oem8) { calc("!"); } }
// // Główna funkcja programu - po naciśnięciu zatwierdź - Taki main // private void btnEquation_Click(object sender, RoutedEventArgs e) { // Czyścimy listę wszystkich rozwiązań allSolutions.Clear(); // Sprawdzamy czy populacja jest większa niż 5 - dla mniejszych program nie działa poprawnie if (System.Int32.Parse(txtPopulationSize.Text) <= 5) { MessageBox.Show("Populacja powinna być większa niż 5!", "Błąd!", MessageBoxButton.OK, MessageBoxImage.Warning); return; } if (miFact.IsEnabled) { if (System.Int32.Parse(miFact.Text) > System.Int32.Parse(txtPopulationSize.Text)) { MessageBox.Show("Współczynnik μ nie może być większy od populacji!", "Błąd!", MessageBoxButton.OK, MessageBoxImage.Warning); return; } } // Inicjalizacja zmiennych algorithm = new Algorithm(); commaSeparatedArguments = ""; population = new Population(); // Równanie w postaci łańcucha znaków equationString = txtEquation.Text; // Tymczasowe równanie - jest nadpisywane w różnych miejscach kodu eq = new org.mariuszgromada.math.mxparser.Expression(equationString); // Odczytywanie argumentów wpisanego równania List <Token> tokensList = eq.getCopyOfInitialTokens(); tmpSolution.Text = ""; foreach (Token t in tokensList) { if (t.tokenTypeId == Token.NOT_MATCHED) { if (!argumentsString.Contains(t.tokenStr)) { argumentsString.Add(t.tokenStr); } } } // Łapanie błędów if (argumentsString.ToArray().Length < 1) { tmpSolution.Text = "Błędne równanie - brak argumentów"; argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } if (!eq.checkLexSyntax()) { tmpSolution.Text = "Błąd składni - używaj składni środowiska MATLAB/WOLFRAM"; argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } foreach (var arg in argumentsString) { if (arg.Length < 2 || !arg.Contains("x")) { tmpSolution.Text = "Wprowadzaj tylko argumenty postaci x1,x2,x3..."; argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } } // Oddzielanie argumentów przecinkami oraz utworzenie funkcji commaSeparatedArguments = string.Join(", ", argumentsString); f = new Function("f(" + commaSeparatedArguments + ") = " + equationString); // Tworzenie populacji i jej inicjalizacja / inicjalizacja algorytmu algorithm.AlgorithmInit(comboReproductionMethod.SelectedIndex, System.Int32.Parse(txtIterations.Text), comboStrategy.SelectedIndex, minmax); if (comboStrategy.SelectedIndex == 1) { algorithm.miFactor = System.Int32.Parse(miFact.Text); } population.initPopulation(arguments, System.Convert.ToInt32(txtPopulationSize.Text)); // Progressbar algorytmu przyjmuje początkową wartość 0 pbProgress.Value = 0; // Na czas wykonywania algorytmu wyłączamy wszystkie przyciski btnEquation.IsEnabled = false; plotRefresh.IsEnabled = false; plotOnlyBest.IsEnabled = false; plotSurfaceBtn.IsEnabled = false; minmax = comboFind.SelectedIndex; // Tworzymy nowy wątek do wykonania obliczeń algorytmu BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += worker_DoWork; worker.ProgressChanged += worker_ProgressChanged; worker.RunWorkerCompleted += worker_RunWorkerCompleted; worker.RunWorkerAsync(10000); }
/** * Removes related expression. * * @param expression the related expression. */ internal void removeRelatedExpression(Expression expression) { if (expression != null) relatedExpressionsList.Remove(expression); }
private void genButton_Click(object sender, EventArgs e) { Random num1Gen = new Random(); Random num2Gen = new Random(); int num1Min; int num1Max; Random randOperator = new Random(); if (string.IsNullOrWhiteSpace(firstNum1.Text)) //Ngecek jika kolom yang akan digunakan kosong atau hanya berupa spasi. { num1Min = 1; } else { num1Min = int.Parse(firstNum1.Text); } if (string.IsNullOrWhiteSpace(firstNum2.Text))//Ngecek jika kolom yang akan digunakan kosong atau hanya berupa spasi. { num1Max = 100; } else { num1Max = int.Parse(firstNum2.Text) + 1; } if (reverseCheck(num1Min, num1Max)) //Ngecek jika angka minimum ama maximum ketuker atau enggak. { //Problem Generator int retryCount = 0; //Ngitung berapa kali ngeGenerate ulang bool decimals = true; var stopWatch = System.Diagnostics.Stopwatch.StartNew(); //Ngeinitialize sekaligus mulai ngitung waktu sampai fungsi Stopwatch dihentikan. while (decimals == true) //Ngecek jika Decimal bernilai True atau engga. Jika benar, jalankan kode ini secara berulang-ulang sampai Decimal bernilai selain True. { Random questionTypeGen = new Random(); Double result; string questionRandResult = questionGenerator(Convert.ToInt32(iterationValue.Text) - 1, num1Min, num1Max); //Manggil Method questionGenerator sambil masukin iterationValue ama range angka random. string questionString = questionRandResult.Replace("*", " X "); //Ngeganti string yang bisa dibaca komputer ke tulisan yang bisa dibaca manusia. questionString = questionString.Replace("+", " + "); //Ngeganti string yang bisa dibaca komputer ke tulisan yang bisa dibaca manusia. questionString = questionString.Replace("-", " - "); //Ngeganti string yang bisa dibaca komputer ke tulisan yang bisa dibaca manusia. questionString = questionString.Replace("/", " : "); //Ngeganti string yang bisa dibaca komputer ke tulisan yang bisa dibaca manusia. Expression ex = new Expression(questionRandResult); result = ex.calculate(); //Ngekalkulasi questionRandResult dengan MathFunction.MathParser.Calculate. if (Math.Abs(result % 1) < Double.Epsilon) //Ngecek jika result merupakan angka dengan desimal { stopWatch.Stop(); //hentikan menghitung waktu kalkulasi var elapsedTime = stopWatch.ElapsedMilliseconds; //memasukan waktu kalkulasi ke variabel. Debug.WriteLine("the number " + result.ToString() + " is not decimal"); decimals = false; logAdd("Succeeded generating a random problem in " + elapsedTime + " millisecond, with each value between " + firstNum1.Text + " to " + firstNum2.Text + ", with an iteration number of " + iterationValue.Text + ", regenerated " + retryCount + " times in attempt to search for the non-decimal result."); questionProblem.Text = questionString; resultNum.Text = result.ToString(); } else { if (noDecimalCheckbox.Checked == false) { stopWatch.Stop(); //hentikan menghitung waktu kalkulasi var elapsedTime = stopWatch.ElapsedMilliseconds; //memasukan waktu kalkulasi ke variabel. logAdd("Succeeded generating a random problem in " + elapsedTime + " millisecond, with each value between " + firstNum1.Text + " to " + firstNum2.Text + ", with an iteration number of " + iterationValue.Text + ", regenerated " + retryCount + " times in attempt to search for the non-decimal result."); Debug.WriteLine("the number " + result.ToString() + " is decimal"); decimals = false; double resultNew = Math.Round(result, Convert.ToInt32(decimalNumbers.Text), MidpointRounding.AwayFromZero); //Jika noDecimalCheckbox tidak dicentang, maka hasil penghitungan tidak dicek dan langsung ditampilkan. questionProblem.Text = questionString; resultNum.Text = resultNew.ToString(); } else { Debug.WriteLine("the number " + result.ToString() + " is decimal"); decimals = true; //mengulang kalkulasi sambil menambahkan retryCount dengan 1 retryCount++; } } } } else { MessageBox.Show("The minimum value should not exceed the maximum value. Please recheck your input.", "Error", MessageBoxButtons.OK); //Jika } }
// // Funkcja wywoływana przez wątek do rysowania wykresów - tutaj plotujemy model // void worker_DoWork2(object sender, DoWorkEventArgs e) { plotBusy = true; // wątek rysowania jest zajęty // Tymczasowe równanie - jest nadpisywane w różnych miejscach kodu eq = new org.mariuszgromada.math.mxparser.Expression(equationString); // Lista tokenów (argumentów) dodawana do listy łańcuchów znaków argumentów List <Token> tokensList = eq.getCopyOfInitialTokens(); foreach (Token t in tokensList) { if (t.tokenTypeId == Token.NOT_MATCHED) { if (!argumentsString.Contains(t.tokenStr)) { argumentsString.Add(t.tokenStr); } } } // Rozdzielenie argumentów przecinkami commaSeparatedArguments = string.Join(", ", argumentsString); // Utworzenie funkcji na podstawie argumentów i równania f = new Function("f(" + commaSeparatedArguments + ") = " + equationString); // Wyłapywanie błędów równania if (argumentsString.ToArray().Length < 1) { argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } if (!eq.checkLexSyntax()) { argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } if (eq.checkSyntax()) { argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } foreach (var arg in argumentsString) { if (arg.Length < 2 || !arg.Contains("x")) { argumentsString.Clear(); argumentsString = new List <string>(); equationString = ""; eq = new org.mariuszgromada.math.mxparser.Expression(); System.GC.Collect(); // <- Garbage Collector algorithm.ClearAlgorithm(); return; } } // Jeśli liczba argumentów > 1 to rysujemy warstwice if (arguments.ToArray().Length > 1) { model.Title = "Warstwice: "; // tytuł modelu to warstwice List <double[]> xy = new List <double[]>(); // lista tablic zmiennych double przechowująca minimum i maximum konkretnych argumentów // Zapisywanie tych zmiennych jest potrzebne do określenia granic wykresów foreach (var arg in arguments) { xy.Add(ArrayBuilder.CreateVector(arg.Minimum, arg.Maximum, p)); } // Pomocnicza tablica łańcuchów znaków argumentów funkcji (trochę czarów się tutaj dzieje) // Finalnie infunc powinien zawierać łańcuchy znaków postaci: // Przykład dla 2 argumentów: 0.125, 1.216 // Przykład dla 3 argumentów: 0.125, 1.216, 0 // Przykład dla 4 argumentów: 0.125, 1.216, 0, 0 // Zera na końcu są wstawiane dlatego, że spłaszczamy wielowymiarowy wykres do postaci warstwic var infunc = new string[p, p]; for (int i = 0; i < p; ++i) { for (int j = 0; j < p; ++j) { for (int k = 0; k < xy.ToArray().Length; ++k) { // Jeśli jest to pierwszy argument to dodajemy go po prostu do łańcucha znaków if (k == 0) { infunc[i, j] += xy[k][i].ToString().Replace(',', '.'); } // Jeżeli jest to drugi argument to dodajemy go do łańcucha znaków z przecinkiem przed wartością if (k == 1) { infunc[i, j] += "," + xy[k][j].ToString().Replace(',', '.'); } // Jeżeli jest to każdy kolejny argument to dodajemy 0 do łańcucha znaków z przecinkiem przed if (k > 1) { infunc[i, j] += ", 0"; } } } } // Tablica zawierająca wyrażenia do obliczenia - korzysta z poprzedniej tablicy pomocniczej do określenia tych wyrażeń var data = new double[p, p]; for (int i = 0; i < p; ++i) { for (int j = 0; j < p; ++j) { int progressPercentage = Convert.ToInt32(((double)i / p) * 100); org.mariuszgromada.math.mxparser.Expression equa = new org.mariuszgromada.math.mxparser.Expression("f(" + infunc[i, j] + ")", f); data[i, j] = equa.calculate(); (sender as BackgroundWorker).ReportProgress(progressPercentage); } } buffer = new PositionsBuffer(); sigma = data; // Tworzenie zmiennej kontur - wykorzystywana do rysowania warstwic var cs = new ContourSeries { Color = OxyColors.Red, LabelBackground = OxyColors.White, ColumnCoordinates = xy[0], RowCoordinates = xy[1], Data = data }; // Dodanie kontur do modelu model.Series.Add(cs); } // Jeśli liczba argumentów = 1 to rysujemy wykres else { p = p * 30; // zmieniamy dokładność na 30-krotnie większą od ustalonej ze względu na mniejszą złożoność obliczeniową model.Title = "Wykres: "; // tytuł modelu to wykres LineSeries series1 = new LineSeries(); // zmienna lineseries używana do rysowania wykresów List <double[]> xy = new List <double[]>(); // lista tablic tak jak w poprzednim przypadku - tutaj przechowuje tylko jeden argument, ale zachowanie konwencji ułatwiło dalsze zadania foreach (var arg in arguments) { xy.Add(ArrayBuilder.CreateVector(arg.Minimum, arg.Maximum, p)); } // Tak samo jak powyżej var infunc = new string[p]; for (int i = 0; i < p; ++i) { infunc[i] = xy[0][i].ToString().Replace(',', '.'); } // Tak samo jak powyżej var data = new double[p]; for (int i = 0; i < p; ++i) { int progressPercentage = Convert.ToInt32(((double)i / p) * 100); org.mariuszgromada.math.mxparser.Expression equa = new org.mariuszgromada.math.mxparser.Expression("f(" + infunc[i] + ")", f); data[i] = equa.calculate(); (sender as BackgroundWorker).ReportProgress(progressPercentage); } // Lista wygenerowanych punktów dodawana do zmiennej typu lineseries w celu wygenerowania wykresu List <DataPoint> pnts = new List <DataPoint>(); for (int i = 0; i < p; ++i) { series1.Points.Add(new DataPoint(xy[0][i], data[i])); } // Kolor wykresu ustalamy na czerwony - tak żeby wykresy i warstwice były tego samego koloru series1.Color = OxyColors.Red; model.Series.Add(series1); p = p / 30; // przywracamy domyślną wartość zmiennej odpowiadającej za dokładność wykresu } // Czyścimy listę argumentów w postaci łańcuchów znaków argumentsString.Clear(); // Czyścimy wyrażenie eq = new org.mariuszgromada.math.mxparser.Expression(); // Zapisujemy utworzony model w wyniku wątku rysowania e.Result = model; }
/** * Private constructor used for function cloning. * * @param function the function, which is going * to be cloned. */ private Function(Function function) : base(Function.TYPE_ID) { functionName = function.functionName; description = function.description; parametersNumber = function.parametersNumber; functionExpression = function.functionExpression.clone(); }
/** * Constructor - creates function from function name, * function expression string and argument names. * * @param functionName the function name * @param functionExpressionString the function expression string * @param argumentsNames the arguments names (variadic parameters) * comma separated list * * @see Expression */ public Function(String functionName ,String functionExpressionString ,params String[] argumentsNames) : base(Function.TYPE_ID) { if (mXparser.regexMatch(functionName, ParserSymbol.nameOnlyTokenRegExp)) { this.functionName = functionName; functionExpression = new Expression(functionExpressionString); functionExpression.setDescription(functionName); foreach (String argName in argumentsNames) functionExpression.addArguments(new Argument(argName)); parametersNumber = argumentsNames.Length - countRecursiveArguments(); description = ""; addFunctions(this); } else { parametersNumber = 0; description = ""; functionExpression = new Expression(""); functionExpression.setSyntaxStatus(SYNTAX_ERROR_OR_STATUS_UNKNOWN, "[" + functionName + "]" + "Invalid function name, pattern not matches: " + ParserSymbol.nameTokenRegExp); } }
/** * Removes related expression. * * @param expression the related expression */ internal void removeRelatedExpression(Expression expression) { functionExpression.removeRelatedExpression(expression); }
public static double[] GetInputData(double frequency, uint length, double samplingRate, Argument timeArg, Argument frequencyArg, org.mariuszgromada.math.mxparser.Expression expression) { return(DSP.Generate.ToneSampling2((t, freq) => { timeArg.setArgumentValue(t); frequencyArg.setArgumentValue(freq); var w = expression.calculate(); if (double.IsNaN(w) || double.IsInfinity(w)) { throw new CalculateException("During calculate value 'NaN' or 'Infinite' occurs"); } return w; }, frequency, samplingRate, length)); }
public static void GetExpressionFromString(string FunctionToFFT, out Argument pierwszy, out Argument drugi, out org.mariuszgromada.math.mxparser.Expression f) { pierwszy = new("t", 1); drugi = new("f", 2); f = new(FunctionToFFT, pierwszy, drugi); }
/** * Calculates function f(x0) (given as expression) assigning Argument x = x0; * * * @param f the expression * @param x the argument * @param x0 the argument value * * @return f.calculate() * * @see Expression */ public static double getFunctionValue(Expression f, Argument x, double x0) { x.setArgumentValue(x0); return f.calculate(); }
/** * Expression cloning. */ internal Expression clone() { Expression newExp = new Expression(this); if ( (initialTokens != null) && (initialTokens.Count > 0) ) newExp.initialTokens = createInitialTokens(0, initialTokens.Count-1, initialTokens); return newExp; }
/** * Returns array of double values of the function f(i) * calculated on the range: i = from to i = to by step = delta * * @param f Function expression * @param index Index argument * @param from 'from' value * @param to 'to' value * @param delta 'delta' step definition * @return Array of function values */ public static double[] getFunctionValues(Expression f, Argument index, double from, double to, double delta) { if ((Double.IsNaN(delta)) || (Double.IsNaN(from)) || (Double.IsNaN(to)) || (delta == 0)) return null; int n = 0; double[] values; if ((to >= from) && (delta > 0)) { for (double i = from; i < to; i += delta) n++; n++; values = new double[n]; int j = 0; for (double i = from; i < to; i += delta) { values[j] = getFunctionValue(f, index, i); j++; } values[j] = getFunctionValue(f, index, to); } else if ((to <= from) && (delta < 0)) { for (double i = from; i > to; i += delta) n++; n++; values = new double[n]; int j = 0; for (double i = from; i > to; i += delta) { values[j] = getFunctionValue(f, index, i); j++; } values[j] = getFunctionValue(f, index, to); } else if (from == to) { n = 1; values = new double[n]; values[0] = getFunctionValue(f, index, from); } else values = null; return values; }
/** * Function derivative * * @param pos the token position * @param derivativeType the type of derivative (left, right, etc...) */ private void DERIVATIVE_NTH(int pos, int derivativeType) { const double DEF_EPS = 1E-6; /* * Default max number of steps */ const int DEF_MAX_STEPS = 20; List<FunctionParameter> derParams = getFunctionParameters(pos, tokensList); /* * Get internal function strinng * 1st - parameter */ FunctionParameter funParam = derParams[0]; /* * Get n-th * 2nd - parameter */ FunctionParameter nParam = derParams[1]; /* * Get argument * 3rd - parameter */ FunctionParameter xParam = derParams[2]; ArgumentParameter x = getParamArgument(xParam.paramStr); if (x.presence == Argument.NOT_FOUND) { updateMissingTokens(xParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(funParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(nParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); } Expression funExp = new Expression(funParam.paramStr, funParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); Expression nExp = new Expression(nParam.paramStr, nParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); double n = nExp.calculate(); double x0 = x.argument.getArgumentValue(); double eps = DEF_EPS; int maxSteps = DEF_MAX_STEPS; if (derParams.Count == 5) { FunctionParameter epsParam = derParams[3]; FunctionParameter maxStepsParam = derParams[4]; if (x.presence == Argument.NOT_FOUND) { updateMissingTokens(epsParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(maxStepsParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); } Expression epsExpr = new Expression(epsParam.paramStr, epsParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); Expression maxStepsExp = new Expression(maxStepsParam.paramStr, maxStepsParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); eps = epsExpr.calculate(); maxSteps = (int)Math.Round(maxStepsExp.calculate()); } if (derivativeType == Calculus.GENERAL_DERIVATIVE) { double left = Calculus.derivativeNth(funExp, n, x.argument, x0, Calculus.LEFT_DERIVATIVE, eps, maxSteps); double right = Calculus.derivativeNth(funExp, n, x.argument, x0, Calculus.RIGHT_DERIVATIVE, eps, maxSteps); calcSetDecreaseRemove(pos, (left + right) / 2.0); } else if (derivativeType == Calculus.LEFT_DERIVATIVE) { double left = Calculus.derivativeNth(funExp, n, x.argument, x0, Calculus.LEFT_DERIVATIVE, eps, maxSteps); calcSetDecreaseRemove(pos, left); } else { double right = Calculus.derivativeNth(funExp, n, x.argument, x0, Calculus.RIGHT_DERIVATIVE, eps, maxSteps); calcSetDecreaseRemove(pos, right); } clearParamArgument(x); }
private double Integral(Expression exp, double n) { exp.setArgumentValue("n", n); return(exp.calculate()); }
/** * Private constructor - expression cloning. * * @param expression the base expression */ private Expression(Expression expression) { expressionString = String.Copy(expression.expressionString); description = String.Copy(expression.description); argumentsList = expression.argumentsList; functionsList = expression.functionsList; constantsList = expression.constantsList; keyWordsList = expression.keyWordsList; relatedExpressionsList = expression.relatedExpressionsList; computingTime = 0; expressionWasModified = expression.expressionWasModified; recursiveMode = expression.recursiveMode; verboseMode = expression.verboseMode; syntaxStatus = expression.syntaxStatus; errorMessage = String.Copy(expression.errorMessage); recursionCallPending = expression.recursionCallPending; parserKeyWordsOnly = expression.parserKeyWordsOnly; disableUlpRounding = expression.disableUlpRounding; }
private void Conversion_click(object sender, RoutedEventArgs e) { if (MathExp.Any()) { var detailSelectedStr = "question"; if (Conversion_ask.SelectedValue.ToString() == "uo_length") { var inputUnit = Units_length.SelectedValue; if (inputUnit.ToString() != detailSelectedStr) { Expression mm = new Expression($"(({MathExp})*[{inputUnit}])/[mm]"); WinCnversion.FeedTxt1($"Millimetre: {mm.calculate()}"); WinCnversion.ShowTxt1(); Expression cm = new Expression($"(({MathExp})*[{inputUnit}])/[cm]"); WinCnversion.FeedTxt2($"Centimeter: {cm.calculate()}"); WinCnversion.ShowTxt2(); Expression m = new Expression($"(({MathExp})*[{inputUnit}])/[m]"); WinCnversion.FeedTxt3($"Meter: {m.calculate()}"); WinCnversion.ShowTxt3(); Expression km = new Expression($"(({MathExp})*[{inputUnit}]) / [km]"); WinCnversion.FeedTxt4($"Kilometer: {km.calculate()}"); WinCnversion.ShowTxt4(); Expression inch = new Expression($"(({MathExp})*[{inputUnit}])/[inch]"); WinCnversion.FeedTxt5($"Inch: {inch.calculate()}"); WinCnversion.ShowTxt5(); Expression ft = new Expression($"(({MathExp})*[{inputUnit}])/[ft]"); WinCnversion.FeedTxt6($"Foot: {ft.calculate()}"); WinCnversion.ShowTxt6(); } else { DisplayResult("Select a unit"); } } else if (Conversion_ask.SelectedValue.ToString() == "uo_mass") { var inputUnit = Units_mass.SelectedValue; if (inputUnit.ToString() != detailSelectedStr) { Expression mg = new Expression($"(({MathExp})*[{inputUnit}])/[mg]"); WinCnversion.output_1b.Text = $"Milligram: {mg.calculate()}"; WinCnversion.output_1b.Visibility = Visibility.Visible; Expression gr = new Expression($"(({MathExp})*[{inputUnit}])/[gr]"); WinCnversion.output_2b.Text = $"Gram: {gr.calculate()}"; WinCnversion.output_2b.Visibility = Visibility.Visible; Expression kg = new Expression($"(({MathExp})*[{inputUnit}])/[kg]"); WinCnversion.output_3b.Text = $"Kilogram: {kg.calculate()}"; WinCnversion.output_3b.Visibility = Visibility.Visible; Expression oz = new Expression($"(({MathExp})*[{inputUnit}])/[oz]"); WinCnversion.output_4b.Text = $"Ounce: {oz.calculate()}"; WinCnversion.output_4b.Visibility = Visibility.Visible; Expression lb = new Expression($"(({MathExp})*[{inputUnit}])/[lb]"); WinCnversion.output_5b.Text = $"Pound: {lb.calculate()}"; WinCnversion.output_5b.Visibility = Visibility.Visible; } else { DisplayResult("Select a unit"); } } else if (Conversion_ask.SelectedValue.ToString() == "uo_info") { var inputUnit = Units_info.SelectedValue; if (inputUnit.ToString() != detailSelectedStr) { Expression b = new Expression($"(({MathExp})*[{inputUnit}])/[B]"); WinCnversion.output_1b.Text = $"Byte: {b.calculate()}"; WinCnversion.output_1b.Visibility = Visibility.Visible; Expression kb = new Expression($"(({MathExp})*[{inputUnit}])/[kB]"); WinCnversion.output_2b.Text = $"Kilobyte: {kb.calculate()}"; WinCnversion.output_2b.Visibility = Visibility.Visible; Expression mb = new Expression($"(({MathExp})*[{inputUnit}])/[MB]"); WinCnversion.output_3b.Text = $"Megabyte: {mb.calculate()}"; WinCnversion.output_3b.Visibility = Visibility.Visible; Expression gb = new Expression($"(({MathExp})*[{inputUnit}])/[GB]"); WinCnversion.output_4b.Text = $"Gigabyte: {gb.calculate()}"; WinCnversion.output_4b.Visibility = Visibility.Visible; Expression tb = new Expression($"(({MathExp})*[{inputUnit}])/[TB]"); WinCnversion.output_5b.Text = $"Terabyte: {tb.calculate()}"; WinCnversion.output_5b.Visibility = Visibility.Visible; } else { DisplayResult("Select a unit"); } } else if (Conversion_ask.SelectedValue.ToString() == "uo_time") { var inputUnit = Units_time.SelectedValue; if (inputUnit.ToString() != detailSelectedStr) { Expression sec = new Expression($"(({MathExp})*[{inputUnit}])/[s]"); WinCnversion.output_1b.Text = $"Second: {sec.calculate()}"; WinCnversion.output_1b.Visibility = Visibility.Visible; Expression min = new Expression($"(({MathExp})*[{inputUnit}])/[min]"); WinCnversion.output_2b.Text = $"Minute: {min.calculate()}"; WinCnversion.output_2b.Visibility = Visibility.Visible; Expression mb = new Expression($"(({MathExp})*[{inputUnit}])/[h]"); WinCnversion.output_3b.Text = $"Hour: {mb.calculate()}"; WinCnversion.output_3b.Visibility = Visibility.Visible; } else { DisplayResult("Select a unit"); } } else if (Conversion_ask.SelectedValue.ToString() == "uo_percent") { Expression regularMath = new Expression(MathExp); var single = regularMath.calculate(); Expression toBig = new Expression($"{single}*100"); WinCnversion.output_1b.Text = $"{single} is {toBig.calculate()}%"; WinCnversion.output_1b.Visibility = Visibility.Visible; Expression toSm = new Expression($"{single}/100"); WinCnversion.output_2b.Text = $"{single}% is {toSm.calculate()}"; WinCnversion.output_2b.Visibility = Visibility.Visible; ClearAll(); } else if (Conversion_ask.SelectedValue.ToString() == "uo_number") { bool success = int.TryParse(MathExp, out int my_regular); if (success) { WinCnversion.output_1b.Text = $"Integer: {my_regular}"; WinCnversion.output_1b.Visibility = Visibility.Visible; var my_bin = ToBinary(my_regular); WinCnversion.output_2b.Text = $"Binary: {my_bin}"; WinCnversion.output_2b.Visibility = Visibility.Visible; var my_oct = Convert.ToString(my_regular, 8); WinCnversion.output_3b.Text = $"Octal: {my_oct}"; WinCnversion.output_3b.Visibility = Visibility.Visible; var my_hex = Convert.ToString(my_regular, 16); WinCnversion.output_4b.Text = $"Hexadecimal: {my_hex}"; WinCnversion.output_4b.Visibility = Visibility.Visible; ClearAll(); } else { WinCnversion.output_1b.Text = $"Not a integer or other errors"; WinCnversion.output_1b.Visibility = Visibility.Visible; } } } else { var warningMsg = "An input number required"; DisplayResult(warningMsg); } }
/** * IF function * * @param pos the token position */ private void IF_CONDITION(int pos) { /* * Get condition string * 1st parameter */ List<FunctionParameter> ifParams = getFunctionParameters(pos, tokensList); FunctionParameter ifParam = ifParams[0]; Expression ifExp = new Expression(ifParam.paramStr, ifParam.tokens, argumentsList, functionsList, constantsList, KEEP_ULP_ROUNDING_SETTINGS); if (verboseMode == true) ifExp.setVerboseMode(); ifSetRemove(pos, ifExp.calculate()); }
/** * Adds related expression form the argumentExpression * * @param expression related expression * * @see Expression */ internal void removeRelatedExpression(Expression expression) { argumentExpression.removeRelatedExpression(expression); }
/** * Constructor for function definition in natural math language, * for instance providing on string "f(x,y) = sin(x) + cos(x)" * is enough to define function "f" with parameters "x and y" * and function body "sin(x) + cos(x)". * * @param constantDefinitionString Constant definition in the form * of one String, ie "c = 2" or "c = 2*sin(pi/3)" * @param elements Optional parameters (comma separated) such as Arguments, Constants, Functions */ public Constant(String constantDefinitionString, params PrimitiveElement[] elements) : base(Constant.TYPE_ID) { description = ""; syntaxStatus = SYNTAX_ERROR_OR_STATUS_UNKNOWN; relatedExpressionsList = new List<Expression>(); if (mXparser.regexMatch(constantDefinitionString, ParserSymbol.constArgDefStrRegExp)) { HeadEqBody headEqBody = new HeadEqBody(constantDefinitionString); constantName = headEqBody.headTokens[0].tokenStr; Expression bodyExpression = new Expression(headEqBody.bodyStr, elements); constantValue = bodyExpression.calculate(); syntaxStatus = bodyExpression.getSyntaxStatus(); errorMessage = bodyExpression.getErrorMessage(); } else errorMessage = "[" + constantDefinitionString + "] " + "--> pattern not mathes: " + ParserSymbol.constArgDefStrRegExp; }
/*================================================= * * Constructors * *================================================= */ /** * Constructor - creates function from function name * and function expression string. * * @param functionName the function name * @param functionExpressionString the function expression string * @param elements Optional elements list (variadic - comma separated) of types: Argument, Constant, Function * * @see PrimitiveElement * @see Expression */ public Function(String functionName ,String functionExpressionString, params PrimitiveElement[] elements) : base(Function.TYPE_ID) { if (mXparser.regexMatch(functionName, ParserSymbol.nameOnlyTokenRegExp)) { this.functionName = functionName; functionExpression = new Expression(functionExpressionString, elements); functionExpression.setDescription(functionName); parametersNumber = 0; description = ""; addFunctions(this); } else { parametersNumber = 0; description = ""; functionExpression = new Expression(""); functionExpression.setSyntaxStatus(SYNTAX_ERROR_OR_STATUS_UNKNOWN, "[" + functionName + "]" + "Invalid function name, pattern not matches: " + ParserSymbol.nameTokenRegExp); } }
/*================================================= * * Constructors * *================================================= */ /** * Default constructor - creates argument based on the argument definition string. * * @param argumentDefinitionString Argument definition string, i.e.: * <ul> * <li>'x' - only argument name * <li>'x=5' - argument name and argument value * <li>'x=2*5' - argument name and argument value given as simple expression * <li>'x=2*y' - argument name and argument expression (dependent argument 'x' on argument 'y') * </ul> * * @param elements Optional parameters (comma separated) such as Arguments, Constants, Functions */ public Argument(String argumentDefinitionString, params PrimitiveElement[] elements) : base(Argument.TYPE_ID) { if (mXparser.regexMatch(argumentDefinitionString, ParserSymbol.nameOnlyTokenRegExp)) { argumentName = argumentDefinitionString; argumentValue = ARGUMENT_INITIAL_VALUE; argumentType = FREE_ARGUMENT; argumentExpression = new Expression(elements); } else if (mXparser.regexMatch(argumentDefinitionString, ParserSymbol.constArgDefStrRegExp)) { HeadEqBody headEqBody = new HeadEqBody(argumentDefinitionString); argumentName = headEqBody.headTokens[0].tokenStr; Expression bodyExpr = new Expression(headEqBody.bodyStr); double bodyValue = bodyExpr.calculate(); if ((bodyExpr.getSyntaxStatus() == Expression.NO_SYNTAX_ERRORS) && (bodyValue != Double.NaN)) { argumentExpression = new Expression(); argumentValue = bodyValue; argumentType = FREE_ARGUMENT; } else { argumentExpression = bodyExpr; addDefinitions(elements); argumentType = DEPENDENT_ARGUMENT; } } else if (mXparser.regexMatch(argumentDefinitionString, ParserSymbol.functionDefStrRegExp)) { HeadEqBody headEqBody = new HeadEqBody(argumentDefinitionString); argumentName = headEqBody.headTokens[0].tokenStr; argumentExpression = new Expression(headEqBody.bodyStr, elements); argumentExpression.setDescription(headEqBody.headStr); argumentValue = ARGUMENT_INITIAL_VALUE; argumentType = DEPENDENT_ARGUMENT; n = new Argument(headEqBody.headTokens[2].tokenStr); } else { argumentValue = ARGUMENT_INITIAL_VALUE; argumentType = FREE_ARGUMENT; argumentExpression = new Expression(); argumentExpression.setSyntaxStatus(SYNTAX_ERROR_OR_STATUS_UNKNOWN, "[" + argumentDefinitionString + "] " + "Invalid argument definition (patterns: 'x', 'x=5', 'x=5+3/2', 'x=2*y')."); } setSilentMode(); description = ""; }
/** * Constructor for function definition in natural math language, * for instance providing on string "f(x,y) = sin(x) + cos(x)" * is enough to define function "f" with parameters "x and y" * and function body "sin(x) + cos(x)". * * @param functionDefinitionString Function definition in the form * of one String, ie "f(x,y) = sin(x) + cos(x)" * @param elements Optional elements list (variadic - comma separated) * of types: Argument, Constant, Function * * @see PrimitiveElement * */ public Function(String functionDefinitionString, params PrimitiveElement[] elements) : base(Function.TYPE_ID) { parametersNumber = 0; if (mXparser.regexMatch(functionDefinitionString, ParserSymbol.functionDefStrRegExp)) { HeadEqBody headEqBody = new HeadEqBody(functionDefinitionString); this.functionName = headEqBody.headTokens[0].tokenStr; functionExpression = new Expression(headEqBody.bodyStr, elements); functionExpression.setDescription(headEqBody.headStr); if (headEqBody.headTokens.Count > 1) { Token t; for (int i = 1; i < headEqBody.headTokens.Count; i++) { t = headEqBody.headTokens[i]; if (t.tokenTypeId != ParserSymbol.TYPE_ID) functionExpression.addArguments(new Argument(t.tokenStr)); } } parametersNumber = functionExpression.getArgumentsNumber() - countRecursiveArguments(); description = ""; addFunctions(this); } else { functionExpression = new Expression(); functionExpression.setDescription(functionDefinitionString); String errorMessage = ""; errorMessage = errorMessage + "\n [" + functionDefinitionString + "] " + "--> pattern not mathes: f(x1,...,xn) = ... reg exp: " + ParserSymbol.functionDefStrRegExp; functionExpression.setSyntaxStatus(Expression.SYNTAX_ERROR_OR_STATUS_UNKNOWN, errorMessage); } }
/** * Constructor - creates free argument. * * @param argumentName the argument name * @param argumentValue the argument value */ public Argument(String argumentName, double argumentValue) : base(Argument.TYPE_ID) { argumentExpression = new Expression(); if (mXparser.regexMatch(argumentName, ParserSymbol.nameOnlyTokenRegExp)) { this.argumentName = String.Copy(argumentName); this.argumentValue = argumentValue; argumentType = FREE_ARGUMENT; } else { this.argumentValue = ARGUMENT_INITIAL_VALUE; argumentExpression.setSyntaxStatus(SYNTAX_ERROR_OR_STATUS_UNKNOWN, "[" + argumentName + "] " + "Invalid argument name, pattern not match: " + ParserSymbol.nameOnlyTokenRegExp); } setSilentMode(); description = ""; }
/** * Adds related expression. * * @param expression the related expression */ internal void addRelatedExpression(Expression expression) { functionExpression.addRelatedExpression(expression); }
/** * Constructor - creates dependent argument(with hidden * argument expression). * * @param argumentName the argument name * @param argumentExpressionString the argument expression string * @param elements Optional parameters (comma separated) * such as Arguments, Constants, Functions * * @see Expression * @see PrimitiveElement */ public Argument(String argumentName, String argumentExpressionString, params PrimitiveElement[] elements) : base(Argument.TYPE_ID) { if (mXparser.regexMatch(argumentName, ParserSymbol.nameOnlyTokenRegExp)) { this.argumentName=String.Copy(argumentName); argumentValue=ARGUMENT_INITIAL_VALUE; argumentExpression = new Expression(argumentExpressionString, elements); argumentExpression.setDescription(argumentName); argumentType = DEPENDENT_ARGUMENT; } else { this.argumentValue = ARGUMENT_INITIAL_VALUE; argumentExpression = new Expression(); argumentExpression.setSyntaxStatus(SYNTAX_ERROR_OR_STATUS_UNKNOWN, "[" + argumentName + "] " + "Invalid argument name, pattern not match: " + ParserSymbol.nameOnlyTokenRegExp); } setSilentMode(); description = ""; }
/*================================================= * * Related expressions handling * *================================================= */ /** * Adds related expression * The same expression could be added more than once * For example when * * @param expression the expression */ internal void addRelatedExpression(Expression expression) { if ((expression != null) && (expression != this)) if ( !relatedExpressionsList.Contains(expression)) relatedExpressionsList.Add(expression); }
/*================================================= * * Related expressions handling * *================================================= */ /** * Adds related expression to the argumentExpression * * @param expression the related expression * @see Expression */ internal void addRelatedExpression(Expression expression) { argumentExpression.addRelatedExpression(expression); }
/** * Removes related expression * * @param expression the expression */ internal void removeRelatedExpression(Expression expression) { relatedExpressionsList.Remove(expression); }
/** * Gets recursive argument value * * @param index the index * * @return value as double */ public double getArgumentValue(double index) { /* * Remember starting index */ if (recursiveCounter == -1) startingIndex = (int)Math.Round(index); int recSize = baseValues.Count; int idx = (int)Math.Round(index); /* * Count recursive calls */ recursiveCounter++; if ((recursiveCounter <= startingIndex) && (idx <= startingIndex)) { /* * if recursive counter is still lower than starting index * and current index is not increasing */ if ((idx >= 0) && (idx < recSize) && (!Double.IsNaN( baseValues[idx] )) ) { /* * decrease recursive counter and return value * if recursive value for the current index was already * calculated and remembered in the base values table */ recursiveCounter--; return baseValues[idx]; } else if (idx >= 0) { /* * value is to be calculated by the recursive calls */ /* * Set n to the current index */ n.setArgumentValue(idx); /* * create new expression */ Expression newExp = new Expression( base.argumentExpression.expressionString , base.argumentExpression.argumentsList , base.argumentExpression.functionsList , base.argumentExpression.constantsList ,Expression.INTERNAL); newExp.setDescription(base.getArgumentName()); //newExp.setRecursiveMode(); if (base.getVerboseMode() == true) { //System.out.println(super.getVerboseMode() + ", " +super.getArgumentName() + ", " + super.argumentExpression.expressionString + "," + "VERBOSE MODE for recurssion"); newExp.setVerboseMode(); } /* * perform recursive call */ double value = newExp.calculate(); /* * remember calculated in the base values array */ addBaseCase(idx, value); /* * decrease recursive counter and return value */ recursiveCounter--; return value; } else { /* * decrease recursive counter and * return Double.NaN for negative index call */ recursiveCounter--; return Double.NaN; } } else { /* stop never ending loop * decrease recursive counter and * return Double.NaN */ recursiveCounter--; return Double.NaN; } }
/** * Forward difference operator * * @param pos the token position */ private void FORWARD_DIFFERENCE(int pos) { List<FunctionParameter> parameters = getFunctionParameters(pos, tokensList); FunctionParameter funParam = parameters[0]; FunctionParameter xParam = parameters[1]; ArgumentParameter x = getParamArgument(xParam.paramStr); Expression funExp = new Expression(funParam.paramStr, funParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); if (verboseMode == true) funExp.setVerboseMode(); double h = 1; if (parameters.Count == 3) { FunctionParameter hParam = parameters[2]; Expression hExp = new Expression(hParam.paramStr, hParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); if (verboseMode == true) hExp.setVerboseMode(); h = hExp.calculate(); } calcSetDecreaseRemove(pos, Calculus.forwardDifference(funExp, h, x.argument) ); clearParamArgument(x); }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { var stopWatch = System.Diagnostics.Stopwatch.StartNew(); int questionNum = Convert.ToInt32(questionNumber.Value); if (backgroundWorker1.CancellationPending) { e.Cancel = true; backgroundWorker1.ReportProgress(0); return; } else { while (!backgroundWorker1.CancellationPending && !workIsCompleted) { Debug.WriteLine("Checking if backgroundWorker Cancelled"); for (int i = 0; i <= questionNumber.Value; i++) { Debug.WriteLine("This Line has been executed on For Loop."); decimals = true; while (decimals == true) { Random questionTypeGen = new Random(); string questionRandResult = questionGenerator(Convert.ToInt32(((quizForm)f).iterationValue.Text) - 1, Convert.ToInt32(((quizForm)f).firstNum1.Value), Convert.ToInt32(((quizForm)f).firstNum2.Value)); if (formattingOption1.Checked == true) { questionString = questionRandResult; } else { questionString = questionRandResult.Replace("*", " X "); questionString = questionString.Replace("+", " + "); questionString = questionString.Replace("-", " - "); questionString = questionString.Replace("/", " : "); } Expression ex = new Expression(questionRandResult); result = ex.calculate(); Debug.WriteLine("This Line executed after computing"); if (Math.Abs(result % 1) < Double.Epsilon) { decimals = false; sb.Append(questionString + " = " + result.ToString() + Environment.NewLine); Debug.WriteLine(sb.ToString()); } else { if (((quizForm)f).noDecimalCheckbox.Checked == false) { decimals = false; double resultNew = Math.Round(result, Convert.ToInt32(((quizForm)f).decimalNumbers.Text), MidpointRounding.AwayFromZero); sb.Append(questionString + " = " + resultNew.ToString() + Environment.NewLine); } else { decimals = true; retryCount++; } } } if (backgroundWorker1.CancellationPending) { backgroundWorker1.ReportProgress(0); break; } if (i == questionNum) { Debug.WriteLine("Completed!"); workIsCompleted = true; } backgroundWorker1.ReportProgress(i); } } } stopWatch.Stop(); }
/** * IFF function * * @param pos the token position */ private void IFF(int pos) { /* * Get condition string * 1st parameter */ List<FunctionParameter> iffParams = getFunctionParameters(pos, tokensList); FunctionParameter iffParam = iffParams[0]; int parametersNumber = iffParams.Count; int trueParamNumber; int paramNumber; paramNumber = 1; Expression iffExp; double iffValue = 0; bool iffCon = true; do { iffExp = new Expression(iffParam.paramStr, iffParam.tokens, argumentsList, functionsList, constantsList, KEEP_ULP_ROUNDING_SETTINGS); if (verboseMode == true) iffExp.setVerboseMode(); iffCon = true; iffValue = iffExp.calculate(); if ( (iffValue == 0) || (Double.IsNaN(iffValue)) ) { paramNumber += 2; iffCon = false; if (paramNumber < parametersNumber) iffParam = iffParams[paramNumber-1]; } } while ( (!iffCon) && (paramNumber < parametersNumber) ); int from; int to; int p; if (iffCon) { trueParamNumber = paramNumber+1; from = pos+1; to = iffParams[parametersNumber-1].toIndex+1; tokensList[from].tokenLevel--; tokensList[to].tokenLevel--; if (trueParamNumber < parametersNumber) { to = iffParams[parametersNumber-1].toIndex; from = iffParams[trueParamNumber].fromIndex-1; for (p = to; p >= from; p--) tokensList.RemoveAt(p); } from = iffParams[trueParamNumber-1].fromIndex; to = iffParams[trueParamNumber-1].toIndex; for (p = from; p <= to; p++) tokensList[p].tokenLevel--; to = from-1; from = pos; for (p = to; p >= from; p--) if (p != pos + 1) tokensList.RemoveAt(p); } else { to = iffParams[parametersNumber-1].toIndex+1; from = pos+1; for (p = to; p >= from; p--) tokensList.RemoveAt(p); setToNumber(pos, Double.NaN); tokensList[pos].tokenLevel--; } }
private void calc(string input) { if (CurrentValue == "NaN") { CurrentValue = ""; } Regex isNumber = new Regex(@"^\d$"); if (isNumber.IsMatch(input)) { CurrentValue += input; CurrentValue = format(CurrentValue); } else if (input == "🗑") { Historique.Clear(); } else if (input == "C") { CalcString = ""; CurrentValue = ""; } else if (input == "CE") { CurrentValue = ""; } else if (input == "=") { if (CalcString.Length > 0) { if (CurrentValue.Length == 0 && CalcString.Substring(CalcString.Length - 1) != "!" && CalcString.Substring(CalcString.Length - 1) != ")") { CalcString = CalcString.Substring(0, CalcString.Length - 1); } CalcString += CurrentValue; if (CalcString.Count(x => x == '(') > CalcString.Count(x => x == ')')) { int numberOfOpen = CalcString.Count(x => x == '('); int numberOfClose = CalcString.Count(x => x == ')'); int rest = numberOfOpen - numberOfClose; for (int i = 0; i < rest; i++) { CalcString += ')'; } } CalcString = CalcString.Replace(",", "."); org.mariuszgromada.math.mxparser.Expression expression = new org.mariuszgromada.math.mxparser.Expression(new string(CalcString.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray())); double result = expression.calculate(); CurrentValue = format(result.ToString()); Historique.Add(new Calcul(CalcString, format(result.ToString()))); CalcString = ""; } } else if (input == ",") { if (CurrentValue.IndexOf(',') == -1 && CurrentValue.Length != 0) { CurrentValue += input; } } else if (input == "(") { CalcString += input; } else if (input == ")") { CalcString += CurrentValue + ")"; CurrentValue = ""; } else { // Supprime la virgule en fin de lignesi un opérateur est choisie if (CurrentValue.Length > 0 && CurrentValue.Substring(CurrentValue.Length - 1) == ",") { CurrentValue = CurrentValue.Substring(0, CurrentValue.Length - 1); } // Ajoute un opérateur s'il y a déjà une valeur enregistré if (CurrentValue != "" || (CalcString.Length > 0 && CalcString.Substring(CalcString.Length - 1) == "!") || (CalcString.Length > 0 && CalcString.Substring(CalcString.Length - 1) == ")")) { CalcString += CurrentValue + input; CurrentValue = ""; } else if (CalcString.Length > 0) { CalcString = CalcString.Substring(0, CalcString.Length - 1) + input; } if (input == "-" && CalcString.Length == 0) { CalcString = "0-"; } } }
/** * Function integral * * @param pos the token position */ private void INTEGRAL(int pos) { /** * Default epsilon */ const double DEF_EPS = 1E-6 ; /* * Default max number of steps */ const int DEF_MAX_STEPS = 20; List<FunctionParameter> intParams = getFunctionParameters(pos, tokensList); /* * Get internal function strinng * 1th - parameter */ FunctionParameter funParam = intParams[0]; /* * Get argument * 2nd - parameter */ FunctionParameter xParam = intParams[1]; /* * Get <a,b> * 2nd - parameter */ FunctionParameter aParam = intParams[2]; FunctionParameter bParam = intParams[3]; ArgumentParameter x = getParamArgument(xParam.paramStr); if (x.presence == Argument.NOT_FOUND) { updateMissingTokens(xParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(funParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(aParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); updateMissingTokens(bParam.tokens, xParam.paramStr, x.index, Argument.TYPE_ID ); } Expression funExp = new Expression(funParam.paramStr, funParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); Expression aExp = new Expression(aParam.paramStr, aParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); Expression bExp = new Expression(bParam.paramStr, bParam.tokens, argumentsList, functionsList, constantsList, DISABLE_ULP_ROUNDING); double eps = DEF_EPS; int maxSteps = DEF_MAX_STEPS; calcSetDecreaseRemove(pos, Calculus.integralTrapezoid(funExp, x.argument, aExp.calculate(), bExp.calculate(), eps, maxSteps) ); clearParamArgument(x); }
public static void Start() { /* * Tutorial for the mXparser version 1.0 * Mariusz Gromada 2010-01-10 */ /* * Simple & complex arithmetic expressions, large math functions collection * User defined arguments, functions, constants * Calculus operations (i.e. differentiation, integration) * Summation and product operations * User defined recursive functions * Boolean operators * and many more... * */ /* * Start from the license */ Expression e = new Expression(); mXparser.consolePrintln(e.getLicense()); mXparser.consolePrintln(); /* * Using help */ mXparser.consolePrintln(); mXparser.consolePrintln(e.getHelp()); /* * Full line searching */ mXparser.consolePrintln(); mXparser.consolePrintln(e.getHelp("sine")); mXparser.consolePrintln(); mXparser.consolePrintln(e.getHelp("inver")); /* * Simple expression */ Expression e1 = new Expression("2+1"); mXparser.consolePrintln(e1.getExpressionString() + " = " + e1.calculate()); e1.setExpressionString("2-1"); mXparser.consolePrintln(e1.getExpressionString() + " = " + e1.calculate()); /* operators */ Expression e2 = new Expression("2-(32-4)/(23+(4)/(5))-(2-4)*(4+6-98.2)+4"); mXparser.consolePrintln(e2.getExpressionString() + " = " + e2.calculate()); /* power function */ Expression e3 = new Expression("2^3+2^(-3)+2^3^(-4)"); mXparser.consolePrintln(e3.getExpressionString() + " = " + e3.calculate()); /* * Relations */ Expression e4 = new Expression("2=3"); mXparser.consolePrintln(e4.getExpressionString() + " = " + e4.calculate()); Expression e5 = new Expression("2<3"); mXparser.consolePrintln(e5.getExpressionString() + " = " + e5.calculate()); Expression e6 = new Expression("(2=3) | (2<3)"); mXparser.consolePrintln(e6.getExpressionString() + " = " + e6.calculate()); Expression e7 = new Expression("(2=3) & (2<3)"); mXparser.consolePrintln(e7.getExpressionString() + " = " + e7.calculate()); /* 1 arg functions */ Expression e8 = new Expression("sin(2)-cos(3)"); mXparser.consolePrintln(e8.getExpressionString() + " = " + e8.calculate()); /* 2 args functions */ Expression e9 = new Expression("min(3,4) + max(-2,-1)"); mXparser.consolePrintln(e9.getExpressionString() + " = " + e9.calculate()); /* binomial coefficient */ Expression e10 = new Expression("C(10,5)"); mXparser.consolePrintln(e10.getExpressionString() + " = " + e10.calculate()); /* 3 args functions */ /* conditions */ Expression e11 = new Expression("if(2<3,1,0)"); mXparser.consolePrintln(e11.getExpressionString() + " = " + e11.calculate()); Expression e12 = new Expression("if(3<2,1,0)"); mXparser.consolePrintln(e12.getExpressionString() + " = " + e12.calculate()); Expression e13 = new Expression("if(3<2, 1, if(1=1, 5, 0) )"); mXparser.consolePrintln(e13.getExpressionString() + " = " + e13.calculate()); /* * Free Arguments */ Argument x = new Argument("x", 1); Argument y = new Argument("y", 2); Argument z = new Argument("z", 3); Argument n = new Argument("n", 4); Expression e14 = new Expression("sin(x+y)-cos(y/z)", x, y, z); mXparser.consolePrintln(e14.getExpressionString() + " = " + e14.calculate()); Expression e15 = new Expression("if(x>y, x-z, if(y<z, sin(x+y), cos(z)) )", x, y, z); mXparser.consolePrintln(e15.getExpressionString() + " = " + e15.calculate()); x.setArgumentValue(5); mXparser.consolePrintln(x.getArgumentName() + " = " + x.getArgumentValue()); /* * Dependent arguments */ y = new Argument("y","2*x+5", x); mXparser.consolePrintln(y.getArgumentName() + " = " + y.getArgumentValue()); y = new Argument("y","sin(y)-z", y, z); mXparser.consolePrintln(y.getArgumentName() + " = " + y.getArgumentValue()); /* syntax checking */ y.setArgumentExpressionString("n*sin(y)-z"); mXparser.consolePrintln(y.getArgumentName() + " = ... \n syntax = " + y.checkSyntax() + "\n message = \n" + y.getErrorMessage()); y.addArguments(n); mXparser.consolePrintln(y.getArgumentName() + " = ... \n syntax = " + y.checkSyntax() + "\n message = \n" + y.getErrorMessage()); mXparser.consolePrintln(y.getArgumentName() + " = " + y.getArgumentValue()); /* * the same methods could be called * for the expression syntax checking * */ /* * Complex expressions */ /* * Summation operator SIGMA * sum(index, from, to, expr) * sum(index, from, to, expr, by) * */ Expression e16 = new Expression("sum(i,1,10,i)"); mXparser.consolePrintln(e16.getExpressionString() + " = " + e16.calculate()); Expression e17 = new Expression("sum(i,1,10,i,0.5)"); mXparser.consolePrintln(e17.getExpressionString() + " = " + e17.calculate()); /* * Product operator SIGMA * prod(index, from, to, expr) * prod(index, from, to, expr, by) */ /* factorial */ Expression e18 = new Expression("prod(i,1,5,i)"); mXparser.consolePrintln(e18.getExpressionString() + " = " + e18.calculate()); Expression e19 = new Expression("prod(i,1,5,i,0.5)"); mXparser.consolePrintln(e19.getExpressionString() + " = " + e19.calculate()); /* Approximation sin(x) by Taylor series * ! - factorial */ Expression e20 = new Expression("sin(x)-sum(n,0,10,(-1)^n*(x^(2*n+1))/(2*n+1)!)", x); x.setArgumentValue(1); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e20.getExpressionString() + " = " + e20.calculate()); x.setArgumentValue(5); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e20.getExpressionString() + " = " + e20.calculate()); x.setArgumentValue(10); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e20.getExpressionString() + " = " + e20.calculate()); /* * calculating pi by integral of * sqrt(1-x^2) from -1 to 1 * using simple summation operator */ Argument d = new Argument("d",0.1); Expression e21 = new Expression("2*sum(x, -1, 1, d*sqrt(1-x^2), d)", d); mXparser.consolePrintln("d = " + d.getArgumentValue() + ", " + e21.getExpressionString() + " = " + e21.calculate()); d.setArgumentValue(0.01); mXparser.consolePrintln("d = " + d.getArgumentValue() + ", " + e21.getExpressionString() + " = " + e21.calculate()); /* * Derivatives * * der( f(x,...), x) - general * der+( f(x,...), x) - right * der-( f(x,...), x) - left */ /* cos(x) as derivative from sin(x) */ Expression e22 = new Expression("cos(x)-der(sin(x), x)", x); mXparser.consolePrintln(e22.getExpressionString() + " = " + e22.calculate()); /* left and right derivative from |x| */ x.setArgumentValue(0); Expression e23 = new Expression("der-(abs(x), x)", x); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e23.getExpressionString() + " = " + e23.calculate()); Expression e24 = new Expression("der+(abs(x), x)", x); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e24.getExpressionString() + " = " + e24.calculate()); /* derivative from sin(x) as Taylor series (approximation) */ x.setArgumentValue(1); Expression e25 = new Expression("cos(x)-der(sum(n,0,10,(-1)^n*(x^(2*n+1))/(2*n+1)!), x)", x); x.setArgumentValue(1); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e25.getExpressionString() + " = " + e25.calculate()); x.setArgumentValue(5); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e25.getExpressionString() + " = " + e25.calculate()); x.setArgumentValue(10); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e25.getExpressionString() + " = " + e25.calculate()); /* * Integral * int(f(x,...), x, a, b) */ /* calculating PI value */ Expression e26 = new Expression("2*int(sqrt(1-x^2), x, -1, 1)"); mXparser.consolePrintln(e26.getExpressionString() + " = " + e26.calculate()); /* * Parser constants */ Expression e27 = new Expression("pi"); mXparser.consolePrintln(e27.getExpressionString() + " = " + e27.calculate()); Expression e28 = new Expression("e"); mXparser.consolePrintln(e28.getExpressionString() + " = " + e28.calculate()); /* and many many more ... */ /* * USER DEFINED FUNCTIONS * f(x,y) = sin(x+y) * f(a,b,c,d,...) = .... */ Function f = new Function("f", "x^2", "x"); Expression e29 = new Expression("f(2)"); e29.addFunctions(f); mXparser.consolePrintln(e29.getExpressionString() + " = " + e29.calculate()); /* * Please be informed that sequence of * arguments names is important. In the below exampe * a - 1st argument of f * b - 2nd argument of f * c - 3rd argument of f * * In the expressions f will be c alled as f( . , . , . ) */ f = new Function("f", "a+b+c", "a", "b", "c"); Expression e30 = new Expression("f(1, 2, 3)"); e30.addFunctions(f); mXparser.consolePrintln(e30.getExpressionString() + " = " + e30.calculate()); /* * Using functions in functions */ f = new Function("f", "x^2", "x"); Function g = new Function("g", "f(x)^2", "x"); g.addFunctions(f); mXparser.consolePrintln("g(2) = " + g.calculate(2)); Expression e31 = new Expression("f(x)+g(2*x)", x); e31.addFunctions(f, g); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e31.getExpressionString() + " = " + e31.calculate()); x.setArgumentValue(2); Expression e32 = new Expression("der(g(x),x)", x); e32.addFunctions(g); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e32.getExpressionString() + " = " + e32.calculate()); /* * Fundamental theorem of calculus * if F(x) = int_a^x f(t) dt * then F'(x) = f(x) */ f = new Function("f", "sin(x)", "x"); Function F = new Function("F", "int(f(t), t, 0, x)", "x"); F.addFunctions(f); Expression e33 = new Expression("f(x) - der(F(x),x)", x); e33.addFunctions(f, F); mXparser.consolePrintln("x = " + x.getArgumentValue() + ", " + e33.getExpressionString() + " = " + e33.calculate() + ", computing time : " + e33.getComputingTime() + " s."); /* * Simple (fast) recursion * Only one index n >= 0, n integer */ /* Fibonacci numbers with add base cases method*/ n = new Argument("n"); RecursiveArgument fib1 = new RecursiveArgument("fib1", "fib1(n-1)+fib1(n-2)", n); fib1.addBaseCase(0, 0); fib1.addBaseCase(1, 1); mXparser.consolePrintln("fib1: "); for (int i = 0; i <= 10; i++ ) mXparser.consolePrint(fib1.getArgumentValue(i) + ", "); mXparser.consolePrintln(); /* Fibonacci numbers with if statement*/ RecursiveArgument fib2 = new RecursiveArgument("fib2", "if( n>1, fib2(n-1)+fib2(n-2), if(n=1,1,0) )", n); mXparser.consolePrintln("fib2: "); for (int i = 0; i <= 10; i++ ) mXparser.consolePrint(fib2.getArgumentValue(i) + ", "); mXparser.consolePrintln(); Expression e34 = new Expression("sum(i, 0, 10, fib1(i))", fib1); mXparser.consolePrintln(e34.getExpressionString() + " = " + e34.calculate() + ", computing time : " + e34.getComputingTime() + " s."); Expression e35 = new Expression("sum(i, 0, 10, fib2(i))", fib2); mXparser.consolePrintln(e35.getExpressionString() + " = " + e35.calculate() + ", computing time : " + e35.getComputingTime() + " s."); /* * Complex recursion (slow) * any definition * * */ /* Fibonacci numbers using complex recursion */ Function fib3 = new Function("fib3","if(n>1, fib3(n-1)+fib3(n-2), if(n>0,1,0))", "n"); mXparser.consolePrintln("fib2: "); for (int i = 0; i <= 10; i++ ) mXparser.consolePrint(fib3.calculate(i) + ", "); mXparser.consolePrintln(); Expression e36 = new Expression("sum(i, 0, 10, fib3(i))"); e36.addFunctions(fib3); mXparser.consolePrintln(e36.getExpressionString() + " = " + e36.calculate() + ", computing time : " + e36.getComputingTime() + " s."); /* * Chebyshev polynomials definition using * recursive functions */ Function T = new Function("T","if(n>1, 2*x*T(n-1,x)-T(n-2,x), if(n>0, x, 1) )", "n", "x"); Argument k = new Argument("k", 5); Expression e37 = new Expression("T(k,x) - ( (x + sqrt(x^2-1))^k + (x - sqrt(x^2-1))^k)/2", k, x); e37.addFunctions(T); mXparser.consolePrintln(e37.getExpressionString() + " = " + e37.calculate() + ", computing time : " + e37.getComputingTime() + " s."); /* * Binomial coefficient using complex recursion */ Function Cnk = new Function("Cnk","if( k>0, if( k<n, Cnk(n-1,k-1)+Cnk(n-1,k), 1), 1)","n", "k"); Expression e38 = new Expression("C(10,5) - Cnk(10,5)"); e38.addFunctions(Cnk); mXparser.consolePrintln(e38.getExpressionString() + " = " + e38.calculate() + ", computing time : " + e38.getComputingTime() + " s."); /* * Differences between simple and complex recursion * * Simple: * * Advantages * 1) fast * 2) remembers what was previously calculated * 3) calculations are done in a controlled way * - recursion counter (each recursion step increases * recursion counter, for calculating n-th recursion * value maximum n recursion steps are needed * - no negative indexes * 4) add base value method * * Disadvantages * 1) limited to one index argument (positive integer index argument) * * Complex recursion * * Advantages * 1) flexible - no limitations * * Disadvantages * 1) slow * 2) no add base values method */ /* * User defined constants */ Constant a = new Constant("a", 5); Constant b = new Constant("b", 10); Constant c = new Constant("c", 15); Expression e39 = new Expression("a+b+c"); e39.addConstants(a, b, c); /* * For example in verbose mode * computing */ e39.setVerboseMode(); e39.checkSyntax(); mXparser.consolePrintln(); mXparser.consolePrintln(e39.getErrorMessage()); mXparser.consolePrintln(e39.getExpressionString() + " = " + e39.calculate() + ", computing time : " + e39.getComputingTime() + " s."); /* * There are much more other features in the mXparser API. * Please refer to the API specifications. * * Please be aware that this is the version 1.0 of the parser * - I am pretty sure you will find some bugs - if so please send me * more info: [email protected] */ }