Пример #1
0
        /// <summary>
        /// Converts the given trigonometric representation of a complex number to its algebraic representation.
        /// </summary>
        /// <param name="trygonometric">Trygonometric representation of the complex number.</param>
        /// <returns>Algebraic representation of the complex number.</returns>
        public static ComplexAlgebraic toAlgebraic(ComplexTrigonometric trygonometric)
        {
            double re = trygonometric.modulus * Math.Cos(trygonometric.arc);
            double im = trygonometric.modulus * Math.Sin(trygonometric.arc);

            return(new ComplexAlgebraic(re, im, trygonometric.root));
        }
Пример #2
0
        /// <summary>
        /// Performs roots calculations for the given list of input complex numbers.
        /// </summary>
        /// <param name="inputs">List of input numbers.</param>
        /// <param name="threadCount">Number of threads to be used for calculations (min. 1, max. 64, default 1).</param>
        /// <param name="lib">Library type that should be used for the main part of the calculation process.</param>
        /// <param name="loggerTextBox">Reference to logging console.</param>
        /// <returns>Presentation of all results corresponding to the given input list.</returns>
        public static ResultsPresentation calculateRoots(List <ComplexAlgebraic> inputs, int threadCount, LibraryType lib, RichTextBox loggerTextBox)
        {
            //set default thread count if it's out of range
            if (threadCount < 1 || threadCount > 64)
            {
                threadCount = 1;
            }

            //create empty list of jobs
            //for each thread one job will be created
            List <CalculationJob> jobs = new List <CalculationJob>();

            //number of inputs passed to one job
            long inputsPerJob = inputs.LongCount() / threadCount;

            //distribute inputs to all jobs equaly
            //the remaining inputs are passed to the last job
            IEnumerator inputsEnumerator = inputs.GetEnumerator();

            for (int i = 0; i < threadCount; i++)
            {
                CalculationJob job = new CalculationJob();
                jobs.Add(job);

                //pass the remaining inputs to the las job
                if (i == threadCount - 1)
                {
                    while (inputsEnumerator.MoveNext())
                    {
                        jobs.Last().inputs.Add((ComplexAlgebraic)inputsEnumerator.Current);
                    }
                }

                //set list of inputs for current job
                for (long j = 0; j < inputsPerJob && inputsEnumerator.MoveNext(); j++)
                {
                    jobs.ElementAt(i).inputs.Add((ComplexAlgebraic)inputsEnumerator.Current);
                }
            }

            //define the calculation task for each thread
            jobs.ForEach(job =>
            {
                job.thread = new Thread(() =>
                {
                    job.inputs.ForEach(i =>
                    {
                        //unsafe - pointers are in use
                        unsafe
                        {
                            //presentation of results fora single input
                            SingleResultPresentation resultPresentation = new SingleResultPresentation();

                            //stores real and imaginary part of each resulting number, so the size is 2 * root
                            double[] results = new double[i.root * 2];

                            //fixed - prevent GC from removing the pointer to array
                            fixed(double *resultsPtr = &results[0])
                            {
                                //convert the input to its trigonometric representation
                                ComplexTrigonometric inputTrig = toTrygonometric(i);

                                //perform calculation using the chosen library
                                if (LibraryType.ASM.Equals(lib))
                                {
                                    calculateRootsAsm(inputTrig.modulus, inputTrig.arc, inputTrig.root, resultsPtr);
                                }
                                else
                                {
                                    calculateRootsCpp(inputTrig.modulus, inputTrig.arc, inputTrig.root, resultsPtr);
                                }

                                //convert results to desired representation
                                resultPresentation.input = i;
                                for (int j = 0; j < i.root * 2 - 1; j += 2)
                                {
                                    resultPresentation.results.Add(new ComplexRootResult(
                                                                       Math.Round(resultsPtr[j], 6),
                                                                       Math.Round(resultsPtr[j + 1], 6)));
                                }

                                //add results for the current number to the job's result list
                                job.resultPresenations.Add(resultPresentation);
                            }
                        }
                    });
                });
            });

            loggerTextBox.AppendText("Worker threads have benn initialized.\n");
            loggerTextBox.AppendText("Pleas wait... Results are beeing calculated...\n");

            //start calculation timer
            Stopwatch calculationTimeWatch = new Stopwatch();

            calculationTimeWatch.Start();

            //start all threads
            jobs.ForEach(job => job.thread.Start());

            //synchronize threads
            jobs.ForEach(job => job.thread.Join());

            //get calculation time
            calculationTimeWatch.Stop();
            double calculationDurationMS = ((double)calculationTimeWatch.ElapsedTicks) / (Stopwatch.Frequency) * 1000;

            loggerTextBox.AppendText("Results have been calculated successfully.\n");
            loggerTextBox.AppendText("Calculation duration (ms): " + calculationDurationMS + "\n");

            //join results from each job to one list
            List <SingleResultPresentation> resultPresentations = new List <SingleResultPresentation>();

            jobs.ForEach(job => resultPresentations.AddRange(job.resultPresenations));

            return(new ResultsPresentation(resultPresentations, calculationDurationMS));
        }