Exemple #1
0
        public static SafeMatrix SolveLinearSystem(SafeMatrix A, SafeMatrix X)
        {
            double[] a = A.GetElements();
            double[] x = X.GetElements();
            double[] y = new double[A.ColumnCount * X.ColumnCount];

            SolveLinearSystem(a, A.RowCount, A.ColumnCount, x, X.RowCount, X.ColumnCount, y);

            SafeMatrix rv = new SafeMatrix(X.RowCount, X.ColumnCount);
            rv.SetElements(y);

            return rv;
        }
Exemple #2
0
        /// <summary>
        /// Warning: This method is not thread safe!
        /// </summary>
        public static SafeMatrix SolveLinearSystemFast(SafeMatrix A, SafeMatrix X)
        {
            if (A.RowCount > 35 * 35)
                throw new InvalidOperationException("Not a PSF fitting linear system.");

            if (s_NumVariables != A.ColumnCount)
            {
                LinearSystemFastInitialiseSolution(A.ColumnCount, 35 * 35);
                s_NumVariables = A.ColumnCount;
            }

            double[] a = A.GetElements();
            double[] x = X.GetElements();
            double[] y = new double[A.ColumnCount * X.ColumnCount];

            SolveLinearSystemFast(a, x, A.RowCount, y);

            SafeMatrix rv = new SafeMatrix(X.RowCount, X.ColumnCount);
            rv.SetElements(y);

            return rv;
        }
Exemple #3
0
        public void Solve()
        {
            if (m_XValues.Count < 3)
                throw new InvalidOperationException("Cannot get a linear fit from less than 3 points.");

            SafeMatrix A = new SafeMatrix(m_XValues.Count, 2);
            SafeMatrix X = new SafeMatrix(m_XValues.Count, 1);

            for (int i = 0; i < m_XValues.Count; i++)
            {
                A[i, 0] = m_XValues[i];
                A[i, 1] = 1;

                X[i, 0] = m_YValues[i];
            }

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

            m_A = bx[0, 0];
            m_B = bx[1, 0];
        }
Exemple #4
0
        // I(x, y) = IBackground + IStarMax * Exp ( -((x - X0)*(x - X0) + (y - Y0)*(y - Y0)) / (r0 * r0))
        private void NonLinearFit(uint[,] intensity, bool useNativeMatrix)
        {
            m_IsSolved = false;

            try
            {
                int full_width = (int)Math.Round(Math.Sqrt(intensity.Length));

                m_MatrixSize = full_width;

                int half_width = full_width / 2;

                m_HalfWidth = half_width;

                switch (DataRange)
                {
                    case PSFFittingDataRange.DataRange8Bit:
                        m_Saturation = Properties.Settings.Default.Saturation8Bit;
                        break;

                    case PSFFittingDataRange.DataRange12Bit:
                        m_Saturation = Properties.Settings.Default.Saturation12Bit;
                        break;

                    case PSFFittingDataRange.DataRange14Bit:
                        m_Saturation = Properties.Settings.Default.Saturation14Bit;
                        break;

                    default:
                        m_Saturation = Properties.Settings.Default.Saturation8Bit;
                        break;
                }

                int nonSaturatedPixels = 0;

                double IBackground = 0;
                double r0 = 4.0;
                double IStarMax = 0;

                double found_x = half_width;
                double found_y = half_width;

                for (int iter = NumberIterations; iter > 0; iter--)
                {
                    if (iter == NumberIterations)
                    {
                        uint zval = 0;

                        IBackground = 0.0; /* assume no backgnd intensity at first... */
                        for (int i = 0; i < full_width; i++)
                        {
                            for (int j = 0; j < full_width; j++)
                            {
                                if (intensity[i, j] > zval) zval = intensity[i, j];
                                if (intensity[i, j] < m_Saturation) nonSaturatedPixels++;
                            }
                        }
                        IStarMax = (double)zval - IBackground;
                    }

                    double[] dx = new double[full_width];
                    double[] dy = new double[full_width];
                    double[] fx = new double[full_width];
                    double[] fy = new double[full_width];

                    double r0_squared = r0 * r0;

                    for (int i = 0; i < full_width; i++)
                    {
                        dx[i] = (double)i - found_x;
                        fx[i] = Math.Exp(-dx[i] * dx[i] / r0_squared);
                        dy[i] = (double)i - found_y;
                        fy[i] = Math.Exp(-dy[i] * dy[i] / r0_squared);
                    }

                    SafeMatrix A = new SafeMatrix(nonSaturatedPixels, 5);
                    SafeMatrix X = new SafeMatrix(nonSaturatedPixels, 1);

                    int index = -1;
                    for (int i = 0; i < full_width; i++)
                    {
                        for (int j = 0; j < full_width; j++)
                        {
                            uint zval = intensity[i, j];

                            if (zval < m_Saturation)
                            {
                                index++;

                                double exp_val = fx[i] * fy[j];

                                double residual = IBackground + IStarMax * exp_val - (double)zval;
                                X[index, 0] = -residual;

                                A[index, 0] = 1.0; /* slope in i0 */
                                A[index, 1] = exp_val; /* slope in a0 */
                                A[index, 2] = 2.0 * IStarMax * dx[i] * exp_val / r0_squared;
                                A[index, 3] = 2.0 * IStarMax * dy[j] * exp_val / r0_squared;
                                A[index, 4] = 2.0 * IStarMax * (dx[i] * dx[i] + dy[j] * dy[j]) * exp_val / (r0 * r0_squared);
                            }
                        }
                    }

                    SafeMatrix Y;

                    if (useNativeMatrix)
                    {
                        Y = NativePSFFitting.SolveLinearSystemFast(A, X);
                    }
                    else
                    {
                        SafeMatrix a_T = A.Transpose();
                        SafeMatrix aa = a_T * A;
                        SafeMatrix aa_inv = aa.Inverse();
                        Y = (aa_inv * a_T) * X;
                    }

                    /* we need at least 6 unsaturated pixels to solve 5 params */
                    if (nonSaturatedPixels > 6) /* Request all pixels to be good! */
                    {
                        IBackground += Y[0, 0];
                        IStarMax += Y[1, 0];

                        for (int i = 2; i < 4; i++)
                        {
                            if (Y[i, 0] > 1.0) Y[i, 0] = 1.0;
                            if (Y[i, 0] < -1.0) Y[i, 0] = -1.0;
                        }

                        found_x += Y[2, 0];
                        found_y += Y[3, 0];

                        if (Y[4, 0] > r0 / 10.0) Y[4, 0] = r0 / 10.0;
                        if (Y[4, 0] < -r0 / 10.0) Y[4, 0] = -r0 / 10.0;

                        r0 += Y[4, 0];
                    }
                    else
                    {
                        m_IsSolved = false;
                        return;
                    }
                }

                m_IsSolved = true;
                m_IBackground = IBackground;
                m_IStarMax = IStarMax;
                m_X0 = found_x;
                m_Y0 = found_y;
                m_R0 = r0;

                m_Residuals = new double[full_width, full_width];

                for (int x = 0; x < full_width; x++)
                    for (int y = 0; y < full_width; y++)
                    {
                        m_Residuals[x, y] = intensity[x, y] - GetPSFValueInternal(x, y);
                    }
            }
            catch (DivideByZeroException)
            { }
        }
Exemple #5
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;
        }
Exemple #6
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;
        }
Exemple #7
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;
        }
Exemple #8
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;
        }
Exemple #9
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;
        }
Exemple #10
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;
        }
Exemple #11
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;
        }