예제 #1
0
 /// <summary>
 /// Creating a new document using the specified map, route, laps, initial transformation matrix, projection origin and document settings, and adding one new session with the specified route and laps.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="route"></param>
 /// <param name="laps"></param>
 /// <param name="initialTransformationMatrix"></param>
 /// <param name="projectionOrigin"></param>
 /// <param name="settings"></param>
 public Document(Map map, Route route, LapCollection laps, GeneralMatrix initialTransformationMatrix, LongLat projectionOrigin, DocumentSettings settings)
 {
     Map = map;
       sessions.Add(new Session(route, laps, map.Image.Size, initialTransformationMatrix, projectionOrigin, settings.DefaultSessionSettings));
       this.settings = settings;
       UpdateDocumentToCurrentVersion(this);
 }
예제 #2
0
 /// <summary>Cholesky algorithm for symmetric and positive definite matrix.</summary>
 /// <param name="Arg">  Square, symmetric matrix.
 /// </param>
 /// <returns>     Structure to access L and isspd flag.
 /// </returns>
 public CholeskyDecomposition(GeneralMatrix Arg)
 {
     // Initialize.
       double[][] A = Arg.Array;
       n = Arg.RowDimension;
       l = new double[n][];
       for (int i = 0; i < n; i++)
       {
     l[i] = new double[n];
       }
       isspd = (Arg.ColumnDimension == n);
       // Main loop.
       for (int j = 0; j < n; j++)
       {
     double[] Lrowj = l[j];
     double d = 0.0;
     for (int k = 0; k < j; k++)
     {
       double[] Lrowk = l[k];
       double s = 0.0;
       for (int i = 0; i < k; i++)
       {
     s += Lrowk[i] * Lrowj[i];
       }
       Lrowj[k] = s = (A[j][k] - s) / l[k][k];
       d = d + s * s;
       isspd = isspd & (A[k][j] == A[j][k]);
     }
     d = A[j][j] - d;
     isspd = isspd & (d > 0.0);
     l[j][j] = System.Math.Sqrt(System.Math.Max(d, 0.0));
     for (int k = j + 1; k < n; k++)
     {
       l[j][k] = 0.0;
     }
       }
 }
예제 #3
0
 /// <summary>A = A - B</summary>
 /// <param name="B">   another matrix
 /// </param>
 /// <returns>     A - B
 /// </returns>
 public virtual GeneralMatrix SubtractEquals(GeneralMatrix B)
 {
     CheckMatrixDimensions(B);
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       a[i][j] = a[i][j] - B.a[i][j];
     }
       }
       return this;
 }
예제 #4
0
 /// <summary>Matrix transpose.</summary>
 /// <returns>    A'
 /// </returns>
 public virtual GeneralMatrix Transpose()
 {
     GeneralMatrix X = new GeneralMatrix(n, m);
       double[][] C = X.Array;
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       C[j][i] = a[i][j];
     }
       }
       return X;
 }
예제 #5
0
        /// <summary>Generate matrix with random elements</summary>
        /// <param name="m">   Number of rows.
        /// </param>
        /// <param name="n">   Number of colums.
        /// </param>
        /// <returns>     An m-by-n matrix with uniformly distributed random elements.
        /// </returns>
        public static GeneralMatrix Random(int m, int n)
        {
            System.Random random = new System.Random();

              GeneralMatrix A = new GeneralMatrix(m, n);
              double[][] X = A.Array;
              for (int i = 0; i < m; i++)
              {
            for (int j = 0; j < n; j++)
            {
              X[i][j] = random.NextDouble();
            }
              }
              return A;
        }
예제 #6
0
 /// <summary>Construct a matrix from a copy of a 2-D array.</summary>
 /// <param name="A">   Two-dimensional array of doubles.
 /// </param>
 /// <exception cref="System.ArgumentException">   All rows must have the same length
 /// </exception>
 public static GeneralMatrix Create(double[][] A)
 {
     int m = A.Length;
       int n = A[0].Length;
       GeneralMatrix X = new GeneralMatrix(m, n);
       double[][] C = X.Array;
       for (int i = 0; i < m; i++)
       {
     if (A[i].Length != n)
     {
       throw new System.ArgumentException("All rows must have the same length.");
     }
     for (int j = 0; j < n; j++)
     {
       C[i][j] = A[i][j];
     }
       }
       return X;
 }
예제 #7
0
        /// <summary>QR Decomposition, computed by Householder reflections.</summary>
        /// <param name="A">   Rectangular matrix
        /// </param>
        /// <returns>     Structure to access R and the Householder vectors and compute Q.
        /// </returns>
        public QRDecomposition(GeneralMatrix A)
        {
            // Initialize.
              qr = A.ArrayCopy;
              m = A.RowDimension;
              n = A.ColumnDimension;
              rDiag = new double[n];

              // Main loop.
              for (int k = 0; k < n; k++)
              {
            // Compute 2-norm of k-th column without under/overflow.
            double nrm = 0;
            for (int i = k; i < m; i++)
            {
              nrm = Maths.Hypot(nrm, qr[i][k]);
            }

            if (nrm != 0.0)
            {
              // Form k-th Householder vector.
              if (qr[k][k] < 0)
              {
            nrm = -nrm;
              }
              for (int i = k; i < m; i++)
              {
            qr[i][k] /= nrm;
              }
              qr[k][k] += 1.0;

              // Apply transformation to remaining columns.
              for (int j = k + 1; j < n; j++)
              {
            double s = 0.0;
            for (int i = k; i < m; i++)
            {
              s += qr[i][k] * qr[i][j];
            }
            s = (-s) / qr[k][k];
            for (int i = k; i < m; i++)
            {
              qr[i][j] += s * qr[i][k];
            }
              }
            }
            rDiag[k] = -nrm;
              }
        }
예제 #8
0
        /// <summary>Construct the singular value decomposition</summary>
        /// <param name="Arg">   Rectangular matrix
        /// </param>
        /// <returns>     Structure to access U, S and V.
        /// </returns>
        public SingularValueDecomposition(GeneralMatrix Arg)
        {
            // Derived from LINPACK code.
              // Initialize.
              double[][] A = Arg.ArrayCopy;
              m = Arg.RowDimension;
              n = Arg.ColumnDimension;
              int nu = System.Math.Min(m, n);
              s = new double[System.Math.Min(m + 1, n)];
              u = new double[m][];
              for (int i = 0; i < m; i++)
              {
            u[i] = new double[nu];
              }
              v = new double[n][];
              for (int i2 = 0; i2 < n; i2++)
              {
            v[i2] = new double[n];
              }
              double[] e = new double[n];
              double[] work = new double[m];
              bool wantu = true;
              bool wantv = true;

              // Reduce A to bidiagonal form, storing the diagonal elements
              // in s and the super-diagonal elements in e.

              int nct = System.Math.Min(m - 1, n);
              int nrt = System.Math.Max(0, System.Math.Min(n - 2, m));
              for (int k = 0; k < System.Math.Max(nct, nrt); k++)
              {
            if (k < nct)
            {

              // Compute the transformation for the k-th column and
              // place the k-th diagonal in s[k].
              // Compute 2-norm of k-th column without under/overflow.
              s[k] = 0;
              for (int i = k; i < m; i++)
              {
            s[k] = Maths.Hypot(s[k], A[i][k]);
              }
              if (s[k] != 0.0)
              {
            if (A[k][k] < 0.0)
            {
              s[k] = -s[k];
            }
            for (int i = k; i < m; i++)
            {
              A[i][k] /= s[k];
            }
            A[k][k] += 1.0;
              }
              s[k] = -s[k];
            }
            for (int j = k + 1; j < n; j++)
            {
              if ((k < nct) & (s[k] != 0.0))
              {

            // Apply the transformation.

            double t = 0;
            for (int i = k; i < m; i++)
            {
              t += A[i][k] * A[i][j];
            }
            t = (-t) / A[k][k];
            for (int i = k; i < m; i++)
            {
              A[i][j] += t * A[i][k];
            }
              }

              // Place the k-th row of A into e for the
              // subsequent calculation of the row transformation.

              e[j] = A[k][j];
            }
            if (wantu & (k < nct))
            {

              // Place the transformation in U for subsequent back
              // multiplication.

              for (int i = k; i < m; i++)
              {
            u[i][k] = A[i][k];
              }
            }
            if (k < nrt)
            {

              // Compute the k-th row transformation and place the
              // k-th super-diagonal in e[k].
              // Compute 2-norm without under/overflow.
              e[k] = 0;
              for (int i = k + 1; i < n; i++)
              {
            e[k] = Maths.Hypot(e[k], e[i]);
              }
              if (e[k] != 0.0)
              {
            if (e[k + 1] < 0.0)
            {
              e[k] = -e[k];
            }
            for (int i = k + 1; i < n; i++)
            {
              e[i] /= e[k];
            }
            e[k + 1] += 1.0;
              }
              e[k] = -e[k];
              if ((k + 1 < m) & (e[k] != 0.0))
              {

            // Apply the transformation.

            for (int i = k + 1; i < m; i++)
            {
              work[i] = 0.0;
            }
            for (int j = k + 1; j < n; j++)
            {
              for (int i = k + 1; i < m; i++)
              {
                work[i] += e[j] * A[i][j];
              }
            }
            for (int j = k + 1; j < n; j++)
            {
              double t = (-e[j]) / e[k + 1];
              for (int i = k + 1; i < m; i++)
              {
                A[i][j] += t * work[i];
              }
            }
              }
              if (wantv)
              {

            // Place the transformation in V for subsequent
            // back multiplication.

            for (int i = k + 1; i < n; i++)
            {
              v[i][k] = e[i];
            }
              }
            }
              }

              // Set up the final bidiagonal matrix or order p.

              int p = System.Math.Min(n, m + 1);
              if (nct < n)
              {
            s[nct] = A[nct][nct];
              }
              if (m < p)
              {
            s[p - 1] = 0.0;
              }
              if (nrt + 1 < p)
              {
            e[nrt] = A[nrt][p - 1];
              }
              e[p - 1] = 0.0;

              // If required, generate U.

              if (wantu)
              {
            for (int j = nct; j < nu; j++)
            {
              for (int i = 0; i < m; i++)
              {
            u[i][j] = 0.0;
              }
              u[j][j] = 1.0;
            }
            for (int k = nct - 1; k >= 0; k--)
            {
              if (s[k] != 0.0)
              {
            for (int j = k + 1; j < nu; j++)
            {
              double t = 0;
              for (int i = k; i < m; i++)
              {
                t += u[i][k] * u[i][j];
              }
              t = (-t) / u[k][k];
              for (int i = k; i < m; i++)
              {
                u[i][j] += t * u[i][k];
              }
            }
            for (int i = k; i < m; i++)
            {
              u[i][k] = -u[i][k];
            }
            u[k][k] = 1.0 + u[k][k];
            for (int i = 0; i < k - 1; i++)
            {
              u[i][k] = 0.0;
            }
              }
              else
              {
            for (int i = 0; i < m; i++)
            {
              u[i][k] = 0.0;
            }
            u[k][k] = 1.0;
              }
            }
              }

              // If required, generate V.

              if (wantv)
              {
            for (int k = n - 1; k >= 0; k--)
            {
              if ((k < nrt) & (e[k] != 0.0))
              {
            for (int j = k + 1; j < nu; j++)
            {
              double t = 0;
              for (int i = k + 1; i < n; i++)
              {
                t += v[i][k] * v[i][j];
              }
              t = (-t) / v[k + 1][k];
              for (int i = k + 1; i < n; i++)
              {
                v[i][j] += t * v[i][k];
              }
            }
              }
              for (int i = 0; i < n; i++)
              {
            v[i][k] = 0.0;
              }
              v[k][k] = 1.0;
            }
              }

              // Main iteration loop for the singular values.

              int pp = p - 1;
              int iter = 0;
              double eps = System.Math.Pow(2.0, -52.0);
              while (p > 0)
              {
            int k, kase;

            // Here is where a test for too many iterations would go.

            // This section of the program inspects for
            // negligible elements in the s and e arrays.  On
            // completion the variables kase and k are set as follows.

            // kase = 1     if s(p) and e[k-1] are negligible and k<p
            // kase = 2     if s(k) is negligible and k<p
            // kase = 3     if e[k-1] is negligible, k<p, and
            //              s(k), ..., s(p) are not negligible (qr step).
            // kase = 4     if e(p-1) is negligible (convergence).

            for (k = p - 2; k >= -1; k--)
            {
              if (k == -1)
              {
            break;
              }
              if (System.Math.Abs(e[k]) <= eps * (System.Math.Abs(s[k]) + System.Math.Abs(s[k + 1])))
              {
            e[k] = 0.0;
            break;
              }
            }
            if (k == p - 2)
            {
              kase = 4;
            }
            else
            {
              int ks;
              for (ks = p - 1; ks >= k; ks--)
              {
            if (ks == k)
            {
              break;
            }
            double t = (ks != p ? System.Math.Abs(e[ks]) : 0.0) + (ks != k + 1 ? System.Math.Abs(e[ks - 1]) : 0.0);
            if (System.Math.Abs(s[ks]) <= eps * t)
            {
              s[ks] = 0.0;
              break;
            }
              }
              if (ks == k)
              {
            kase = 3;
              }
              else if (ks == p - 1)
              {
            kase = 1;
              }
              else
              {
            kase = 2;
            k = ks;
              }
            }
            k++;

            // Perform the task indicated by kase.

            switch (kase)
            {

              // Deflate negligible s(p).
              case 1:
            {
              double f = e[p - 2];
              e[p - 2] = 0.0;
              for (int j = p - 2; j >= k; j--)
              {
                double t = Maths.Hypot(s[j], f);
                double cs = s[j] / t;
                double sn = f / t;
                s[j] = t;
                if (j != k)
                {
                  f = (-sn) * e[j - 1];
                  e[j - 1] = cs * e[j - 1];
                }
                if (wantv)
                {
                  for (int i = 0; i < n; i++)
                  {
                    t = cs * v[i][j] + sn * v[i][p - 1];
                    v[i][p - 1] = (-sn) * v[i][j] + cs * v[i][p - 1];
                    v[i][j] = t;
                  }
                }
              }
            }
            break;

              // Split at negligible s(k).

              case 2:
            {
              double f = e[k - 1];
              e[k - 1] = 0.0;
              for (int j = k; j < p; j++)
              {
                double t = Maths.Hypot(s[j], f);
                double cs = s[j] / t;
                double sn = f / t;
                s[j] = t;
                f = (-sn) * e[j];
                e[j] = cs * e[j];
                if (wantu)
                {
                  for (int i = 0; i < m; i++)
                  {
                    t = cs * u[i][j] + sn * u[i][k - 1];
                    u[i][k - 1] = (-sn) * u[i][j] + cs * u[i][k - 1];
                    u[i][j] = t;
                  }
                }
              }
            }
            break;

              // Perform one qr step.

              case 3:
            {
              // Calculate the shift.

              double scale = System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Max(System.Math.Abs(s[p - 1]), System.Math.Abs(s[p - 2])), System.Math.Abs(e[p - 2])), System.Math.Abs(s[k])), System.Math.Abs(e[k]));
              double sp = s[p - 1] / scale;
              double spm1 = s[p - 2] / scale;
              double epm1 = e[p - 2] / scale;
              double sk = s[k] / scale;
              double ek = e[k] / scale;
              double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0;
              double c = (sp * epm1) * (sp * epm1);
              double shift = 0.0;
              if ((b != 0.0) | (c != 0.0))
              {
                shift = System.Math.Sqrt(b * b + c);
                if (b < 0.0)
                {
                  shift = -shift;
                }
                shift = c / (b + shift);
              }
              double f = (sk + sp) * (sk - sp) + shift;
              double g = sk * ek;

              // Chase zeros.

              for (int j = k; j < p - 1; j++)
              {
                double t = Maths.Hypot(f, g);
                double cs = f / t;
                double sn = g / t;
                if (j != k)
                {
                  e[j - 1] = t;
                }
                f = cs * s[j] + sn * e[j];
                e[j] = cs * e[j] - sn * s[j];
                g = sn * s[j + 1];
                s[j + 1] = cs * s[j + 1];
                if (wantv)
                {
                  for (int i = 0; i < n; i++)
                  {
                    t = cs * v[i][j] + sn * v[i][j + 1];
                    v[i][j + 1] = (-sn) * v[i][j] + cs * v[i][j + 1];
                    v[i][j] = t;
                  }
                }
                t = Maths.Hypot(f, g);
                cs = f / t;
                sn = g / t;
                s[j] = t;
                f = cs * e[j] + sn * s[j + 1];
                s[j + 1] = (-sn) * e[j] + cs * s[j + 1];
                g = sn * e[j + 1];
                e[j + 1] = cs * e[j + 1];
                if (wantu && (j < m - 1))
                {
                  for (int i = 0; i < m; i++)
                  {
                    t = cs * u[i][j] + sn * u[i][j + 1];
                    u[i][j + 1] = (-sn) * u[i][j] + cs * u[i][j + 1];
                    u[i][j] = t;
                  }
                }
              }
              e[p - 2] = f;
              iter = iter + 1;
            }
            break;

              // Convergence.

              case 4:
            {
              // Make the singular values positive.

              if (s[k] <= 0.0)
              {
                s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
                if (wantv)
                {
                  for (int i = 0; i <= pp; i++)
                  {
                    v[i][k] = -v[i][k];
                  }
                }
              }

              // Order the singular values.

              while (k < pp)
              {
                if (s[k] >= s[k + 1])
                {
                  break;
                }
                double t = s[k];
                s[k] = s[k + 1];
                s[k + 1] = t;
                if (wantv && (k < n - 1))
                {
                  for (int i = 0; i < n; i++)
                  {
                    t = v[i][k + 1]; v[i][k + 1] = v[i][k]; v[i][k] = t;
                  }
                }
                if (wantu && (k < m - 1))
                {
                  for (int i = 0; i < m; i++)
                  {
                    t = u[i][k + 1]; u[i][k + 1] = u[i][k]; u[i][k] = t;
                  }
                }
                k++;
              }
              iter = 0;
              p--;
            }
            break;
            }
              }
        }
예제 #9
0
 /// <summary>Set a submatrix.</summary>
 /// <param name="r">   Array of row indices.
 /// </param>
 /// <param name="j0">  Initial column index
 /// </param>
 /// <param name="j1">  Final column index
 /// </param>
 /// <param name="X">   A(r(:),j0:j1)
 /// </param>
 /// <exception cref="System.IndexOutOfRangeException"> Submatrix indices
 /// </exception>
 public virtual void SetMatrix(int[] r, int j0, int j1, GeneralMatrix X)
 {
     try
       {
     for (int i = 0; i < r.Length; i++)
     {
       for (int j = j0; j <= j1; j++)
       {
     a[r[i]][j] = X.GetElement(i, j - j0);
       }
     }
       }
       catch (System.IndexOutOfRangeException e)
       {
     throw new System.IndexOutOfRangeException("Submatrix indices", e);
       }
 }
예제 #10
0
        /// <summary>LU Decomposition</summary>
        /// <param name="A">  Rectangular matrix
        /// </param>
        /// <returns>     Structure to access L, U and piv.
        /// </returns>
        public LUDecomposition(GeneralMatrix A)
        {
            // Use a "left-looking", dot-product, Crout/Doolittle algorithm.

              lu = A.ArrayCopy;
              m = A.RowDimension;
              n = A.ColumnDimension;
              piv = new int[m];
              for (int i = 0; i < m; i++)
              {
            piv[i] = i;
              }
              pivsign = 1;
              double[] LUrowi;
              double[] LUcolj = new double[m];

              // Outer loop.

              for (int j = 0; j < n; j++)
              {

            // Make a copy of the j-th column to localize references.

            for (int i = 0; i < m; i++)
            {
              LUcolj[i] = lu[i][j];
            }

            // Apply previous transformations.

            for (int i = 0; i < m; i++)
            {
              LUrowi = lu[i];

              // Most of the time is spent in the following dot product.

              int kmax = System.Math.Min(i, j);
              double s = 0.0;
              for (int k = 0; k < kmax; k++)
              {
            s += LUrowi[k] * LUcolj[k];
              }

              LUrowi[j] = LUcolj[i] -= s;
            }

            // Find pivot and exchange if necessary.

            int p = j;
            for (int i = j + 1; i < m; i++)
            {
              if (System.Math.Abs(LUcolj[i]) > System.Math.Abs(LUcolj[p]))
              {
            p = i;
              }
            }
            if (p != j)
            {
              for (int k = 0; k < n; k++)
              {
            double t = lu[p][k]; lu[p][k] = lu[j][k]; lu[j][k] = t;
              }
              int k2 = piv[p]; piv[p] = piv[j]; piv[j] = k2;
              pivsign = -pivsign;
            }

            // Compute multipliers.

            if (j < m & lu[j][j] != 0.0)
            {
              for (int i = j + 1; i < m; i++)
              {
            lu[i][j] /= lu[j][j];
              }
            }
              }
        }
예제 #11
0
 /// <summary>Multiply a matrix by a scalar, C = s*A</summary>
 /// <param name="s">   scalar
 /// </param>
 /// <returns>     s*A
 /// </returns>
 public virtual GeneralMatrix Multiply(double s)
 {
     GeneralMatrix X = new GeneralMatrix(m, n);
       double[][] C = X.Array;
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       C[i][j] = s * a[i][j];
     }
       }
       return X;
 }
예제 #12
0
 /// <summary>Linear algebraic matrix multiplication, A * B</summary>
 /// <param name="B">   another matrix
 /// </param>
 /// <returns>     Matrix product, A * B
 /// </returns>
 /// <exception cref="System.ArgumentException">  Matrix inner dimensions must agree.
 /// </exception>
 public virtual GeneralMatrix Multiply(GeneralMatrix B)
 {
     if (B.m != n)
       {
     throw new System.ArgumentException("GeneralMatrix inner dimensions must agree.");
       }
       GeneralMatrix X = new GeneralMatrix(m, B.n);
       double[][] C = X.Array;
       double[] Bcolj = new double[n];
       for (int j = 0; j < B.n; j++)
       {
     for (int k = 0; k < n; k++)
     {
       Bcolj[k] = B.a[k][j];
     }
     for (int i = 0; i < m; i++)
     {
       double[] Arowi = a[i];
       double s = 0;
       for (int k = 0; k < n; k++)
       {
     s += Arowi[k] * Bcolj[k];
       }
       C[i][j] = s;
     }
       }
       return X;
 }
예제 #13
0
 /// <summary>Get a submatrix.</summary>
 /// <param name="r">   Array of row indices.
 /// </param>
 /// <param name="j0">  Initial column index
 /// </param>
 /// <param name="j1">  Final column index
 /// </param>
 /// <returns>     A(r(:),j0:j1)
 /// </returns>
 /// <exception cref="System.IndexOutOfRangeException">   Submatrix indices
 /// </exception>
 public virtual GeneralMatrix GetMatrix(int[] r, int j0, int j1)
 {
     GeneralMatrix X = new GeneralMatrix(r.Length, j1 - j0 + 1);
       double[][] B = X.Array;
       try
       {
     for (int i = 0; i < r.Length; i++)
     {
       for (int j = j0; j <= j1; j++)
       {
     B[i][j - j0] = a[r[i]][j];
       }
     }
       }
       catch (System.IndexOutOfRangeException e)
       {
     throw new System.IndexOutOfRangeException("Submatrix indices", e);
       }
       return X;
 }
예제 #14
0
 /// <summary>Get a submatrix.</summary>
 /// <param name="i0">  Initial row index
 /// </param>
 /// <param name="i1">  Final row index
 /// </param>
 /// <param name="c">   Array of column indices.
 /// </param>
 /// <returns>     A(i0:i1,c(:))
 /// </returns>
 /// <exception cref="System.IndexOutOfRangeException">   Submatrix indices
 /// </exception>
 public virtual GeneralMatrix GetMatrix(int i0, int i1, int[] c)
 {
     GeneralMatrix X = new GeneralMatrix(i1 - i0 + 1, c.Length);
       double[][] B = X.Array;
       try
       {
     for (int i = i0; i <= i1; i++)
     {
       for (int j = 0; j < c.Length; j++)
       {
     B[i - i0][j] = a[i][c[j]];
       }
     }
       }
       catch (System.IndexOutOfRangeException e)
       {
     throw new System.IndexOutOfRangeException("Submatrix indices", e);
       }
       return X;
 }
예제 #15
0
 /// <summary>Element-by-element right division in place, A = A./B</summary>
 /// <param name="B">   another matrix
 /// </param>
 /// <returns>     A./B
 /// </returns>
 public virtual GeneralMatrix ArrayRightDivideEquals(GeneralMatrix B)
 {
     CheckMatrixDimensions(B);
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       a[i][j] = a[i][j] / B.a[i][j];
     }
       }
       return this;
 }
예제 #16
0
 /// <summary>Unary minus</summary>
 /// <returns>    -A
 /// </returns>
 public virtual GeneralMatrix UnaryMinus()
 {
     GeneralMatrix X = new GeneralMatrix(m, n);
       double[][] C = X.Array;
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       C[i][j] = -a[i][j];
     }
       }
       return X;
 }
예제 #17
0
        /// <summary>Check for symmetry, then construct the eigenvalue decomposition</summary>
        /// <param name="Arg">   Square matrix
        /// </param>
        /// <returns>     Structure to access D and V.
        /// </returns>
        public EigenvalueDecomposition(GeneralMatrix Arg)
        {
            double[][] A = Arg.Array;
              n = Arg.ColumnDimension;
              v = new double[n][];
              for (int i = 0; i < n; i++)
              {
            v[i] = new double[n];
              }
              d = new double[n];
              e = new double[n];

              issymmetric = true;
              for (int j = 0; (j < n) & issymmetric; j++)
              {
            for (int i = 0; (i < n) & issymmetric; i++)
            {
              issymmetric = (A[i][j] == A[j][i]);
            }
              }

              if (issymmetric)
              {
            for (int i = 0; i < n; i++)
            {
              for (int j = 0; j < n; j++)
              {
            v[i][j] = A[i][j];
              }
            }

            // Tridiagonalize.
            tred2();

            // Diagonalize.
            tql2();
              }
              else
              {
            H = new double[n][];
            for (int i2 = 0; i2 < n; i2++)
            {
              H[i2] = new double[n];
            }
            ort = new double[n];

            for (int j = 0; j < n; j++)
            {
              for (int i = 0; i < n; i++)
              {
            H[i][j] = A[i][j];
              }
            }

            // Reduce to Hessenberg form.
            orthes();

            // Reduce Hessenberg to real Schur form.
            hqr2();
              }
        }
예제 #18
0
 /// <summary>Check if size(A) == size(B) *</summary>
 private void CheckMatrixDimensions(GeneralMatrix B)
 {
     if (B.m != m || B.n != n)
       {
     throw new System.ArgumentException("GeneralMatrix dimensions must agree.");
       }
 }
예제 #19
0
 /// <summary>Set a submatrix.</summary>
 /// <param name="i0">  Initial row index
 /// </param>
 /// <param name="i1">  Final row index
 /// </param>
 /// <param name="c">   Array of column indices.
 /// </param>
 /// <param name="X">   A(i0:i1,c(:))
 /// </param>
 /// <exception cref="System.IndexOutOfRangeException">  Submatrix indices
 /// </exception>
 public virtual void SetMatrix(int i0, int i1, int[] c, GeneralMatrix X)
 {
     try
       {
     for (int i = i0; i <= i1; i++)
     {
       for (int j = 0; j < c.Length; j++)
       {
     a[i][c[j]] = X.GetElement(i - i0, j);
       }
     }
       }
       catch (System.IndexOutOfRangeException e)
       {
     throw new System.IndexOutOfRangeException("Submatrix indices", e);
       }
 }
예제 #20
0
        /// <summary>Solve A*X = B</summary>
        /// <param name="B">  A Matrix with as many rows as A and any number of columns.
        /// </param>
        /// <returns>     X so that L*U*X = B(piv,:)
        /// </returns>
        /// <exception cref="System.ArgumentException"> Matrix row dimensions must agree.
        /// </exception>
        /// <exception cref="System.SystemException"> Matrix is singular.
        /// </exception>
        public virtual GeneralMatrix Solve(GeneralMatrix B)
        {
            if (B.RowDimension != m)
              {
            throw new System.ArgumentException("Matrix row dimensions must agree.");
              }
              if (!this.IsNonSingular)
              {
            throw new System.SystemException("Matrix is singular.");
              }

              // Copy right hand side with pivoting
              int nx = B.ColumnDimension;
              GeneralMatrix Xmat = B.GetMatrix(piv, 0, nx - 1);
              double[][] X = Xmat.Array;

              // Solve L*Y = B(piv,:)
              for (int k = 0; k < n; k++)
              {
            for (int i = k + 1; i < n; i++)
            {
              for (int j = 0; j < nx; j++)
              {
            X[i][j] -= X[k][j] * lu[i][k];
              }
            }
              }
              // Solve U*X = Y;
              for (int k = n - 1; k >= 0; k--)
              {
            for (int j = 0; j < nx; j++)
            {
              X[k][j] /= lu[k][k];
            }
            for (int i = 0; i < k; i++)
            {
              for (int j = 0; j < nx; j++)
              {
            X[i][j] -= X[k][j] * lu[i][k];
              }
            }
              }
              return Xmat;
        }
        private byte[] CreateSessionData(Session session)
        {
            var sessionStream = new MemoryStream();
              var sessionWriter = new BinaryWriter(sessionStream);
              // route
              var routeStream = new MemoryStream();
              var routeWriter = new BinaryWriter(routeStream);

              // which attributes to include for each waypoint
              var attributes = WaypointAttribute.Position | WaypointAttribute.Time;
              if (session.Route.ContainsWaypointAttribute(BusinessEntities.WaypointAttribute.HeartRate))
            attributes |= WaypointAttribute.HeartRate;
              if (session.Route.ContainsWaypointAttribute(BusinessEntities.WaypointAttribute.Altitude))
            attributes |= WaypointAttribute.Altitude;
              routeWriter.Write((UInt16)attributes);
              // any extra length in bytes for future elements for each waypoint
              routeWriter.Write((UInt16)0);
              // number of route segments in this route
              routeWriter.Write((UInt32)session.Route.Segments.Count);

              foreach (var routeSegment in session.Route.Segments)
              {
            // number of waypoints in this route segment
            routeWriter.Write((UInt32)routeSegment.Waypoints.Count);
            var lastTime = DateTime.MinValue;
            foreach (var waypoint in routeSegment.Waypoints)
            {
              // position: 8 bytes
              WriteLongLat(waypoint.LongLat, routeWriter);
              // time and tome type: 1 + 2-8 bytes
              WriteTimeTypeAndTime(waypoint.Time, lastTime, routeWriter);
              lastTime = waypoint.Time;
              // heart rate: 1 byte
              if ((((UInt16)attributes) & ((UInt16)WaypointAttribute.HeartRate)) == (UInt16)WaypointAttribute.HeartRate)
              {
            routeWriter.Write((byte)(waypoint.HeartRate.HasValue ? Math.Min(Math.Max(waypoint.HeartRate.Value, byte.MinValue), byte.MaxValue) : byte.MinValue));
              }
              // altitude: 2 bytes
              if ((((UInt16)attributes) & ((UInt16)WaypointAttribute.Altitude)) == (UInt16)WaypointAttribute.Altitude)
              {
            routeWriter.Write((Int16)(waypoint.Altitude.HasValue ? Math.Min(Math.Max(waypoint.Altitude.Value, Int16.MinValue), Int16.MaxValue) : 0));
              }
            }
              }
              sessionWriter.Write((byte)Tags.Route);
              sessionWriter.Write((UInt32)routeStream.Length);
              sessionWriter.Write(routeStream.ToArray());
              routeWriter.Close();
              routeStream.Close();
              routeStream.Dispose();

              // handles
              // TODO: adjust for zoom
              var handleStream = new MemoryStream();
              var handleWriter = new BinaryWriter(handleStream);
              handleWriter.Write((UInt32)session.Handles.Length);
              foreach (var handle in session.Handles)
              {
            // transformation matrix
            var scaleMatrix = new GeneralMatrix(new[] {PercentualSize, 0, 0, 0, PercentualSize, 0, 0, 0, 1}, 3);
            var scaledTM = scaleMatrix*handle.TransformationMatrix;
            for (var i = 0; i < 3; i++)
            {
              for (var j = 0; j < 3; j++)
              {
            handleWriter.Write(scaledTM.GetElement(i, j));
              }
            }
            // parameterized location
            handleWriter.Write((UInt32)handle.ParameterizedLocation.SegmentIndex);
            handleWriter.Write(handle.ParameterizedLocation.Value);
            // pixel location
            handleWriter.Write(PercentualSize * handle.Location.X);
            handleWriter.Write(PercentualSize * handle.Location.Y);
            // type
            handleWriter.Write((Int16)handle.Type);
              }
              sessionWriter.Write((byte)Tags.Handles);
              sessionWriter.Write((UInt32)handleStream.Length);
              sessionWriter.Write(handleStream.ToArray());
              handleWriter.Close();
              handleStream.Close();
              handleStream.Dispose();

              // projection origin
              sessionWriter.Write((byte)Tags.ProjectionOrigin);
              sessionWriter.Write((UInt32)8);
              WriteLongLat(session.ProjectionOrigin, sessionWriter);

              // laps
              var lapStream = new MemoryStream();
              var lapWriter = new BinaryWriter(lapStream);
              lapWriter.Write((UInt32)session.Laps.Count);
              foreach (var lap in session.Laps)
              {
            // time
            lapWriter.Write(lap.Time.ToUniversalTime().ToBinary());
            // type
            lapWriter.Write((byte)lap.LapType);
              }
              sessionWriter.Write((byte)Tags.Laps);
              sessionWriter.Write((UInt32)lapStream.Length);
              sessionWriter.Write(lapStream.ToArray());
              lapWriter.Close();
              lapStream.Close();
              lapStream.Dispose();

              // session info
              var sessionInfoStream = new MemoryStream();
              var sessionInfoWriter = new BinaryWriter(sessionInfoStream);
              // never change the order or remove field that has already been added!
              WriteString(session.SessionInfo.Person.Name, sessionInfoWriter);
              WriteString(session.SessionInfo.Person.Club, sessionInfoWriter);
              sessionInfoWriter.Write(session.SessionInfo.Person.Id);
              WriteString(session.SessionInfo.Description, sessionInfoWriter);

              sessionWriter.Write((byte)Tags.SessionInfo);
              sessionWriter.Write((UInt32)sessionInfoStream.Length);
              sessionWriter.Write(sessionInfoStream.ToArray());
              sessionInfoWriter.Close();
              sessionInfoStream.Close();
              sessionInfoStream.Dispose();

              // map reading info
              var mapReadingsList = session.Route.GetMapReadingsList();
              if(mapReadingsList != null)
              {
            var mapReadingInfoStream = new MemoryStream();
            var mapReadingInfoWriter = new BinaryWriter(mapReadingInfoStream);
            var lastTime = DateTime.MinValue;
            foreach (var mapReading in mapReadingsList)
            {
              WriteTimeTypeAndTime(mapReading, lastTime, mapReadingInfoWriter);
            }
            sessionWriter.Write((byte)Tags.MapReadingInfo);
            sessionWriter.Write((UInt32)mapReadingInfoStream.Length);
            sessionWriter.Write(mapReadingInfoStream.ToArray());
            mapReadingInfoWriter.Close();
            mapReadingInfoStream.Close();
            mapReadingInfoStream.Dispose();
              }

              var data = sessionStream.ToArray();
              sessionWriter.Close();
              sessionStream.Close();
              sessionStream.Dispose();
              return data;
        }
예제 #22
0
        /// <summary>Least squares solution of A*X = B</summary>
        /// <param name="B">   A Matrix with as many rows as A and any number of columns.
        /// </param>
        /// <returns>     X that minimizes the two norm of Q*R*X-B.
        /// </returns>
        /// <exception cref="System.ArgumentException"> Matrix row dimensions must agree.
        /// </exception>
        /// <exception cref="System.SystemException"> Matrix is rank deficient.
        /// </exception>
        public virtual GeneralMatrix Solve(GeneralMatrix B)
        {
            if (B.RowDimension != m)
              {
            throw new System.ArgumentException("GeneralMatrix row dimensions must agree.");
              }
              if (!this.FullRank)
              {
            throw new System.SystemException("Matrix is rank deficient.");
              }

              // Copy right hand side
              int nx = B.ColumnDimension;
              double[][] X = B.ArrayCopy;

              // Compute Y = transpose(Q)*B
              for (int k = 0; k < n; k++)
              {
            for (int j = 0; j < nx; j++)
            {
              double s = 0.0;
              for (int i = k; i < m; i++)
              {
            s += qr[i][k] * X[i][j];
              }
              s = (-s) / qr[k][k];
              for (int i = k; i < m; i++)
              {
            X[i][j] += s * qr[i][k];
              }
            }
              }
              // Solve R*X = Y;
              for (int k = n - 1; k >= 0; k--)
              {
            for (int j = 0; j < nx; j++)
            {
              X[k][j] /= rDiag[k];
            }
            for (int i = 0; i < k; i++)
            {
              for (int j = 0; j < nx; j++)
              {
            X[i][j] -= X[k][j] * qr[i][k];
              }
            }
              }

              return (new GeneralMatrix(X, n, nx).GetMatrix(0, n - 1, 0, nx - 1));
        }
예제 #23
0
 /// <summary>
 /// Creating a new document using the specified map, route, laps, initial transformation matrix and document settings, and adding one new session with the specified route and laps.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="route"></param>
 /// <param name="laps"></param>
 /// <param name="initialTransformationMatrix"></param>
 /// <param name="settings"></param>
 public Document(Map map, Route route, LapCollection laps, GeneralMatrix initialTransformationMatrix, DocumentSettings settings)
     : this(map, route, laps, initialTransformationMatrix, null, settings)
 {
 }
예제 #24
0
 /// <summary>Solve A*X = B</summary>
 /// <param name="B">   right hand side
 /// </param>
 /// <returns>     solution if A is square, least squares solution otherwise
 /// </returns>
 public virtual GeneralMatrix Solve(GeneralMatrix B)
 {
     return (m == n ? (new LUDecomposition(this)).Solve(B) : (new QRDecomposition(this)).Solve(B));
 }
예제 #25
0
 /// <summary>Generate identity matrix</summary>
 /// <param name="m">   Number of rows.
 /// </param>
 /// <param name="n">   Number of colums.
 /// </param>
 /// <returns>     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
 /// </returns>
 public static GeneralMatrix Identity(int m, int n)
 {
     GeneralMatrix A = new GeneralMatrix(m, n);
       double[][] X = A.Array;
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       X[i][j] = (i == j ? 1.0 : 0.0);
     }
       }
       return A;
 }
예제 #26
0
 /// <summary>
 /// Converts a map image pixel coordinate to a longitude and latitude coordinate
 /// </summary>
 /// <param name="mapImagePosition">Map pixel coordinate, referring to unzoomed map without any borders and image header</param>
 /// <returns></returns>
 public LongLat GetLongLatForMapImagePosition(PointD mapImagePosition, GeneralMatrix averageTransformationMatrixInverse)
 {
     var projectedPosition = LinearAlgebraUtil.Transform(mapImagePosition, averageTransformationMatrixInverse);
       return LongLat.Deproject(projectedPosition, ProjectionOrigin);
 }
예제 #27
0
 /// <summary>Solve X*A = B, which is also A'*X' = B'</summary>
 /// <param name="B">   right hand side
 /// </param>
 /// <returns>     solution if A is square, least squares solution otherwise.
 /// </returns>
 public virtual GeneralMatrix SolveTranspose(GeneralMatrix B)
 {
     return Transpose().Solve(B.Transpose());
 }
예제 #28
0
 /// <summary>C = A - B</summary>
 /// <param name="B">   another matrix
 /// </param>
 /// <returns>     A - B
 /// </returns>
 public virtual GeneralMatrix Subtract(GeneralMatrix B)
 {
     CheckMatrixDimensions(B);
       GeneralMatrix X = new GeneralMatrix(m, n);
       double[][] C = X.Array;
       for (int i = 0; i < m; i++)
       {
     for (int j = 0; j < n; j++)
     {
       C[i][j] = a[i][j] - B.a[i][j];
     }
       }
       return X;
 }
예제 #29
0
        /// <summary>Solve A*X = B</summary>
        /// <param name="B">  A Matrix with as many rows as A and any number of columns.
        /// </param>
        /// <returns>     X so that L*L'*X = B
        /// </returns>
        /// <exception cref="System.ArgumentException">  Matrix row dimensions must agree.
        /// </exception>
        /// <exception cref="System.SystemException"> Matrix is not symmetric positive definite.
        /// </exception>
        public virtual GeneralMatrix Solve(GeneralMatrix B)
        {
            if (B.RowDimension != n)
              {
            throw new System.ArgumentException("Matrix row dimensions must agree.");
              }
              if (!isspd)
              {
            throw new System.SystemException("Matrix is not symmetric positive definite.");
              }

              // Copy right hand side.
              double[][] X = B.ArrayCopy;
              int nx = B.ColumnDimension;

              // Solve L*Y = B;
              for (int k = 0; k < n; k++)
              {
            for (int i = k + 1; i < n; i++)
            {
              for (int j = 0; j < nx; j++)
              {
            X[i][j] -= X[k][j] * l[i][k];
              }
            }
            for (int j = 0; j < nx; j++)
            {
              X[k][j] /= l[k][k];
            }
              }

              // Solve L'*X = Y;
              for (int k = n - 1; k >= 0; k--)
              {
            for (int j = 0; j < nx; j++)
            {
              X[k][j] /= l[k][k];
            }
            for (int i = 0; i < k; i++)
            {
              for (int j = 0; j < nx; j++)
              {
            X[i][j] -= X[k][j] * l[k][i];
              }
            }
              }
              return new GeneralMatrix(X, n, nx);
        }