private static void EvalMatrixD(AsyncArg arg, IExpression exprV1V2, double[,] res, int steps1, int[] progress, int index, string var1, double step1, int start1, int end1, string var2, double step2, int steps2) { for (int n = start1; n < end1; n++) { if (arg.Token.IsCancellationRequested) { return; } double v1 = step1 * n; IExpression substituted1 = ExprSimplifier.Substitute(exprV1V2, var1, new ExprConst(v1.ToString("f15"))); for (int j = 0; j < steps2; j++) { double v2 = step2 * j; IExpression substituted2 = ExprSimplifier.Substitute(substituted1, var2, new ExprConst(v2.ToString("f15"))); substituted2 = ExprSimplifier.Simplify(substituted2); res[n, j] = ExprDoubleSimplifier.CalcConstExpr(substituted2); } lock (progress) { progress[index]++; int steps = 0; foreach (int s in progress) { steps += s; } arg.Progress?.Report(steps / (float)steps1); } } }
public static double[,] EvalMatrixD_OneThread(AsyncArg arg, IExpression expr, DependencySpace depSpace, string[] deps, string var1, double len1, int steps1, string var2, double len2, int steps2) { expr = ExprUtils.GetCopy_Slow(expr); foreach (string dep in deps) { Complex?val = depSpace.Get(dep); if (val.HasValue) { expr = ExprSimplifier.Substitute(expr, dep, new ExprConst(val.Value.Real.ToString("f15"))); } } double[,] res = new double[steps1, steps2]; // t, x for (int n = 0; n < steps1; n++) { if (arg.Token.IsCancellationRequested) { return(null); } double v1 = len1 * n / steps1; IExpression substituted1 = ExprSimplifier.Substitute(expr, var1, new ExprConst(v1.ToString("f15"))); for (int j = 0; j < steps2; j++) { double v2 = len2 * j / steps2; IExpression substituted2 = ExprSimplifier.Substitute(substituted1, var2, new ExprConst(v2.ToString("f15"))); substituted2 = ExprSimplifier.Simplify(substituted2); res[n, j] = ExprDoubleSimplifier.CalcConstExpr(substituted2); } arg.Progress?.Report((n + 1) / (float)steps1); } return(res); }
private void DrawExpectedSolution() { SolutionInput input = BuildInput(); IExpression expr = MainParser.Parse(input.v); string[] deps = MainParser.GetDependencies(expr); double T = double.Parse(input.T); int M = int.Parse(input.t_count); int N = int.Parse(input.x_count); if (M > VISUALIZATION_HEIGHT) { M = VISUALIZATION_HEIGHT; } if (N > VISUALIZATION_WIDTH) { N = VISUALIZATION_WIDTH; } if (Dependencies.Get(MathAliases.ConvertName("chi")) == null) { Dependencies.Set(MathAliases.ConvertName("chi"), 0); } SwitchDrawButton(true); calcBar.Value = 0; var calcProgress = new Progress <double>(value => calcBar.Value = value); ShowProgress(); Task.Run(() => { AsyncArg arg = new AsyncArg(calcProgress, solveCancellation.Token); double[,] sol = MainParser.EvalMatrixD(arg, expr, Dependencies, deps, "t", T, M, "x", 2 * Math.PI, N); if (arg.Token.IsCancellationRequested) { return; } this.Dispatcher.Invoke(() => { UpdateVisualization(sol, "U(x,t)"); SwitchDrawButton(false); }); }); }
public static double[,] EvalMatrixD(AsyncArg arg, IExpression expr, DependencySpace depSpace, string[] deps, string var1, double len1, int steps1, string var2, double len2, int steps2) { expr = ExprUtils.GetCopy_Slow(expr); foreach (string dep in deps) { Complex?val = depSpace.Get(dep); if (val.HasValue) { expr = ExprSimplifier.Substitute(expr, dep, new ExprConst(val.Value.Real.ToString("f15"))); } } double[,] res = new double[steps1, steps2]; // t, x if (!ExprSimplifier.IsDependsOn(expr, var1)) { double[] xArr = EvalArrayD(expr, depSpace, deps, var2, len2, steps2); for (int j = 0; j < steps2; j++) { for (int i = 0; i < steps1; i++) { res[i, j] = xArr[j]; } } return(res); } if (!ExprSimplifier.IsDependsOn(expr, var2)) { double[] xArr = EvalArrayD(expr, depSpace, deps, var1, len1, steps1); for (int i = 0; i < steps1; i++) { for (int j = 0; j < steps2; j++) { res[i, j] = xArr[i]; } } return(res); } int[] progress = new int[Environment.ProcessorCount]; int interval = (int)Math.Ceiling(steps1 / (double)progress.Length); Parallel.For(0, progress.Length, (index) => EvalMatrixD(arg, expr, res, steps1, progress, index, var1, len1 / steps1, index * interval, Math.Min((index + 1) * interval, steps1), var2, len2 / steps2, steps2)); return(res); }
private async void drawButton_ClickAsync(object sender, RoutedEventArgs e) { if (solveCancellation != null) { SwitchDrawButton(false); return; } BuildSolver(); SwitchDrawButton(true); calcBar.Value = 0; var calcProgress = new Progress <double>(value => calcBar.Value = value); ShowProgress(); Task.Run(() => { AsyncArg asyncArg = new AsyncArg(calcProgress, solveCancellation.Token); curSolver.Solve(method, asyncArg); if (asyncArg.Token.IsCancellationRequested) { return; } this.Dispatcher.Invoke(() => { textBlock_Khi.Text = "𝜒 = " + curSolver.Chi.ToString("f4"); var eigen = FilterInfo.UpdateEigen(filterBuilder.Filter, textBlock_critical, curSolver.Parameters); Complex[] eigenvalies = eigen.Item1; int k = -1; bool isTuring = false; for (int i = 0; i < eigenvalies.Length; i++) { if (eigenvalies[i].Real > 0 || Math.Abs(eigenvalies[i].Real) < 0.005) { if (eigenvalies[i].Imaginary > 0) { k = i; isTuring = false; break; } if (Math.Abs(eigenvalies[i].Imaginary) < 0.00001) { k = i; isTuring = true; break; } } } if (k >= 0) { Complex[] eigenvector = new Complex[eigenvalies.Length]; for (int i = 0; i < eigenvector.Length; i++) { eigenvector[i] = eigen.Item2[i, k]; } int center = eigenvector.Length / 2; string v; if (isTuring) { v = SolutionInput.GenExpectedTuring( (n) => (eigenvector[center + n] + eigenvector[center - n]).Real, (n) => - (eigenvector[center + n] - eigenvector[center - n]).Imaginary, center, true, 1); } else { v = SolutionInput.GenExpectedHopf(eigenvalies[k].Imaginary, (n) => (eigenvector[center + n] + eigenvector[center - n]).Real, (n) => - (eigenvector[center + n] - eigenvector[center - n]).Imaginary, (n) => (eigenvector[center + n] + eigenvector[center - n]).Imaginary, (n) => (eigenvector[center + n] - eigenvector[center - n]).Real, center, true, 1); } foreach (UIParam param in parameters) { if (param.Name == "v") { param.Text = v; break; } } } UpdateVisualization(curSolver.Solution, "u(x,T)"); SwitchDrawButton(false); }); }); }