Beispiel #1
0
        /// <summary>
        /// Inverts square matrix as long as det != 0.
        /// </summary>
        /// <returns>Inverse of matrix.</returns>
        public SafeMatrix Inverse()
        {
            if (!this.IsSquare())
            {
                throw new InvalidOperationException("Cannot invert non-square matrix.");
            }

            double det = this.Determinant();

            if (det == 0)
            {
                throw new InvalidOperationException("Cannot invert (nearly) singular matrix.");
            }

            SafeMatrix buf = new SafeMatrix(m_ColumnCount, m_ColumnCount);

            for (int i = 0; i < m_ColumnCount; i++)
            {
                for (int j = 0; j < m_ColumnCount; j++)
                {
                    buf.m_Elements[i * buf.m_ColumnCount + j] = (Math.Pow(-1, i + j) * this.Minor(j, i).Determinant()) / det;
                }
            }

            return(buf);
        }
Beispiel #2
0
        public SafeMatrix Minor(int row, int col)
        {
            // THIS IS THE LOW-LEVEL SOLUTION ~ O(n^2)
            SafeMatrix buf = new SafeMatrix(m_RowCount - 1, m_ColumnCount - 1);
            int        r   = 0;
            int        c   = 0;

            for (int i = 0; i < m_RowCount; i++)
            {
                if (i != row)
                {
                    for (int j = 0; j < m_ColumnCount; j++)
                    {
                        if (j != col)
                        {
                            buf.m_Elements[r * buf.m_ColumnCount + c] = m_Elements[i * m_ColumnCount + j];
                            c++;
                        }
                    }

                    c = 0;
                    r++;
                }
            }

            return(buf);
        }
Beispiel #3
0
        public double Determinant()
        {
            if (!this.IsSquare())
            {
                throw new InvalidOperationException("Cannot calc determinant of non-square matrix.");
            }

            if (this.m_ColumnCount == 1)
            {
                return(this[0, 0]);
            }

            // perform LU-decomposition & return product of diagonal elements of U
            SafeMatrix X = this.Clone();

            // for speed concerns, use this
            try
            {
                X.LU();
                return(X.DiagProd());
            }
            catch (DivideByZeroException)
            {
                // this is slower and needs more memory... .
                //Matrix P = X.LUSafe();
                //return (double)P.Signum() * X.DiagProd();

                throw;
            }
        }
Beispiel #4
0
        public SafeMatrix Clone()
        {
            SafeMatrix A = new SafeMatrix(m_RowCount, m_ColumnCount);

            for (int i = 0; i < m_MatrixSize; i++)
            {
                A.m_Elements[i] = m_Elements[i];
            }

            return(A);
        }
Beispiel #5
0
        public static SafeMatrix operator *(double x, SafeMatrix A)
        {
            SafeMatrix B = new SafeMatrix(A.RowCount, A.ColumnCount);

            for (int i = 0; i < A.m_MatrixSize; i++)
            {
                B.m_Elements[i] = A.m_Elements[i] * x;
            }

            return(B);
        }
Beispiel #6
0
        public SafeMatrix Transpose()
        {
            SafeMatrix M = new SafeMatrix(m_ColumnCount, m_RowCount);

            for (int i = 0; i < m_ColumnCount; i++)
            {
                for (int j = 0; j < m_RowCount; j++)
                {
                    M.m_Elements[i * M.m_ColumnCount + j] = m_Elements[j * m_ColumnCount + i];
                }
            }

            return(M);
        }
Beispiel #7
0
        public static double Dot(SafeMatrix v, int vRow, SafeMatrix w, int wCol)
        {
            if (v.ColumnCount != w.RowCount)
            {
                throw new ArgumentException("Vectors must be of the same length.");
            }

            double buf = 0;

            for (int i = 0; i < v.ColumnCount; i++)
            {
                buf += v.m_Elements[vRow * v.m_ColumnCount + i] * w.m_Elements[i * w.m_ColumnCount + wCol];
            }

            return(buf);
        }
Beispiel #8
0
        public static SafeMatrix operator *(SafeMatrix A, SafeMatrix B)
        {
            if (A.ColumnCount != B.RowCount)
            {
                throw new ArgumentException("Inner matrix dimensions must agree.");
            }

            SafeMatrix C = new SafeMatrix(A.RowCount, B.ColumnCount);

            for (int i = 0; i < A.RowCount; i++)
            {
                for (int j = 0; j < B.ColumnCount; j++)
                {
                    C.m_Elements[i * C.m_ColumnCount + j] = Dot(A, i, B, j);
                }
            }

            return(C);
        }
Beispiel #9
0
        public static SafeMatrix operator *(double x, SafeMatrix A)
        {
            SafeMatrix B = new SafeMatrix(A.RowCount, A.ColumnCount);

            for (int i = 0; i < A.m_MatrixSize; i++)
            {
                B.m_Elements[i] = A.m_Elements[i] * x;
            }

            return B;
        }
Beispiel #10
0
        public SafeMatrix Transpose()
        {
            SafeMatrix M = new SafeMatrix(m_ColumnCount, m_RowCount);

            for (int i = 0; i < m_ColumnCount; i++)
            {
                for (int j = 0; j < m_RowCount; j++)
                {
                    M.m_Elements[i * M.m_ColumnCount + j] = m_Elements[j * m_ColumnCount + i];
                }
            }

            return M;
        }
Beispiel #11
0
        public SafeMatrix Minor(int row, int col)
        {
            // THIS IS THE LOW-LEVEL SOLUTION ~ O(n^2)
            SafeMatrix buf = new SafeMatrix(m_RowCount - 1, m_ColumnCount - 1);
            int r = 0;
            int c = 0;

            for (int i = 0; i < m_RowCount; i++)
            {
                if (i != row)
                {
                    for (int j = 0; j < m_ColumnCount; j++)
                    {
                        if (j != col)
                        {
                            buf.m_Elements[r * buf.m_ColumnCount + c] = m_Elements[i * m_ColumnCount + j];
                            c++;
                        }
                    }

                    c = 0;
                    r++;
                }
            }

            return buf;
        }
Beispiel #12
0
        /// <summary>
        /// Inverts square matrix as long as det != 0.
        /// </summary>
        /// <returns>Inverse of matrix.</returns>
        public SafeMatrix Inverse()
        {
            if (!this.IsSquare())
                throw new InvalidOperationException("Cannot invert non-square matrix.");

            double det = this.Determinant();

            if (det == 0)
                throw new InvalidOperationException("Cannot invert (nearly) singular matrix.");

            SafeMatrix buf = new SafeMatrix(m_ColumnCount, m_ColumnCount);

            for (int i = 0; i < m_ColumnCount; i++)
            {
                for (int j = 0; j < m_ColumnCount; j++)
                {
                    buf.m_Elements[i * buf.m_ColumnCount + j] = (Math.Pow(-1, i + j) * this.Minor(j, i).Determinant()) / det;
                }
            }

            return buf;
        }
Beispiel #13
0
        public SafeMatrix Clone()
        {
            SafeMatrix A = new SafeMatrix(m_RowCount, m_ColumnCount);

            for (int i = 0; i < m_MatrixSize; i++)
                A.m_Elements[i] = m_Elements[i];

            return A;
        }
Beispiel #14
0
        public static double Dot(SafeMatrix v, int vRow, SafeMatrix w, int wCol)
        {
            if (v.ColumnCount != w.RowCount)
                throw new ArgumentException("Vectors must be of the same length.");

            double buf = 0;

            for (int i = 0; i < v.ColumnCount; i++)
            {
                buf += v.m_Elements[vRow * v.m_ColumnCount + i] * w.m_Elements[i * w.m_ColumnCount + wCol];
            }

            return buf;
        }
Beispiel #15
0
        public void Solve(bool useNormalisation, double t0_initialVal)
        {
            var varTimes = new List<double>();
            var varMagnitudes = new List<double>();

            double constNorm = double.NaN;
            if (!useNormalisation)
            {
                List<double> medianCalcList = new List<double>(m_CompData);
                medianCalcList.Sort();
                constNorm = medianCalcList[medianCalcList.Count/2];
            }

            C = 1; // Fix C to 1
            M0 = FitM0ForT0(t0_initialVal, constNorm) - 1; // Get from known max magnitude of star

            for (int i = 0; i < m_NumObs; i++)
            {
                double mag = M0 - 2.5 * Math.Log10(m_VarData[i] / (!useNormalisation ? constNorm : m_CompData[i]));

                if (IsOutlier(i, mag)) continue;

                varTimes.Add(m_Times[i]);
                varMagnitudes.Add(mag);
            }

            if (varMagnitudes.Count < 7)
            {
                // Not enought data points for solving 5 variables
                IsSolved = false;
                return;
            }

            // Starting values
            C = 1;
            T0 = t0_initialVal; // Get from Kwee van Worden
            G = 0.5;
            // Get D from solving the equation to D (with other starting values specified)
            D = (varTimes[varMagnitudes.Count - 1] - T0) / Acosh(1 - Math.Log(1 - Math.Pow(1 - (varMagnitudes[varMagnitudes.Count - 1] - M0) / C, 1 / G)));
            if (double.IsNaN(D) || double.IsInfinity(D)) D = 0.1;

            NumberIterations = 100;

            double[] minCorr = new double[] {double.MaxValue, double.MaxValue, double.MaxValue, double.MaxValue, double.MaxValue};

            //// Our guess ot T0 is very close, so assume it is contant and solve for G and D
            //for (int iter = NumberIterations; iter > 0; iter--)
            //{
            //    var A = new SafeMatrix(varMagnitudes.Count, 2);
            //    var X = new SafeMatrix(varMagnitudes.Count, 1);

            //    for (int index = 0; index < varMagnitudes.Count; index++)
            //    {
            //        double t = varTimes[index];
            //        double difference = ComputeModelValue(t) - varMagnitudes[index];
            //        X[index, 0] = -difference;

            //        double GAMMA = 1 - Math.Exp(1 - Math.Cosh((t - T0) / D));
            //        double GAMMA_G = Math.Pow(GAMMA, G);

            //        A[index, 0] = GAMMA_G * Math.Log(G); // G
            //        A[index, 1] = -(G / D) * Math.Pow(GAMMA, G - 1) * Math.Exp(1 - Math.Cosh((t - T0) / D)) * Math.Sinh((t - T0) / D) * (t - T0) / D; // D
            //    }

            //    SafeMatrix a_T = A.Transpose();
            //    SafeMatrix aa = a_T * A;
            //    SafeMatrix aa_inv = aa.Inverse();
            //    SafeMatrix Y = (aa_inv * a_T) * X;

            //    D += Y[1, 0];
            //    if (D < 0) D = 0.001;

            //    // Enforce maximum correction for G of |0.1|. G > 0
            //    //if (Y[0, 0] > 0.01) Y[0, 0] = 0.01;
            //    //if (Y[0, 0] < -0.01) Y[0, 0] = -0.01;
            //    G += Y[0, 0];
            //    if (G < 0) G = 0.001;

            //    Trace.WriteLine(string.Format("D Corr: {0}\t\t G Corr: {1}", Y[1, 0], Y[0, 0]));
            //}

            for (int iter = NumberIterations; iter > 0; iter--)
            {
                var A = new SafeMatrix(varMagnitudes.Count, 3);
                var X = new SafeMatrix(varMagnitudes.Count, 1);

                for (int index = 0; index < varMagnitudes.Count; index++)
                {
                    double t = varTimes[index];
                    double difference = ComputeModelValue(t) - varMagnitudes[index];
                    X[index, 0] = -difference;

                    double GAMMA = 1 - Math.Exp(1 - Math.Cosh((t - T0) / D));
                    double GAMMA_G = Math.Pow(GAMMA, G);

                    A[index, 0] = -GAMMA_G * Math.Log(G); // G
                    A[index, 1] = (G / D) * Math.Pow(GAMMA, G - 1) * Math.Exp(1 - Math.Cosh((t - T0) / D)) * Math.Sinh((t - T0) / D); // T0
                    A[index, 2] = A[index, 1] * (t - T0) / D; // D
                }

                SafeMatrix a_T = A.Transpose();
                SafeMatrix aa = a_T * A;
                SafeMatrix aa_inv = aa.Inverse();
                SafeMatrix Y = (aa_inv * a_T) * X;

                if (minCorr[0] > Math.Abs(Y[0, 0])) minCorr[0] = Y[0, 0];
                if (minCorr[1] > Math.Abs(Y[1, 0])) minCorr[1] = Y[1, 0];
                if (minCorr[2] > Math.Abs(Y[2, 0])) minCorr[2] = Y[2, 0];

                //if (Y[1, 0] > 0.0001) Y[1, 0] = 0.0001;
                //if (Y[1, 0] < -0.0001) Y[1, 0] = -0.0001;
                T0 += Y[1, 0];

                Trace.WriteLine(string.Format("T0 Corr: {0}; ", Y[1, 0]));

                //if (Y[2, 0] > 0.01) Y[2, 0] = 0.01;
                //if (Y[2, 0] < -0.01) Y[2, 0] = -0.01;
                D += Y[2, 0];
                if (D < 0) D = 0.001;

                // Enforce maximum correction for G of |0.1|. G > 0
                //if (Y[0, 0] > 0.01) Y[0, 0] = 0.01;
                //if (Y[0, 0] < -0.01) Y[0, 0] = -0.01;
                G += Y[0, 0];
                if (G < 0) G = 0.001;

            }

            //Trace.WriteLine(string.Format("{0}; {1}; {2}; {3}; {4}", minCorr[0], minCorr[1], minCorr[2], minCorr[3], minCorr[4]));

            Times.Clear();
            NormIntensities.Clear();
            var residuals = new List<double>();

            for (int index = 0; index < varMagnitudes.Count; index++)
            {
                double t = varTimes[index];
                Times.Add(t);
                double magVal = ComputeModelValue(t);
                double residual = magVal - varMagnitudes[index];
                NormIntensities.Add(Math.Pow(10, (10 - magVal)/2.5));
                residuals.Add(residual);
            }
        }
Beispiel #16
0
        public void Solve(bool useNormalisation, double t0_initialVal)
        {
            var varTimes      = new List <double>();
            var varMagnitudes = new List <double>();

            double constNorm = double.NaN;

            if (!useNormalisation)
            {
                List <double> medianCalcList = new List <double>(m_CompData);
                medianCalcList.Sort();
                constNorm = medianCalcList[medianCalcList.Count / 2];
            }

            C  = 1;                                        // Fix C to 1
            M0 = FitM0ForT0(t0_initialVal, constNorm) - 1; // Get from known max magnitude of star

            for (int i = 0; i < m_NumObs; i++)
            {
                double mag = M0 - 2.5 * Math.Log10(m_VarData[i] / (!useNormalisation ? constNorm : m_CompData[i]));

                if (IsOutlier(i, mag))
                {
                    continue;
                }

                varTimes.Add(m_Times[i]);
                varMagnitudes.Add(mag);
            }

            if (varMagnitudes.Count < 7)
            {
                // Not enought data points for solving 5 variables
                IsSolved = false;
                return;
            }

            // Starting values
            C  = 1;
            T0 = t0_initialVal;             // Get from Kwee van Worden
            G  = 0.5;
            // Get D from solving the equation to D (with other starting values specified)
            D = (varTimes[varMagnitudes.Count - 1] - T0) / Acosh(1 - Math.Log(1 - Math.Pow(1 - (varMagnitudes[varMagnitudes.Count - 1] - M0) / C, 1 / G)));
            if (double.IsNaN(D) || double.IsInfinity(D))
            {
                D = 0.1;
            }

            NumberIterations = 100;

            double[] minCorr = new double[] { double.MaxValue, double.MaxValue, double.MaxValue, double.MaxValue, double.MaxValue };


            //// Our guess ot T0 is very close, so assume it is contant and solve for G and D
            //for (int iter = NumberIterations; iter > 0; iter--)
            //{
            //    var A = new SafeMatrix(varMagnitudes.Count, 2);
            //    var X = new SafeMatrix(varMagnitudes.Count, 1);

            //    for (int index = 0; index < varMagnitudes.Count; index++)
            //    {
            //        double t = varTimes[index];
            //        double difference = ComputeModelValue(t) - varMagnitudes[index];
            //        X[index, 0] = -difference;

            //        double GAMMA = 1 - Math.Exp(1 - Math.Cosh((t - T0) / D));
            //        double GAMMA_G = Math.Pow(GAMMA, G);

            //        A[index, 0] = GAMMA_G * Math.Log(G); // G
            //        A[index, 1] = -(G / D) * Math.Pow(GAMMA, G - 1) * Math.Exp(1 - Math.Cosh((t - T0) / D)) * Math.Sinh((t - T0) / D) * (t - T0) / D; // D
            //    }

            //    SafeMatrix a_T = A.Transpose();
            //    SafeMatrix aa = a_T * A;
            //    SafeMatrix aa_inv = aa.Inverse();
            //    SafeMatrix Y = (aa_inv * a_T) * X;

            //    D += Y[1, 0];
            //    if (D < 0) D = 0.001;

            //    // Enforce maximum correction for G of |0.1|. G > 0
            //    //if (Y[0, 0] > 0.01) Y[0, 0] = 0.01;
            //    //if (Y[0, 0] < -0.01) Y[0, 0] = -0.01;
            //    G += Y[0, 0];
            //    if (G < 0) G = 0.001;

            //    Trace.WriteLine(string.Format("D Corr: {0}\t\t G Corr: {1}", Y[1, 0], Y[0, 0]));
            //}

            for (int iter = NumberIterations; iter > 0; iter--)
            {
                var A = new SafeMatrix(varMagnitudes.Count, 3);
                var X = new SafeMatrix(varMagnitudes.Count, 1);

                for (int index = 0; index < varMagnitudes.Count; index++)
                {
                    double t          = varTimes[index];
                    double difference = ComputeModelValue(t) - varMagnitudes[index];
                    X[index, 0] = -difference;

                    double GAMMA   = 1 - Math.Exp(1 - Math.Cosh((t - T0) / D));
                    double GAMMA_G = Math.Pow(GAMMA, G);

                    A[index, 0] = -GAMMA_G *Math.Log(G);                                                                              // G

                    A[index, 1] = (G / D) * Math.Pow(GAMMA, G - 1) * Math.Exp(1 - Math.Cosh((t - T0) / D)) * Math.Sinh((t - T0) / D); // T0
                    A[index, 2] = A[index, 1] * (t - T0) / D;                                                                         // D
                }

                SafeMatrix a_T    = A.Transpose();
                SafeMatrix aa     = a_T * A;
                SafeMatrix aa_inv = aa.Inverse();
                SafeMatrix Y      = (aa_inv * a_T) * X;

                if (minCorr[0] > Math.Abs(Y[0, 0]))
                {
                    minCorr[0] = Y[0, 0];
                }
                if (minCorr[1] > Math.Abs(Y[1, 0]))
                {
                    minCorr[1] = Y[1, 0];
                }
                if (minCorr[2] > Math.Abs(Y[2, 0]))
                {
                    minCorr[2] = Y[2, 0];
                }

                //if (Y[1, 0] > 0.0001) Y[1, 0] = 0.0001;
                //if (Y[1, 0] < -0.0001) Y[1, 0] = -0.0001;
                T0 += Y[1, 0];

                Trace.WriteLine(string.Format("T0 Corr: {0}; ", Y[1, 0]));

                //if (Y[2, 0] > 0.01) Y[2, 0] = 0.01;
                //if (Y[2, 0] < -0.01) Y[2, 0] = -0.01;
                D += Y[2, 0];
                if (D < 0)
                {
                    D = 0.001;
                }

                // Enforce maximum correction for G of |0.1|. G > 0
                //if (Y[0, 0] > 0.01) Y[0, 0] = 0.01;
                //if (Y[0, 0] < -0.01) Y[0, 0] = -0.01;
                G += Y[0, 0];
                if (G < 0)
                {
                    G = 0.001;
                }
            }

            //Trace.WriteLine(string.Format("{0}; {1}; {2}; {3}; {4}", minCorr[0], minCorr[1], minCorr[2], minCorr[3], minCorr[4]));

            Times.Clear();
            NormIntensities.Clear();
            var residuals = new List <double>();

            for (int index = 0; index < varMagnitudes.Count; index++)
            {
                double t = varTimes[index];
                Times.Add(t);
                double magVal   = ComputeModelValue(t);
                double residual = magVal - varMagnitudes[index];
                NormIntensities.Add(Math.Pow(10, (10 - magVal) / 2.5));
                residuals.Add(residual);
            }
        }
Beispiel #17
0
        public static SafeMatrix operator *(SafeMatrix A, SafeMatrix B)
        {
            if (A.ColumnCount != B.RowCount)
                throw new ArgumentException("Inner matrix dimensions must agree.");

            SafeMatrix C = new SafeMatrix(A.RowCount, B.ColumnCount);

            for (int i = 0; i < A.RowCount; i++)
            {
                for (int j = 0; j < B.ColumnCount; j++)
                {
                    C.m_Elements[i * C.m_ColumnCount + j] = Dot(A, i, B, j);
                }
            }

            return C;
        }