public void HeapSortWithDecreasingDoubleArray()
        {
            var sortedIndices = new int[10];
            Vector<Complex> values = new DenseVector(10);
            values[0] = 9;
            values[1] = 8;
            values[2] = 7;
            values[3] = 6;
            values[4] = 5;
            values[5] = 4;
            values[6] = 3;
            values[7] = 2;
            values[8] = 1;
            values[9] = 0;
            for (var i = 0; i < sortedIndices.Length; i++)
            {
                sortedIndices[i] = i;
            }

            ILUTPElementSorter.SortDoubleIndicesDecreasing(0, sortedIndices.Length - 1, sortedIndices, values);
            for (var i = 0; i < sortedIndices.Length; i++)
            {
                Assert.AreEqual(i, sortedIndices[i], "#01-" + i);
            }
        }
Пример #2
0
        public void SolveLongMatrixThrowsArgumentException()
        {
            var matrix = new SparseMatrix(3, 2);
            var input = new DenseVector(3);

            var solver = new BiCgStab();
            Assert.That(() => matrix.SolveIterative(input, solver), Throws.ArgumentException);
        }
Пример #3
0
        public void SolveWideMatrixThrowsArgumentException()
        {
            var matrix = new SparseMatrix(2, 3);
            var input = new DenseVector(2);

            var solver = new TFQMR();
            Assert.That(() => matrix.SolveIterative(input, solver), Throws.ArgumentException);
        }
Пример #4
0
        public void SolveLongMatrixThrowsArgumentException()
        {
            var matrix = new SparseMatrix(3, 2);
            var input = new DenseVector(3);

            var solver = new TFQMR();
            Assert.Throws<ArgumentException>(() => matrix.SolveIterative(input, solver));
        }
Пример #5
0
        public void SolveWideMatrixThrowsArgumentException()
        {
            var matrix = new SparseMatrix(2, 3);
            var input = new DenseVector(2);

            var solver = new GpBiCg();
            Assert.Throws<ArgumentException>(() => matrix.SolveIterative(input, solver));
        }
Пример #6
0
        /// <summary>
        /// Creates a new instance of the Vector class.
        /// </summary>
        /// <param name="data">The array to create this vector from.</param>
        /// <returns>The new <c>Vector</c>.</returns>
        protected override Vector<Complex> CreateVector(IList<Complex> data)
        {
            var vector = new DenseVector(data.Count);
            for (var index = 0; index < data.Count; index++)
            {
                vector[index] = data[index];
            }

            return vector;
        }
Пример #7
0
        /// <summary>
        /// Create standard vector.
        /// </summary>
        /// <param name="size">Size of the vector.</param>
        /// <returns>New vector.</returns>
        protected DenseVector CreateStandardBcVector(int size)
        {
            var vector = new DenseVector(size);
            for (var i = 0; i < size; i++)
            {
                vector[i] = i + 1;
            }

            return vector;
        }
        public void DetermineStatus()
        {
            var criterium = new FailureStopCriterium();
            Assert.IsNotNull(criterium, "There should be a criterium");

            var solution = new DenseVector(new[] {new Complex(3.0, 0), new Complex(2.0, 0), new Complex(1, 0)});
            var source = new DenseVector(new[] {new Complex(1001.0, 0), Complex.Zero, new Complex(2003.0, 0)});
            var residual = new DenseVector(new[] {new Complex(1.0, 0), new Complex(2.0, 0), new Complex(3, 0)});

            var status = criterium.DetermineStatus(5, solution, source, residual);
            Assert.AreEqual(IterationStatus.Continue, status, "Should be running");
        }
        public void CanAddTwoDenseVectorsUsingOperator()
        {
            var vector = new DenseVector(Data);
            var other = new DenseVector(Data);
            var result = vector + other;
            CollectionAssert.AreEqual(Data, vector, "Making sure the original vector wasn't modified.");
            CollectionAssert.AreEqual(Data, other, "Making sure the original vector wasn't modified.");

            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(Data[i]*2.0, result[i]);
            }
        }
Пример #10
0
        public void CanCreateDenseVectorFromArray()
        {
            var data = new Complex[Data.Length];
            Array.Copy(Data, data, Data.Length);
            var vector = new DenseVector(data);

            for (var i = 0; i < data.Length; i++)
            {
                Assert.AreEqual(data[i], vector[i]);
            }

            vector[0] = new Complex(10.0, 1);
            Assert.AreEqual(new Complex(10.0, 1), data[0]);
        }
        public void ApproximateReturningOldVector()
        {
            const int Size = 10;
            var newMatrix = CreateUnitMatrix(Size);
            var vector = CreateStandardBcVector(Size);

            var preconditioner = CreatePreconditioner();
            preconditioner.Initialize(newMatrix);

            var result = new DenseVector(vector.Count);
            preconditioner.Approximate(vector, result);

            CheckResult(preconditioner, newMatrix, vector, result);
        }
        public void CanMultiplyWithVector()
        {
            var matrix = TestMatrices["Singular3x3"];
            var x = new DenseVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1) });
            var y = matrix * x;

            Assert.AreEqual(matrix.RowCount, y.Count);

            for (var i = 0; i < matrix.RowCount; i++)
            {
                var ar = matrix.Row(i);
                var dot = ar * x;
                Assert.AreEqual(dot, y[i]);
            }
        }
Пример #13
0
        /// <summary>
        /// Check the result.
        /// </summary>
        /// <param name="preconditioner">Specific preconditioner.</param>
        /// <param name="matrix">Source matrix.</param>
        /// <param name="vector">Initial vector.</param>
        /// <param name="result">Result vector.</param>
        protected override void CheckResult(IPreconditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result)
        {
            Assert.AreEqual(typeof(Diagonal), preconditioner.GetType(), "#01");

            // Compute M * result = product
            // compare vector and product. Should be equal
            var product = new DenseVector(result.Count);
            matrix.Multiply(result, product);

            for (var i = 0; i < product.Count; i++)
            {
                Assert.IsTrue(vector[i].Real.AlmostEqual(product[i].Real, -Epsilon.Magnitude()), "#02-" + i);
                Assert.IsTrue(vector[i].Imaginary.AlmostEqual(product[i].Imaginary, -Epsilon.Magnitude()), "#03-" + i);
            }
        }
Пример #14
0
        public void FFT2dInverse()
        {
            dmResultComplex = new MathNet.Numerics.LinearAlgebra.Complex.DenseMatrix(dmComplexInput.RowCount,
                                                                                     dmComplexInput.ColumnCount, new Complex[] { new Complex(0.0d, 0.0d) });


            IEnumerable <Tuple <int, Vector <Complex> > > columnEnumerator =
                dmComplexInput.EnumerateColumnsIndexed();

            foreach (Tuple <int, Vector <Complex> > theColumnTuple in columnEnumerator)
            {
                Vector <Complex> theVector      = theColumnTuple.Item2;
                Complex[]        theVectorArray = theVector.ToArray();
                Fourier.Inverse(theVectorArray);
                Vector <Complex> theVectorSpectrum = new MathNet.Numerics.LinearAlgebra.Complex.DenseVector(theVectorArray);
                dmResultComplex.SetColumn(theColumnTuple.Item1, theVectorSpectrum);
            }

            IEnumerable <Tuple <int, Vector <Complex> > > rowEnumerator =
                dmResultComplex.EnumerateRowsIndexed();

            foreach (Tuple <int, Vector <Complex> > theRowTuple in rowEnumerator)
            {
                Vector <Complex> theVector      = theRowTuple.Item2;
                Complex[]        theVectorArray = theVector.ToArray();
                Fourier.Inverse(theVectorArray);
                Vector <Complex> theVectorSpectrum = new MathNet.Numerics.LinearAlgebra.Complex.DenseVector(theVectorArray);
                dmResultComplex.SetRow(theRowTuple.Item1, theVectorSpectrum);
            }

            dmOutputReal = MathNet.Numerics.LinearAlgebra.Double.DenseMatrix.Create(dmResultComplex.RowCount, dmResultComplex.ColumnCount, new Func <int, int, double>(
                                                                                        (row, column) =>
            {
                return(dmResultComplex[row, column].Real);
            }));
            dmOutputImaginary = MathNet.Numerics.LinearAlgebra.Double.DenseMatrix.Create(dmResultComplex.RowCount, dmResultComplex.ColumnCount, new Func <int, int, double>(
                                                                                             (row, column) =>
            {
                return(dmResultComplex[row, column].Imaginary);
            }));
        }
Пример #15
0
        /// <summary>
        /// Multiplies this matrix with another matrix and places the results into the result matrix.
        /// </summary>
        /// <param name="other">The matrix to multiply with.</param>
        /// <param name="result">The result of the multiplication.</param>
        protected override void DoMultiply(Matrix<Complex> other, Matrix<Complex> result)
        {
            var columnVector = new DenseVector(other.RowCount);
            for (var row = 0; row < RowCount; row++)
            {
                // Get the begin / end index for the current row
                var startIndex = _rowIndex[row];
                var endIndex = row < _rowIndex.Length - 1 ? _rowIndex[row + 1] : NonZerosCount;
                if (startIndex == endIndex)
                {
                    continue;
                }

                for (var column = 0; column < other.ColumnCount; column++)
                {
                    // Multiply row of matrix A on column of matrix B
                    other.Column(column, columnVector);

                    var sum = Complex.Zero;
                    for (var index = startIndex; index < endIndex; index++)
                    {
                        sum += _nonZeroValues[index] * columnVector[_columnIndices[index]];
                    }

                    result.At(row, column, sum);
                }
            }
        }
Пример #16
0
        public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column)
        {
            var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column);
            var matrixACopy = matrixA.Clone();
            var factorSvd = matrixA.Svd();
            var vectorb = MatrixLoader.GenerateRandomDenseVector(row);
            var vectorbCopy = vectorb.Clone();
            var resultx = new DenseVector(column);
            factorSvd.Solve(vectorb, resultx);

            var matrixBReconstruct = matrixA*resultx;

            // Check the reconstruction.
            for (var i = 0; i < vectorb.Count; i++)
            {
                AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 9);
            }

            // Make sure A didn't change.
            for (var i = 0; i < matrixA.RowCount; i++)
            {
                for (var j = 0; j < matrixA.ColumnCount; j++)
                {
                    Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
                }
            }

            // Make sure b didn't change.
            for (var i = 0; i < vectorb.Count; i++)
            {
                Assert.AreEqual(vectorbCopy[i], vectorb[i]);
            }
        }
Пример #17
0
        public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order)
        {
            var matrixA = Matrix<Complex>.Build.Random(order, order, 1);
            var matrixACopy = matrixA.Clone();
            var factorQR = matrixA.QR(QRMethod.Thin);
            var vectorb = Vector<Complex>.Build.Random(order, 1);
            var vectorbCopy = vectorb.Clone();
            var resultx = new DenseVector(order);
            factorQR.Solve(vectorb, resultx);

            Assert.AreEqual(vectorb.Count, resultx.Count);

            var matrixBReconstruct = matrixA * resultx;

            // Check the reconstruction.
            for (var i = 0; i < vectorb.Count; i++)
            {
                AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 10);
            }

            // Make sure A didn't change.
            for (var i = 0; i < matrixA.RowCount; i++)
            {
                for (var j = 0; j < matrixA.ColumnCount; j++)
                {
                    Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
                }
            }

            // Make sure b didn't change.
            for (var i = 0; i < vectorb.Count; i++)
            {
                Assert.AreEqual(vectorbCopy[i], vectorb[i]);
            }
        }
Пример #18
0
 /// <summary>
 /// Clone the given vector.
 /// </summary>
 public static DenseVector Clone(DenseVector vector)
 {
     return(DenseVector.OfArray((Complex[])vector));
 }
Пример #19
0
 public void CanCallUnaryNegationOperatorOnDenseVector()
 {
     var vector = new DenseVector(Data);
     var other = -vector;
     for (var i = 0; i < Data.Length; i++)
     {
         Assert.AreEqual(-Data[i], other[i]);
     }
 }
Пример #20
0
        /// <summary>
        /// Outer product of two vectors
        /// </summary>
        /// <param name="u">First vector</param>
        /// <param name="v">Second vector</param>
        /// <returns>Matrix M[i,j] = u[i]*v[j] </returns>
        /// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception> 
        /// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception> 
        public static DenseMatrix OuterProduct(DenseVector u, DenseVector v)
        {
            if (u == null)
            {
                throw new ArgumentNullException("u");
            }

            if (v == null)
            {
                throw new ArgumentNullException("v");
            }

            var matrix = new DenseMatrix(u.Count, v.Count);
            CommonParallel.For(
                0, 
                u.Count, 
                i =>
                {
                    for (var j = 0; j < v.Count; j++)
                    {
                        matrix.At(i, j, u._values[i] * v._values[j]);
                    }
                });
            return matrix;
        }
Пример #21
0
        private void cbed_DoWork(object sender, DoWorkEventArgs e)
        {
            //波数を計算
            var kvac = UniversalConstants.Convert.EnergyToElectronWaveNumber(AccVoltage);
            //U0を計算
            var u0 = getU(AccVoltage, (0, 0, 0), 0).Real.Real;
            //k0ベクトルを計算
            var vecK0 = getVecK0(kvac, u0);

            //計算対象のg-Vectorsを決める。indexが小さく、かつsg(励起誤差)の小さいg-vectorを抽出する
            Beams = Find_gVectors(BaseRotation, vecK0);

            //入射面での波動関数を定義
            var psi0 = DVec.OfArray(Enumerable.Range(0, Beams.Length).ToList().Select(g => g == 0 ? One : 0).ToArray());

            //ポテンシャルマトリックスを取得
            uDictionary = new Dictionary <int, (Complex, Complex)>();
            var factorMatrix = getPotentialMatrix(Beams);
            //有効なRotationだけを選択
            var beamRotationsValid = new List <Matrix3D>();

            for (int i = 0; i < BeamRotations.Length; i++)
            {
                if (BeamRotations[i] != null)
                {
                    beamRotationsValid.Add(BeamRotations[i]);
                }
            }
            RotationArrayValidLength = beamRotationsValid.Count;
            //rotationsValidに対応するdiskValidを定義
            var diskValid = new List <Complex[][]>();
            //進捗状況報告用の各種定数を初期化
            int count = 0, total = beamRotationsValid.Count;
            var sw   = new Stopwatch();
            var bLen = Beams.Length;

            //ローカル関数. RotationsValid(の一部)を対象にdisks[t][g]を計算し、diskValidに追加し、最後にかかった時間を返す
            long func(Solver solver, int thread, bool speedTest = true)
            {
                if (solver == Solver.MKL)
                {
                    MathNet.Numerics.Control.TryUseNativeMKL();
                }
                else if (solver == Solver.Managed)
                {
                    MathNet.Numerics.Control.UseManaged();
                }

                var reportString   = (solver == Solver.MKL ? "MKL" : "EIG") + thread.ToString();
                var beamRotationsP = beamRotationsValid.AsParallel().WithDegreeOfParallelism(thread);

                if (speedTest)//スピードテストのとき
                {
                    var n = Math.Min(bLen < 64 ? 512 : bLen < 128 ? 256 : bLen < 256 ? 128 : bLen < 512 ? 64 : 32, beamRotationsValid.Count);
                    if (n == 0)
                    {
                        return(0);
                    }
                    beamRotationsP = beamRotationsValid.Take(n).ToArray().AsParallel().WithDegreeOfParallelism(thread);
                    beamRotationsValid.RemoveRange(0, n);
                }
                sw.Restart();
                //disks[t][g]を計算.
                var disk = beamRotationsP.Select(beamRotation =>
                {
                    if (bwCBED.CancellationPending)
                    {
                        return(null);
                    }
                    var rotZ  = beamRotation * zNorm;
                    var coeff = 1.0 / rotZ.Z; // = 1/cosTau

                    var vecK0 = getVecK0(kvac, u0, beamRotation);

                    var beams           = reset_gVectors(Beams, BaseRotation, vecK0); //BeamsのPやQをリセット
                    var potentialMatrix = getEigenProblemMatrix(beams, factorMatrix); //ポテンシャル行列をセット
                    Complex[][] result;

                    //ポテンシャル行列の固有値、固有ベクトルを取得し、resultに格納
                    if (solver == Solver.Eigen)
                    {
                        result = NativeWrapper.CBEDSolver(potentialMatrix, psi0.ToArray(), Thicknesses, coeff);
                    }
                    else
                    {
                        var evd   = DMat.OfArray(potentialMatrix).Evd(Symmetricity.Unknown);
                        var alpha = evd.EigenVectors.Inverse() * psi0;
                        result    = Thicknesses.Select(t =>
                        {
                            //ガンマの対称行列×アルファを作成
                            var gammmaAlpha = DVec.OfArray(evd.EigenValues.Select((ev, i) => Exp(TwoPiI * ev * t * coeff) * alpha[i]).ToArray());
                            //深さtにおけるψを求める
                            return((evd.EigenVectors * gammmaAlpha).ToArray());
                        }).ToArray();
                    }
                    bwCBED.ReportProgress(Interlocked.Increment(ref count), reportString); //進捗状況を報告
                    return(result);
                }).ToArray();

                diskValid.AddRange(disk); //diskをdiskValidに加える
                return(sw.ElapsedTicks);  //経過時間を返す
            }

            //ここからチューニング&本番

            if ((Solver)((object[])e.Argument)[0] == Solver.Auto)
            {
                if (EigenEnabled && bLen < 512 && func(Solver.Eigen, Environment.ProcessorCount) < func(Solver.MKL, 8))//eigenの方が早い場合
                {
                    func(Solver.Eigen, Environment.ProcessorCount, false);
                }
                else if (Environment.ProcessorCount <= 4)//MKLでコア数が4以下の場合
                {
                    func(Solver.MKL, Environment.ProcessorCount, false);
                }
                else//コア数4,6,8,10,12,14,16を試して最速のもので
                {
                    var list = new SortedList <long, int>();
                    foreach (var t in new[] { 4, 6, 8, 10, 12, 14, 16 })
                    {
                        if (t <= Environment.ProcessorCount)
                        {
                            list.Add(func(Solver.MKL, t), t);
                        }
                    }
                    func(Solver.MKL, list.Values[0], false);
                }
            }
            else
            {
                func((Solver)((object[])e.Argument)[0], (int)((object[])e.Argument)[1], false);
            }


            //無効なRotationも考慮してdisk[RotationIndex][Z_index][G_index]を構築
            var disk = new List <Complex[][]>();

            for (int i = 0, j = 0; i < BeamRotations.Length; i++)
            {
                disk.Add(BeamRotations[i] != null ? diskValid[j++] : null);
            }

            //diskをコンパイルする
            Disks = new CBED_Disk[Thicknesses.Length][];
            Parallel.For(0, Thicknesses.Length, t =>
            {
                Disks[t] = new CBED_Disk[Beams.Length];
                for (int g = 0; g < Beams.Length; g++)
                {
                    var intensity = new double[BeamRotations.Length];
                    for (int r = 0; r < BeamRotations.Length; r++)
                    {
                        if (disk[r] != null)
                        {
                            intensity[r] = disk[r][t][g].Magnitude2();
                        }
                    }

                    Disks[t][g] = new CBED_Disk(new[] { Beams[g].H, Beams[g].K, Beams[g].L }, Beams[g].Vec, Thicknesses[t], intensity);
                }
            });

            if (bwCBED.CancellationPending)
            {
                e.Cancel = true;
            }
        }
Пример #22
0
 public void CanCreateDenseMatrix()
 {
     var vector = new DenseVector(3);
     var matrix = vector.CreateMatrix(2, 3);
     Assert.AreEqual(2, matrix.RowCount);
     Assert.AreEqual(3, matrix.ColumnCount);
 }
Пример #23
0
        public void CanCreateDenseVectorFromAnotherDenseVector()
        {
            var vector = new DenseVector(Data);
            var other = DenseVector.OfVector(vector);

            Assert.AreNotSame(vector, other);
            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(vector[i], other[i]);
            }
        }
 public void MultiplyWithVectorIntoLargerResultThrowsArgumentException()
 {
     var matrix = TestMatrices["Singular3x3"];
     var x = new DenseVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1) });
     Vector<Complex> y = new DenseVector(4);
     Assert.Throws<ArgumentException>(() => matrix.Multiply(x, y));
 }
Пример #25
0
 public void CanConvertDenseVectorToArray()
 {
     var vector = new DenseVector(Data);
     var array = (Complex[]) vector;
     Assert.IsInstanceOf(typeof (Complex[]), array);
     CollectionAssert.AreEqual(vector, array);
 }
Пример #26
0
        /// <summary>
        /// Compute sum of scaled vectors, target = alpha * x + beta * y + z.
        /// </summary>
        public static void Add(Complex alpha, DenseVector x, Complex beta, DenseVector y, DenseVector z,
                               DenseVector target)
        {
            var vx = (Complex[])x;
            var vy = (Complex[])y;
            var vz = (Complex[])z;
            var vt = (Complex[])target;

            int length = vx.Length;

            CommonParallel.For(0, length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    vt[i] = alpha * vx[i] + beta * vy[i] + vz[i];
                }
            });
        }
Пример #27
0
 /// <summary>
 /// Converts the string representation of a complex dense vector to double-precision dense vector equivalent.
 /// A return value indicates whether the conversion succeeded or failed.
 /// </summary>
 /// <param name="value">
 /// A string containing a complex vector to convert.
 /// </param>
 /// <param name="result">
 /// The parsed value.
 /// </param>
 /// <returns>
 /// If the conversion succeeds, the result will contain a complex number equivalent to value.
 /// Otherwise the result will be <c>null</c>.
 /// </returns>
 public static bool TryParse(string value, out DenseVector result)
 {
     return TryParse(value, null, out result);
 }
Пример #28
0
        /// <summary>
        /// Set all vector elements to zero.
        /// </summary>
        public static void Clear(DenseVector vector)
        {
            var x = (Complex[])vector;

            Array.Clear(x, 0, x.Length);
        }
Пример #29
0
        /// <summary>
        /// Returns a negated vector.
        /// </summary>
        /// <returns>The negated vector.</returns>
        /// <remarks>Added as an alternative to the unary negation operator.</remarks>
        public override Vector<Complex> Negate()
        {
            var result = new DenseVector(_length);
            CommonParallel.For(
                0, 
                _values.Length,
                index => result[index] = -_values[index]);

            return result;
        }
Пример #30
0
        public void CanDivideDenseVectorByComplexUsingOperators()
        {
            var vector = new DenseVector(Data);
            vector = vector/new Complex(2.0, 1);

            for (var i = 0; i < Data.Length; i++)
            {
                AssertHelpers.AlmostEqual(Data[i]/new Complex(2.0, 1), vector[i], 14);
            }

            vector = vector/1.0;
            for (var i = 0; i < Data.Length; i++)
            {
                AssertHelpers.AlmostEqual(Data[i]/new Complex(2.0, 1), vector[i], 14);
            }
        }
Пример #31
0
        /// <summary>
        /// Creates a vector containing specified elements.
        /// </summary>
        /// <param name="index">The first element to begin copying from.</param>
        /// <param name="length">The number of elements to copy.</param>
        /// <returns>A vector containing a copy of the specified elements.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><list><item>If <paramref name="index"/> is not positive or
        /// greater than or equal to the size of the vector.</item>
        /// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item>
        /// </list></exception>
        /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
        public override Vector<Complex> SubVector(int index, int length)
        {
            if (index < 0 || index >= _length)
            {
                throw new ArgumentOutOfRangeException("index");
            }

            if (length <= 0)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            if (index + length > _length)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            var result = new DenseVector(length);

            CommonParallel.For(
                index, 
                index + length,
                i => result._values[i - index] = _values[i]);
            return result;
        }
Пример #32
0
        public void CanMultiplyDenseVectorByScalarUsingOperators()
        {
            var vector = new DenseVector(Data);
            vector = vector*new Complex(2.0, 1);

            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(Data[i]*new Complex(2.0, 1), vector[i]);
            }

            vector = vector*1.0;
            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(Data[i]*new Complex(2.0, 1), vector[i]);
            }

            vector = new DenseVector(Data);
            vector = new Complex(2.0, 1)*vector;

            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(Data[i]*new Complex(2.0, 1), vector[i]);
            }

            vector = 1.0*vector;
            for (var i = 0; i < Data.Length; i++)
            {
                Assert.AreEqual(Data[i]*new Complex(2.0, 1), vector[i]);
            }
        }
Пример #33
0
 /// <summary>
 /// Outer product of this and another vector.
 /// </summary>
 /// <param name="v">The vector to operate on.</param>
 /// <returns>
 /// Matrix M[i,j] = this[i] * v[j].
 /// </returns>
 /// <seealso cref="OuterProduct(DenseVector, DenseVector)"/>
 public Matrix<Complex> OuterProduct(DenseVector v)
 {
     return OuterProduct(this, v);
 }
Пример #34
0
        /// <summary>
        /// 平行ビームの電子回折計算
        /// </summary>
        /// <param name="maxNumOfBloch"></param>
        /// <param name="voltage"></param>
        /// <param name="rotation"></param>
        /// <param name="thickness"></param>
        /// <returns></returns>
        public Beam[] GetDifractedBeamAmpriltudes(int maxNumOfBloch, double voltage, Matrix3D rotation, double thickness)
        {
            var useEigen = !MathNet.Numerics.Control.TryUseNativeMKL();

            if (AccVoltage != voltage)
            {
                uDictionary = new Dictionary <int, (Complex, Complex)>();
            }

            //波数を計算
            var k_vac = UniversalConstants.Convert.EnergyToElectronWaveNumber(voltage);
            //U0を計算
            var u0    = getU(voltage, (0, 0, 0), 0).Real.Real;
            var vecK0 = getVecK0(k_vac, u0);

            if (MaxNumOfBloch != maxNumOfBloch || AccVoltage != voltage || EigenValues == null || EigenVectors == null || !rotation.Equals(BaseRotation))
            {
                MaxNumOfBloch = maxNumOfBloch;
                AccVoltage    = voltage;
                BaseRotation  = new Matrix3D(rotation);
                Thickness     = thickness;

                //計算対象のg-Vectorsを決める。
                Beams = Find_gVectors(BaseRotation, vecK0);

                if (Beams == null || Beams.Length == 0)
                {
                    return(new Beam[0]);
                }

                var potentialMatrix = getEigenProblemMatrix(Beams);

                //A行列に関する固有値、固有ベクトルを取得
                if (useEigen)
                {
                    (EigenValues, EigenVectors) = NativeWrapper.EigenSolver(potentialMatrix);
                }
                else
                {
                    var evd = DMat.OfArray(potentialMatrix).Evd(Symmetricity.Asymmetric);
                    EigenValues  = evd.EigenValues.AsArray();
                    EigenVectors = (DMat)evd.EigenVectors;
                }

                //(EigenVectors, EigenValues) = RefineEigenProblem(DMat.OfArray(potentialMatrix), (DMat)evd.EigenVectors, evd.EigenValues.ToArray());
            }
            int len = EigenValues.Count();

            var psi0 = DVec.OfArray(new Complex[len]);//入射面での波動関数を定義

            psi0[0] = 1;

            var alpha = EigenVectors.Inverse() * psi0;//アルファベクトルを求める

            //ガンマの対称行列×アルファを作成
            var gamma_alpha = new DVec(Enumerable.Range(0, len).Select(n => Exp(TwoPiI * EigenValues[n] * thickness) * alpha[n]).ToArray());

            //出射面での境界条件を考慮した位相にするため、以下の1行を追加 (20190827)
            var p = new DiagonalMatrix(len, len, Beams.Select(b => Exp(PiI * (b.P - 2 * k_vac * Surface.Z) * thickness)).ToArray());
            //var p = new DiagonalMatrix(len, len, Beams.Select(b => new Complex(1, 0)).ToArray());

            //深さZにおけるψを求める
            var psi_atZ = p * EigenVectors * gamma_alpha;

            for (int i = 0; i < Beams.Length && i < len; i++)
            {
                Beams[i].Psi = psi_atZ[i];
            }

            return(Beams);
        }
Пример #35
0
        /// <summary>
        /// Converts the string representation of a complex dense vector to double-precision dense vector equivalent.
        /// A return value indicates whether the conversion succeeded or failed.
        /// </summary>
        /// <param name="value">
        /// A string containing a complex vector to convert.
        /// </param>
        /// <param name="formatProvider">
        /// An <see cref="IFormatProvider"/> that supplies culture-specific formatting information about value.
        /// </param>
        /// <param name="result">
        /// The parsed value.
        /// </param>
        /// <returns>
        /// If the conversion succeeds, the result will contain a complex number equivalent to value.
        /// Otherwise the result will be <c>null</c>.
        /// </returns>
        public static bool TryParse(string value, IFormatProvider formatProvider, out DenseVector result)
        {
            bool ret;
            try
            {
                result = Parse(value, formatProvider);
                ret = true;
            }
            catch (ArgumentNullException)
            {
                result = null;
                ret = false;
            }
            catch (FormatException)
            {
                result = null;
                ret = false;
            }

            return ret;
        }
        public void CanTransposeThisAndMultiplyWithVectorIntoResultWhenUpdatingInputArgument()
        {
            var matrix = TestMatrices["Singular3x3"];
            var x = new DenseVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1) });
            var y = x;
            matrix.TransposeThisAndMultiply(x, x);

            Assert.AreSame(y, x);

            y = new DenseVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1) });
            for (var j = 0; j < matrix.ColumnCount; j++)
            {
                var ar = matrix.Column(j);
                var dot = ar * y;
                Assert.AreEqual(dot, x[j]);
            }
        }