zoukankan      html  css  js  c++  java
  • Guass列选主元消去法和三角分解法

      最近数值计算学了Guass列主消元法和三角分解法解线性方程组,具体原理如下:

    1Guass列选主元消去法对于AX =B 

    1)、消元过程:将(A|B)进行变换为,其中是上三角矩阵。即:

    k1n-1

    a、 列选主元

        选取第k列中绝对值最大元素作为主元。

    b、 换行

             

    c、 归一化

             

    d、 消元

            

    2)、回代过程:由解出。

            

    2三角分解法(Doolittle分解)

    A分解为如下形式

     

    由矩阵乘法原理

    a、计算U的第一行,再计算L的第一列

     

    b、设已求出U1r-1行,L1r-1列。先计算U的第r行,再计算L的第r列。

    a)计算Ur

     

     

    b)计算Lr

     

     

    C#代码:

      代码说明:Guass列主消元法部分将计算出来的根仍然储存在增广矩阵的最后一列,而Doolittle分解,将分解后的结果也储存至原来的数组中,这样可以节约空间。。

    using System;
    using System.Windows.Forms;
    
    namespace Test
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Cannel_Button_Click(object sender, EventArgs e)
            {
                this.textBox1.Clear();
                this.textBox2.Clear();
                this.textBox3.Clear();
                this.comboBox1.SelectedIndex = -1;
            }
            public double[,] GetNum(string str, int n)
            {
                string[] strnum = str.Split(' ');
                double[,] a = new double[n, n + 1];
                int k = 0;
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < strnum.Length / n; j++)
                    {
                        a[i, j] = double.Parse((strnum[k]).ToString());
                        k++;
                    }
                }
                return a;
            }
            public void Gauss(double[,] a, int n)
            {
                int i, j;
                SelectColE(a, n);
                for (i = n - 1; i >= 0; i--)
                {
                    for (j = i + 1; j < n; j++)
                        a[i, n] -= a[i, j] * a[j, n];
                    a[i, n] /= a[i, i];
                }
            }
            //选择列主元并进行消元  
            public void SelectColE(double[,] a, int n)
            {
                int i, j, k, maxRowE;
                double temp; //用于记录消元时的因数  
                for (j = 0; j < n; j++)
                {
                    maxRowE = j;
                    for (i = j; i < n; i++)
                        if (System.Math.Abs(a[i, j]) > System.Math.Abs(a[maxRowE, j]))
                            maxRowE = i;
                    if (maxRowE != j)
                        swapRow(a, j, maxRowE, n);   //与最大主元所在行交换  
                                                     //消元  
                    for (i = j + 1; i < n; i++)
                    {
                        temp = a[i, j] / a[j, j];
                        for (k = j; k < n + 1; k++)
                            a[i, k] -= a[j, k] * temp;
                    }
                }
                return;
            }
            public void swapRow(double[,] a, int m, int maxRowE, int n)
            {
                int k;
                double temp;
                for (k = m; k < n + 1; k++)
                {
                    temp = a[m, k];
                    a[m, k] = a[maxRowE, k];
                    a[maxRowE, k] = temp;
                }
            }
            public void Doolittle(double[,] a, int n)
            {
                for (int i = 0; i < n; i++)
                {
                    if (i == 0)
                    {
                        for (int j = i + 1; j < n; j++)
                            a[j, 0] = a[j, 0] / a[0, 0];
                    }
                    else
                    {
                        double temp = 0, s = 0;
                        for (int j = i; j < n; j++)
                        {
                            for (int k = 0; k < i; k++)
                            {
                                temp = temp + a[i, k] * a[k, j];
                            }
                            a[i, j] = a[i, j] - temp;
                        }
                        for (int j = i + 1; j < n; j++)
                        {
                            for (int k = 0; k < i; k++)
                            {
                                s = s + a[j, k] * a[k, i];
                            }
                            a[j, i] = (a[j, i] - s) / a[i, i];
                        }
                    }
                }
            }
            private void Exit_Button_Click(object sender, EventArgs e)
            {
                this.Close();
            }
    
            private void Confirm_Button_Click(object sender, EventArgs e)
            {
                if (this.textBox2.Text.Trim().ToString().Length == 0)
                {
                    this.textBox2.Text = this.textBox1.Text.Trim();
                }
                else
                {
                    this.textBox2.Text = this.textBox2.Text + "
    " + this.textBox1.Text.Trim();
                }
                this.textBox1.Clear();
            }
    
            private void Calculate_Button_Click(object sender, EventArgs e)
            {
                string str = this.textBox2.Text.Trim().ToString();
                string myString = str.Replace("
    ", " ").Replace("
    ", string.Empty);
                double[,] a = new double[this.textBox2.Lines.GetUpperBound(0) + 1, this.textBox2.Lines.GetUpperBound(0) + 2];
                a = GetNum(myString, this.textBox2.Lines.GetUpperBound(0) + 1);
                if (this.comboBox1.Text == "Guass列主消元法")
                {
                    Gauss(a, this.textBox2.Lines.GetUpperBound(0) + 1);
                    for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++)
                    {
                        this.textBox3.Text = this.textBox3.Text + "
    X" + (i + 1) + "=" + a[i, this.textBox2.Lines.GetUpperBound(0) + 1];
                    }
                }
                else if (this.comboBox1.Text == "Doolittle三角分解法")
                {
                    this.textBox3.Enabled = true;
                    Doolittle(a, this.textBox2.Lines.GetUpperBound(0) + 1);
                    this.label3.Text = "分解后的结果:";
                    this.textBox3.Clear();
                    this.textBox3.Text += "L矩阵:
    ";
                    for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++)
                    {
                        for (int j = 0; j < this.textBox2.Lines.GetUpperBound(0) + 1; j++)
                        {
                            if (j < i)
                            {
                                this.textBox3.Text += a[i, j].ToString() + "	";
                            }
                            else if (i == j)
                            {
                                this.textBox3.Text += "1	";
                            }
                            else
                            {
                                this.textBox3.Text += "0	";
                            }
                        }
                        this.textBox3.Text += "
    ";
                    }
                    this.textBox3.Text += "
    U矩阵:
    ";
                    for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++)
                    {
                        for (int j = 0; j < this.textBox2.Lines.GetUpperBound(0) + 1; j++)
                        {
                            if (j >= i)
                            {
                                this.textBox3.Text += a[i, j].ToString() + "	";
                            }
                            else
                            {
                                this.textBox3.Text += "0	";
                            }
                        }
                        this.textBox3.Text += "
    ";
                    }
                }
    
            }
    
            private void textBox1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    if (this.textBox1.Text.Trim().ToString().Length == 0)
                    {
                        Calculate_Button_Click(sender, e);
                    }
                    else
                    {
                        Confirm_Button_Click(sender, e);
                    }
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                this.textBox2.Enabled = true;
            }
        }
    }
    

      运行截图:

      至此完毕。。。。

  • 相关阅读:
    基于摸板匹配的目標跟蹤算法
    spoj 2713 Can you answer these queries IV
    zoj 3633 Alice's present
    hdu 3642 Get The Treasury
    poj 1195 Mobile phones
    poj 2760 End of Windless Days
    zoj 3540 Adding New Machine
    spoj 1716 Can you answer these queries III
    spoj 1043 Can you answer these queries I
    spoj 2916 Can you answer these queries V
  • 原文地址:https://www.cnblogs.com/czx1/p/5438136.html
Copyright © 2011-2022 走看看