Ejemplo n.º 1
0
        /// <summary>
        /// 行基本変形による頭の単位化を実行します。
        /// </summary>
        /// <returns>Rank を返します。</returns>
        internal int _Identicalize()
        {
            int cmin = System.Math.Min(height, width);

            bool[] sweeped = new bool[this.height];

            for (int c = 0; c < cmin; c++)
            {
                // 列 c で最大の絶対値を持つ物 l_m
                Rational max = -1;
                int      l_m = -1;
                for (int l = 0; l < height; l++)
                {
                    Rational cand = Rational.Abs(vals[l, c]);
                    if (!sweeped[l] && Rational.Abs(vals[l, c]) > max)
                    {
                        max = cand;
                        l_m = l;
                    }
                }

                if (vals[l_m, c].IsZero)
                {
                    return(c);
                }

                // pivot[l_m,c] で掃き出し
                if (vals[l_m, c] != Rational.One)
                {
                    lines.Divide(l_m, this.vals[l_m, c]);
                }

                for (int l = 0; l < height; l++)
                {
                    if (l == l_m || vals[l, c].IsZero)
                    {
                        continue;
                    }
                    lines.SubtractLine(l, l_m, vals[l, c]);
                }

                sweeped[l_m] = true;
            }

            // 並び替え
            for (int c = 0; c < height; c++)
            {
                for (int l = c; l < height; l++)
                {
                    if (vals[l, c] == Rational.One)
                    {
                        lines.ExchangeLines(l, c);
                        break;
                    }
                }
            }

            return(cmin);
        }
Ejemplo n.º 2
0
        public static string Calc1()
        {
            Rational hf = new Rational(1, 2);
            Matrix   m  = new Matrix(new ksh.Rational[, ] {
                { 1, new Rational(1, 2), 0, -1, 1 },
                { 1, -new Rational(3, 2), -1, 1, 0 },
            });

            int cmin = System.Math.Min(m.Height, m.Width);

            bool[] sweeped = new bool[m.Height];
            for (int c = 0; c < cmin; c++)
            {
                // 列 c で最大の絶対値を持つ物 l_m
                Rational max = -1; int l_m = -1;
                for (int l = 0; l < m.Height; l++)
                {
                    Rational cand = Rational.Abs(m[l, c]);
                    if (!sweeped[l] && Rational.Abs(m[l, c]) > max)
                    {
                        max = cand;
                        l_m = l;
                    }
                }

                if (m[l_m, c].IsZero)
                {
                    continue;
                }

                if (m[l_m, c] != Rational.One)
                {
                    m.Lines.Divide(l_m, m[l_m, c]);
                }

                for (int l = 0; l < m.Height; l++)
                {
                    if (l == l_m || m[l, c].IsZero)
                    {
                        continue;
                    }
                    m.Lines.SubtractLine(l, l_m, m[l, c]);
                }

                sweeped[l_m] = true;
            }

            return(m.ToHtml());
        }
Ejemplo n.º 3
0
        public static string InverseMatrix()
        {
            Matrix m = new Matrix(new ksh.Rational[, ] {
                { 3, 0, 2 },
                { 5, 4, 6 },
                { 2, 7, -4 },
            });

            System.Text.StringBuilder build = new System.Text.StringBuilder();
            build.Append("<h1>逆行列の求め方</h1>\r\n");
            build.Append("<p>以下の行列の逆行列を求めたいと思います。</p>\r\n");
            build.Append("<p>" + m.ToHtml() + "</p>\r\n");

            build.Append("<p>先ず右から単位行列をくっつけます。</p>\r\n");
            m |= Matrix.Identical(m.Height);
            build.Append("<p>" + m.ToHtml() + "</p>\r\n");

            bool[] sweeped = new bool[m.Height];
            for (int c = 0; c < 3; c++)
            {
                // 列 c で最大の絶対値を持つ物 l_m (既に掃き出した物は除く)
                Rational max = -1; int l_m = -1;
                for (int l = 0; l < m.Height; l++)
                {
                    Rational cand = Rational.Abs(m[l, c]);
                    if (!sweeped[l] && Rational.Abs(m[l, c]) > max)
                    {
                        max = cand;
                        l_m = l;
                    }
                }

                if (m[l_m, c].IsZero)
                {
                    build.Append("<p>やっぱり何だか求められない雰囲気です...</p>");
                    break;
                }

                build.AppendFormat("<p>({0},{1}) 成分に注目します。これが 1 に為る様に行全体を割り算します。</p>\r\n", l_m + 1, c + 1);
                if (m[l_m, c] == Rational.One)
                {
                    build.Append("<p>(と思ったら、元から 1 でした...)</p>\r\n");
                }
                else
                {
                    m.Lines.Divide(l_m, m[l_m, c]);
                    build.Append("<p>" + m.ToHtml() + "</p>\r\n");
                }

                build.AppendFormat("<p>次に ({0},{1}) 成分を使って掃き出しを実行します。</p>\r\n", l_m + 1, c + 1);
                bool haki = false;
                for (int l = 0; l < m.Height; l++)
                {
                    if (l == l_m || m[l, c].IsZero)
                    {
                        continue;
                    }
                    haki = true;
                    build.AppendFormat("<p>{0} 行目から ({1} 行目)×{2} を引き去ります</p>\r\n", l + 1, l_m + 1, m[l, c].ToHtml());
                    m.Lines.SubtractLine(l, l_m, m[l, c]);
                    build.Append("<p>" + m.ToHtml() + "</p>\r\n");
                }
                if (!haki)
                {
                    build.Append("<p>と思ったら、元から掃き出された形になっているので次に進みます。</p>\r\n");
                }

                sweeped[l_m] = true;
            }

            return(build.ToString());
        }