コード例 #1
0
 /// <summary>
 /// Returns the minimal absolute distance between the components of
 /// the two matrices.
 /// </summary>
 public static __ftype__ DistanceMin(__nmtype__ a, __nmtype__ b)
 {
     return(Fun.Min(     /*# n.ForEach(i => { */
                Fun.Min( /*# m.ForEach(j => { */
                    Fun.Abs(b.M__i____j__ - a.M__i____j__) /*#
                                                            * }, comma); */) /*# }, comma); */));
 }
コード例 #2
0
 /// <summary>
 /// Perform a QR factorization of the supplied m x n matrix using
 /// Householder transofmations, i.e. A = QR, where Q is orthogonal
 /// (a product of n-2 Householder-Transformations) and R is a right
 /// upper n x n triangular matrix. An array of the diagonal elements
 /// of R is returned. WARNING: the supplied matrix A is overwritten
 ///  with its factorization QR, both in the parameter aqr.
 /// </summary>
 public static double[] QrFactorize(
     this Matrix <double> aqr)
 {
     double[] diag = new double[Fun.Min(aqr.SX, aqr.SY)];
     aqr.Data.QrFactorize(aqr.Origin, aqr.DX, aqr.DY, aqr.SX, aqr.SY, diag);
     return(diag);
 }
コード例 #3
0
        /// <summary>
        /// Fills the target array starting at offset with normalized
        /// Lerp/weighted combinations of the source array.
        /// </summary>
        public static Array LerpAndNormalizeTo(
            this Array source,
            IEnumerable <WeightedIndex[]> weightedIndexArrays,
            Array target, int offset)
        {
            int length = Fun.Min(weightedIndexArrays.Count(), target.Length - offset);

            return(source.LerpAndNormalizeTo(weightedIndexArrays, target, offset, length));
        }
コード例 #4
0
        // Note that this version of the LU factorization is mostly provided
        // for studying the algorithm. In practice the Matrix<double> version
        // is noticeably faster, since it performs incremental indexing.

        /// <summary>
        /// Perform a partially pivoting LU factorization of the supplied
        /// matrix, i.e A = inv(P) LU, so that any matrix equation A x = b
        /// can be solved using LU x = P b. The permutation matrix P is
        /// returns as permutation vector. WARNING: the supplied matrix A is
        /// overwritten with its factorization LU, both in the parameter alu.
        /// If the matrix is singular an ArgumentException is thrown.
        /// </summary>
        public static int[] LuFactorize(this double[,] alu)
        {
            int n = Fun.Min(alu.GetLength(0), alu.GetLength(1));

            int[] perm = new int[n];
            if (alu.LuFactorize(perm))
            {
                return(perm);
            }
            throw new ArgumentException("singular matrix");
        }
コード例 #5
0
        /// <summary>
        /// Perform the supplied action for all triples of items from
        /// each of the supplied arrays.
        /// The action gets the index of the item as last parameter.
        /// </summary>
        public static void ForEach <T0, T1, T2>(
            this T0[] array0, T1[] array1, T2[] array2,
            Action <T0, T1, T2, int> item0_item1_item2_i_act)
        {
            int count = Fun.Min(array0.Length, array1.Length, array2.Length);

            for (int i = 0; i < count; i++)
            {
                item0_item1_item2_i_act(array0[i], array1[i], array2[i], i);
            }
        }
コード例 #6
0
        /// <summary>
        /// Perform the supplied action for all pairs of items in the array
        /// and from the second array.
        /// </summary>
        public static void ForEach <T0, T1>(
            this T0[] array0, T1[] array1,
            Action <T0, T1> item0_item1_act)
        {
            int count = Fun.Min(array0.Length, array1.Length);

            for (int i = 0; i < count; i++)
            {
                item0_item1_act(array0[i], array1[i]);
            }
        }
コード例 #7
0
        /// <summary>
        /// Return the inverse inv(A) of a the supplied LU factorized matrix
        /// lu, where A = inv(P) LU. The permuation matrix P is supplied as
        /// the permutation vector p.
        /// </summary>
        public static double[,] LuInverse(this double[,] lu, int[] p)
        {
            int n = Fun.Min(lu.GetLength(0), lu.GetLength(1));

            if (n != p.GetLength(0))
            {
                throw new ArgumentException();
            }
            double[,] inv = new double[n, n];
            lu.LuInverse(p, inv);
            return(inv);
        }
コード例 #8
0
        public static Tr[] Map2 <T0, T1, Tr>(
            this IList <T0> xs0, IList <T1> xs1, Func <T0, T1, int, Tr> item0_item1_index_fun)
        {
            var len    = Fun.Min(xs0.Count, xs1.Count);
            var result = new Tr[len];

            for (var i = 0; i < len; i++)
            {
                result[i] = item0_item1_index_fun(xs0[i], xs1[i], i);
            }
            return(result);
        }
コード例 #9
0
        public static List <Tr> Map2 <T0, T1, Tr>(
            this List <T0> list0, List <T1> list1, Func <T0, T1, Tr> item0_item1_fun)
        {
            var count  = Fun.Min(list0.Count, list1.Count);
            var result = new List <Tr>(count);

            for (var i = 0; i < count; i++)
            {
                result.Add(item0_item1_fun(list0[i], list1[i]));
            }
            return(result);
        }
コード例 #10
0
        /// <summary>
        /// Solve a matrix equation of the form LU x = P b.
        /// LU is the supplied factorized matrix lu, P is a permutation matrix
        /// supplied as a permutation array p, and b is the right hand side
        /// supplied as a vector. The returned x satisfies the equation.
        /// </summary>
        public static double[] LuSolve(this double[,] lu, int[] p, double[] b)
        {
            int n = Fun.Min(lu.GetLength(0), lu.GetLength(1));

            if (n != p.GetLength(0))
            {
                throw new ArgumentException();
            }
            if (n > b.GetLength(0))
            {
                throw new ArgumentException();
            }
            var x = new double[n];

            lu.LuSolve(p, b, x);
            return(x);
        }
コード例 #11
0
        public static bool IsTrueFor(long value)
        {
            if (value < 0)
            {
                return(false);
            }
            if (value < isPrimeArray.Length)
            {
                return(isPrimeArray[value]);
            }

            int root           = (int)Fun.Sqrt(value);
            int directMaxPrime = Fun.Min(primeArray[primeCount - 1], root);
            int pi;

            for (pi = 0; primeArray[pi] <= directMaxPrime; pi++)
            {
                if (value % primeArray[pi] == 0)
                {
                    return(false);
                }
            }

            if (directMaxPrime == root)
            {
                return(true);
            }

            while (true)
            {
                int p = Prime.WithIndex(pi);
                if (p > root)
                {
                    break;
                }
                if (value % p == 0)
                {
                    return(false);
                }
                pi++;
            }
            return(true);
        }
コード例 #12
0
 public void Log(LogMsg msg)
 {
     if (msg.Type == LogType.End)
     {
         if (m_state.Buffer.Length > 0 &&
             (m_state.Type == LogType.Info ||
              (m_state.Type != LogType.Unknown && m_state.LeftPos != msg.LeftPos)))    // different indent == other job
         {
             WriteAct(m_state.TIdx, m_state.Type, m_state.Level, m_state.GetBufferLineAndClear());
         }
         if ((msg.Opt & (LogOpt.Timed | LogOpt.NewText)) == 0)
         {
             return;                                                  // if End is not timed, suppress repeated start message
         }
     }
     if (msg.Type == LogType.Progress && !AllowBackspace)
     {
         msg.Opt |= LogOpt.EndLine;
     }
     if (LogCompleteLinesOnly)
     {
         if (msg.Type == LogType.Begin)
         {
             msg.Opt = msg.Opt | LogOpt.EndLine; if ((msg.Opt & LogOpt.Timed) != 0)
             {
                 msg.RightText = "";
             }
         }
         else if (msg.Type == LogType.Progress)
         {
             msg.Opt = msg.Opt | LogOpt.EndLine;
         }
     }
     else if (m_state.Type == LogType.Begin)
     {
         if (msg.Type == LogType.End)
         {
             var pos = m_state.LeftPos + m_state.PrefixLength; var len = m_state.Buffer.Length - pos;
             if (len > 0 && // len < 0 if we are from a different indent == other job
                 msg.LeftText.StartsWith(m_state.Buffer.ToString(pos, len)))
             {
                 msg.LeftText = msg.LeftText.Substring(len); msg.LeftPos = 0;
             }
         }
         else if (msg.Type == LogType.Progress)
         {
             msg.LeftText = null;
         }
         else if ((msg.Opt & LogOpt.Wrap) == 0)
         {
             if (m_state.Timed)
             {
                 m_state.AddDotsText(m_state.RightPos, "", m_width);                // dots to line end
             }
             WriteAct(m_state.TIdx, m_state.Type, m_state.Level, m_state.GetBufferLineAndClear());
         }
     }
     else if (m_state.Type == LogType.Progress)
     {
         if (msg.Type == LogType.Progress)
         {
             if (AllowBackspace)
             {
                 if (m_state.DoneCount > 0)
                 {
                     WriteAct(m_state.TIdx, msg.Type, msg.Level, m_state.Backspace(msg.RightText.Length));
                     msg.LeftText = null;
                 }
                 else
                 {
                     m_state.Buffer.Clear();
                 }
             }
         }
         else if (msg.Type == LogType.End)
         {
             if (AllowBackspace)
             {
                 if (m_state.DoneCount > 0)
                 {
                     var len = m_state.Buffer.Length - m_state.PrefixLength - m_state.LeftPos;
                     WriteAct(m_state.TIdx, msg.Type, msg.Level, m_state.Backspace(len));
                 }
                 else
                 {
                     m_state.Buffer.Clear();
                 }
             }
         }
         else
         {
             WriteAct(m_state.TIdx, m_state.Type, m_state.Level, m_state.GetBufferLineAndClear());
         }
     }
     if ((msg.Opt & LogOpt.Wrap) != 0)
     {
         if (m_state.Buffer.Length + msg.LeftText.Length + 1 > Width + msg.RightPos)
         {
             WriteAct(m_state.TIdx, m_state.Type, m_state.Level, m_state.GetBufferLineAndClear());
         }
         else if (m_state.Buffer.Length > 0 && m_state.Buffer[m_state.Buffer.Length - 1] != ' ')
         {
             m_state.Buffer.Append(' ');
         }
     }
     if (m_state.Buffer.Length == 0)
     {
         m_state.Buffer.Append(m_state.Prefix);
     }
     if (msg.LeftText != null)
     {
         m_state.AddSpaceText(Fun.Min(msg.LeftPos, m_maxIndent), msg.LeftText);
     }
     if (msg.RightText != null)
     {
         m_state.AddDotsText(Fun.Min(msg.RightPos, m_width), msg.RightText, m_width);
     }
     if ((msg.Opt & LogOpt.EndLine) != 0)
     {
         WriteAct(m_state.TIdx, msg.Type, msg.Level, m_state.GetBufferLineAndClear());
         m_state.Type = LogType.Unknown;
     }
     else
     {
         if (!LogCompleteLinesOnly)
         {
             int pos = m_state.DoneCount; int len = m_state.Buffer.Length - pos;
             WriteAct(m_state.TIdx, msg.Type, msg.Level, m_state.Buffer.ToString(pos, len));
             m_state.DoneCount = pos + len;
         }
         m_state.Type     = msg.Type;
         m_state.Timed    = (msg.Opt & LogOpt.Timed) != 0;
         m_state.LeftPos  = msg.LeftPos;
         m_state.RightPos = msg.RightPos; // remember EndPos of timed begins for dotting to lineEnd
     }
     m_state.Level = msg.Level;
 }
コード例 #13
0
        /// <summary>
        /// Returns the rotation of the supplied counter clockwise enumerated
        /// convex polygon that results in the minimum area enclosing box.
        /// If multiple rotations are within epsilon in their area, the one
        /// that is closest to an axis-aligned rotation (0, 90, 180, 270) is
        /// returned. O(n).
        /// </summary>
        public static M22d ComputeMinAreaEnclosingBoxRotation(
            this Polygon2d polygon, double epsilon = 1e-6)
        {
            polygon = polygon.WithoutMultiplePoints(epsilon);
            var pc = polygon.PointCount;

            if (pc < 2)
            {
                return(M22d.Identity);
            }
            var ea = polygon.GetEdgeArray();

            ea.Apply(v => v.Normalized);

            int i0 = 0, i1 = 0;
            int i2 = 0, i3 = 0;
            var min = polygon[0]; var max = polygon[0];

            for (int pi = 1; pi < pc; pi++)
            {
                var p = polygon[pi];
                if (p.Y < min.Y)
                {
                    i0 = pi; min.Y = p.Y;
                }
                else if (p.Y > max.Y)
                {
                    i2 = pi; max.Y = p.Y;
                }
                if (p.X > max.X)
                {
                    i1 = pi; max.X = p.X;
                }
                else if (p.X < min.X)
                {
                    i3 = pi; min.X = p.X;
                }
            }

            V2d p0 = polygon[i0], e0 = ea[i0], p1 = polygon[i1], e1 = ea[i1];
            V2d p2 = polygon[i2], e2 = ea[i2], p3 = polygon[i3], e3 = ea[i3];

            int end0 = (i0 + 1) % pc, end1 = (i1 + 1) % pc;
            int end2 = (i2 + 1) % pc, end3 = (i3 + 1) % pc;
            var dir = V2d.XAxis;

            var best      = dir;
            var bestArea  = double.MaxValue;
            var bestValue = double.MaxValue;

            while (true)
            {
                var s0 = Fun.FastAtan2(e0.Dot90(dir), e0.Dot(dir));
                var s1 = Fun.FastAtan2(e1.Dot180(dir), e1.Dot90(dir));
                var s2 = Fun.FastAtan2(e2.Dot270(dir), e2.Dot180(dir));
                var s3 = Fun.FastAtan2(e3.Dot(dir), e3.Dot270(dir));

                int si, si01, si23; double s01, s23;
                if (s0 < s1)
                {
                    s01 = s0; si01 = 0;
                }
                else
                {
                    s01 = s1; si01 = 1;
                }
                if (s2 < s3)
                {
                    s23 = s2; si23 = 2;
                }
                else
                {
                    s23 = s3; si23 = 3;
                }
                if (s01 < s23)
                {
                    si = si01;
                }
                else
                {
                    si = si23;
                }

                if (si == 0)
                {
                    dir = ea[i0];
                }
                else if (si == 1)
                {
                    dir = ea[i1].Rot270;
                }
                else if (si == 2)
                {
                    dir = ea[i2].Rot180;
                }
                else
                {
                    dir = ea[i3].Rot90;
                }

                double sx = (p2 - p0).Dot90(dir), sy = (p1 - p3).Dot(dir);
                double area  = sx * sy;
                double value = Fun.Min(Fun.Abs(dir.X), Fun.Abs(dir.Y));

                if (area < bestArea - epsilon ||
                    (area < bestArea + epsilon && value < bestValue))
                {
                    bestArea = area; bestValue = value; best = dir;
                }

                if (si == 0)
                {
                    if (++i0 >= pc)
                    {
                        i0 -= pc;
                    }
                    if (i0 == end1)
                    {
                        break;
                    }
                    p0 = polygon[i0]; e0 = ea[i0];
                }
                else if (si == 1)
                {
                    if (++i1 >= pc)
                    {
                        i1 -= pc;
                    }
                    if (i1 == end2)
                    {
                        break;
                    }
                    p1 = polygon[i1]; e1 = ea[i1];
                }
                else if (si == 2)
                {
                    if (++i2 >= pc)
                    {
                        i2 -= pc;
                    }
                    if (i2 == end3)
                    {
                        break;
                    }
                    p2 = polygon[i2]; e2 = ea[i2];
                }
                else
                {
                    if (++i3 >= pc)
                    {
                        i3 -= pc;
                    }
                    if (i3 == end0)
                    {
                        break;
                    }
                    p3 = polygon[i3]; e3 = ea[i3];
                }
            }
            return(new M22d(best.X, best.Y, -best.Y, best.X));
        }
コード例 #14
0
 /// <summary>
 /// Perform a QR factorization of the supplied m x n matrix using
 /// Householder transofmations, i.e. A = QR, where Q is orthogonal
 /// (a product of n-2 Householder-Transformations) and R is a right
 /// upper n x n triangular matrix. An array of the diagonal elements
 /// of R is returned. WARNING: the supplied matrix A is overwritten
 ///  with its factorization QR, both in the parameter aqr.
 /// </summary>
 public static double[] QrFactorize(this double[,] aqr)
 {
     double[] diag = new double[Fun.Min(aqr.GetLength(0), aqr.GetLength(1))];
     aqr.QrFactorize(diag);
     return(diag);
 }