Ejemplo n.º 1
0
 public static Vector operator -(Vector vector, double val)
 {
     EnsureValid(vector);
     var v = new Vector(vector.NRows);
     Parallel.For(0, v.NRows, i => v[i] = vector[i] - val);
     return v;
 }
Ejemplo n.º 2
0
        public static Vector operator +(Vector target, Vector source)
        {
            EnsureValid(source, "Source vector");
            EnsureValid(target, "Target vector");
            EnsureCompatible(target, source);

            var v = new Vector(target.NRows);
            Parallel.For(0, v.NRows, i => v[i] = target[i] + source[i]);
            return v;
        }
Ejemplo n.º 3
0
 public static bool AreCompatible(Vector v1, Vector v2)
 {
     EnsureValid(v1, "Vector 1");
     EnsureValid(v2, "Vector 2");
     return v1.NRows == v2.NRows;
 }
Ejemplo n.º 4
0
 private static void EnsureValid(Vector v, string name = "Vector")
 {
     if (!v.IsValid())
         throw new ArgumentException($"{name} is not initialized");
 }
Ejemplo n.º 5
0
 private static void EnsureCompatible(Vector v1, Vector v2)
 {
     if (!AreCompatible(v1, v2))
         throw new ArgumentException("Vectors are not compatible");
 }
Ejemplo n.º 6
0
 public Vector Sqrt()
 {
     EnsureValid(this);
     var v = new Vector(NRows);
     Parallel.For(0, NRows, i => v[i] = Math.Sqrt(this.Elements[i]));
     return v;
 }
Ejemplo n.º 7
0
        public Vector ElementDiv(Vector target, Vector source)
        {
            EnsureValid(source, "Source vector");
            EnsureValid(target, "Target vector");
            EnsureCompatible(target, source);

            var v = new Vector(target.NRows);
            Parallel.For(0, NRows, i => v[i] = target[i] / source[i]);
            return v;
        }
Ejemplo n.º 8
0
 public Vector Sqr()
 {
     EnsureValid(this);
     var v = new Vector(NRows);
     Parallel.For(0, this.NRows, i => v[i] = this.Elements[i] * this.Elements[i]);
     return v;
 }
Ejemplo n.º 9
0
 public void MakeTridiagonal(Matrix a, Vector d, Vector e)
 {
     int num1 = a.m;
     if (a.m != a.n)
         throw new ArgumentException("Matrix to tridiagonalize must be square");
     if (!a.IsSymmetric)
         throw new ArgumentException("Can only tridiagonalise symmetric matrix");
     var numArray1 = new double[this.M * this.N];
     for (int index = 0; index < this.M * this.N; ++index)
         numArray1[index] = a.Elements[index / this.M, index % this.N];
     var elements1 = d.Elements;
     var elements2 = e.Elements;
     for (int index1 = num1 - 1; index1 > 0; --index1)
     {
         int num2 = index1 - 1;
         double d1 = 0.0;
         double num3 = 0.0;
         if (num2 > 0)
         {
             for (int index2 = 0; index2 <= num2; ++index2)
                 num3 += Math.Abs(numArray1[index1 + index2 * num1]);
             if (num3 == 0.0)
             {
                 elements2[index1] = numArray1[index1 + num2 * num1];
             }
             else
             {
                 for (int index2 = 0; index2 <= num2; ++index2)
                 {
                     numArray1[index1 + index2 * num1] /= num3;
                     d1 += numArray1[index1 + index2 * num1] * numArray1[index1 + index2 * num1];
                 }
                 double num4 = numArray1[index1 + num2 * num1];
                 double num5 = num4 < 0.0 ? Math.Sqrt(d1) : -Math.Sqrt(d1);
                 elements2[index1] = num3 * num5;
                 d1 -= num4 * num5;
                 numArray1[index1 + num2 * num1] = num4 - num5;
                 double num6 = 0.0;
                 for (int index2 = 0; index2 <= num2; ++index2)
                 {
                     numArray1[index2 + index1 * num1] = numArray1[index1 + index2 * num1] / d1;
                     double num7 = 0.0;
                     for (int index3 = 0; index3 <= index2; ++index3)
                         num7 += numArray1[index2 + index3 * num1] * numArray1[index1 + index3 * num1];
                     for (int index3 = index2 + 1; index3 <= num2; ++index3)
                         num7 += numArray1[index3 + index2 * num1] * numArray1[index1 + index3 * num1];
                     elements2[index2] = num7 / d1;
                     num6 += elements2[index2] * numArray1[index1 + index2 * num1];
                 }
                 double num8 = num6 / (d1 + d1);
                 for (int index2 = 0; index2 <= num2; ++index2)
                 {
                     double num7 = numArray1[index1 + index2 * num1];
                     double num9;
                     elements2[index2] = num9 = elements2[index2] - num8 * num7;
                     for (int index3 = 0; index3 <= index2; ++index3)
                         numArray1[index2 + index3 * num1] -= num7 * elements2[index3] + num9 * numArray1[index1 + index3 * num1];
                 }
             }
         }
         else
             elements2[index1] = numArray1[index1 + num2 * num1];
         elements1[index1] = d1;
     }
     elements1[0] = 0.0;
     elements2[0] = 0.0;
     for (int index1 = 0; index1 < num1; ++index1)
     {
         int num2 = index1 - 1;
         if (elements1[index1] != 0.0)
         {
             for (int index2 = 0; index2 <= num2; ++index2)
             {
                 double num3 = 0.0;
                 for (int index3 = 0; index3 <= num2; ++index3)
                     num3 += numArray1[index1 + index3 * num1] * numArray1[index3 + index2 * num1];
                 for (int index3 = 0; index3 <= num2; ++index3)
                     numArray1[index3 + index2 * num1] -= num3 * numArray1[index3 + index1 * num1];
             }
         }
         elements1[index1] = numArray1[index1 + index1 * num1];
         numArray1[index1 + index1 * num1] = 1.0;
         for (int index2 = 0; index2 <= num2; ++index2)
         {
             double[] numArray2 = numArray1;
             int index3 = index2 + index1 * num1;
             double[] numArray3 = numArray1;
             int index4 = index1 + index2 * num1;
             double num3 = 0.0;
             double num4 = 0.0;
             numArray3[index4] = num3;
             double num5 = num4;
             numArray2[index3] = num5;
         }
     }
     for (int index = 0; index < this.M * this.N; ++index)
         a.Elements[index / this.M, index % this.N] = numArray1[index];
 }
Ejemplo n.º 10
0
 public Matrix EigenVectors(Vector eigenValues)
 {
     if (!this.IsSymmetric)
         throw new NotImplementedException("Not yet implemented for non-symmetric matrix");
     var matrix = new Matrix(this.Rows, this.Cols);
     for (int index1 = 0; index1 < this.Rows; ++index1)
         for (int index2 = 0; index2 < this.Cols; ++index2)
             matrix[index1, index2] = this[index1, index2];
     eigenValues.ResizeTo(this.Rows);
     var e = new Vector(this.Rows);
     MakeTridiagonal(matrix, eigenValues, e);
     MakeEigenVectors(eigenValues, e, matrix);
     EigenSort(matrix, eigenValues);
     return matrix;
 }
Ejemplo n.º 11
0
 public void EigenSort(Matrix eigenVectors, Vector eigenValues)
 {
     int rows = eigenVectors.Rows;
     double[] numArray = new double[rows * rows];
     for (int index = 0; index < rows * rows; ++index)
         numArray[index] = eigenVectors.Elements[index / rows, index % rows];
     double[] elements = eigenValues.Elements;
     for (int index1 = 0; index1 < rows; ++index1)
     {
         int index2 = index1;
         double num1 = elements[index1];
         for (int index3 = index1 + 1; index3 < rows; ++index3)
         {
             if (elements[index3] >= num1)
             {
                 index2 = index3;
                 num1 = elements[index3];
             }
         }
         if (index2 != index1)
         {
             elements[index2] = elements[index1];
             elements[index1] = num1;
             for (int index3 = 0; index3 < rows; ++index3)
             {
                 double num2 = numArray[index3 + index1 * rows];
                 numArray[index3 + index1 * rows] = numArray[index3 + index2 * rows];
                 numArray[index3 + index2 * rows] = num2;
             }
         }
     }
     for (int index = 0; index < rows * rows; ++index)
         eigenVectors.Elements[index / rows, index % rows] = numArray[index];
 }
Ejemplo n.º 12
0
 public void MakeEigenVectors(Vector d, Vector e, Matrix z)
 {
     int rows = z.Rows;
     double[] elements1 = d.Elements;
     double[] elements2 = e.Elements;
     double[] numArray = new double[rows * rows];
     for (int index = 0; index < rows * rows; ++index)
         numArray[index] = z.Elements[index / rows, index % rows];
     for (int index = 1; index < rows; ++index)
         elements2[index - 1] = elements2[index];
     elements2[rows - 1] = 0.0;
     for (int index1 = 0; index1 < rows; ++index1)
     {
         int num1 = 0;
         int index2;
         do
         {
             for (index2 = index1; index2 < rows - 1; ++index2)
             {
                 double num2 = Math.Abs(elements1[index2]) + Math.Abs(elements1[index2 + 1]);
                 if (Math.Abs(elements2[index2]) + num2 == num2)
                     break;
             }
             if (index2 != index1)
             {
                 if (num1++ != 30)
                 {
                     double num2 = (elements1[index1 + 1] - elements1[index1]) / (2.0 * elements2[index1]);
                     double num3 = Math.Sqrt(num2 * num2 + 1.0);
                     double num4 = elements1[index2] - elements1[index1] + elements2[index1] / (num2 + (num2 >= 0.0 ? Math.Abs(num3) : -Math.Abs(num3)));
                     double num5 = 1.0;
                     double num6 = 1.0;
                     double num7 = 0.0;
                     int index3;
                     for (index3 = index2 - 1; index3 >= index1; --index3)
                     {
                         double num8 = num5 * elements2[index3];
                         double num9 = num6 * elements2[index3];
                         num3 = Math.Sqrt(num8 * num8 + num4 * num4);
                         elements2[index3 + 1] = num3;
                         if (num3 != 0.0)
                         {
                             num5 = num8 / num3;
                             num6 = num4 / num3;
                             double num10 = elements1[index3 + 1] - num7;
                             num3 = (elements1[index3] - num10) * num5 + 2.0 * num6 * num9;
                             num7 = num5 * num3;
                             elements1[index3 + 1] = num10 + num7;
                             num4 = num6 * num3 - num9;
                             for (int index4 = 0; index4 < rows; ++index4)
                             {
                                 double num11 = numArray[index4 + (index3 + 1) * rows];
                                 numArray[index4 + (index3 + 1) * rows] = num5 * numArray[index4 + index3 * rows] + num6 * num11;
                                 numArray[index4 + index3 * rows] = num6 * numArray[index4 + index3 * rows] - num5 * num11;
                             }
                         }
                         else
                         {
                             elements1[index3 + 1] -= num7;
                             elements2[index2] = 0.0;
                             break;
                         }
                     }
                     if (num3 != 0.0 || index3 < index1)
                     {
                         elements1[index1] -= num7;
                         elements2[index1] = num4;
                         elements2[index2] = 0.0;
                     }
                 }
                 else
                     goto label_31;
             }
         }
         while (index2 != index1);
         continue;
         label_31:
         Error("MakeEigenVectors", "too many iterationsn");
         return;
     }
     for (int index = 0; index < rows * rows; ++index)
         z.Elements[index / rows, index % rows] = numArray[index];
 }