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); } }
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); }
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); }
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)); }
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)); }
/// <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; }
/// <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]); } }
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]); } }
/// <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); } }
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); })); }
/// <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); } } }
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]); } }
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]); } }
/// <summary> /// Clone the given vector. /// </summary> public static DenseVector Clone(DenseVector vector) { return(DenseVector.OfArray((Complex[])vector)); }
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]); } }
/// <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; }
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; } }
public void CanCreateDenseMatrix() { var vector = new DenseVector(3); var matrix = vector.CreateMatrix(2, 3); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); }
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)); }
public void CanConvertDenseVectorToArray() { var vector = new DenseVector(Data); var array = (Complex[]) vector; Assert.IsInstanceOf(typeof (Complex[]), array); CollectionAssert.AreEqual(vector, array); }
/// <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]; } }); }
/// <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); }
/// <summary> /// Set all vector elements to zero. /// </summary> public static void Clear(DenseVector vector) { var x = (Complex[])vector; Array.Clear(x, 0, x.Length); }
/// <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; }
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); } }
/// <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; }
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]); } }
/// <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); }
/// <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); }
/// <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]); } }