Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
                });
            });
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
                });
            });
        }