⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form1.cs

📁 最小二乘拟合:用C#语言写成的最小二乘法拟合而成的
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace 最小二乘拟合
{
    public partial class Form1 : Form
    {
        int n = 0;
        int linesNo = 1;
        string name = null;
        public Form1()
        {
            InitializeComponent();
        }








        public void 开始拟合ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (n == 0)
            {
                MessageBox.Show("请配置拟合次数!");
                return;
            }//判断拟合次数是否为0
            if (name == null)
            {
                MessageBox.Show("请选择拟合数据!");
                return ;
            }//判断拟合数据是否为空
            if (linesNo <(n+1))
            {
                MessageBox .Show ("拟合次数不得超过"+(linesNo -1)+"次,请重新设定!");
                return ;
            }

            double[,] X=new double [linesNo ,n+1],
                      XT=new double [n+1,linesNo ],
                      XTX=new double [n+1,n+1],
                      XTX1=new double [n+1 ,n+1],
                      XTX1XT=new double [n+1,linesNo];
            double[] x=new double [linesNo ],
                     b = new double[linesNo],
                     y = new double[linesNo];

            StreamReader dataFile = new StreamReader(name );
            linesNo = Int32 .Parse (dataFile.ReadLine());
            for (int i = 0; i < linesNo; i++)
            {
                string temp = dataFile.ReadLine();
                string[] str = System.Text.RegularExpressions.Regex.Split(temp , @"[\t]+");
                x[i] =Convert .ToDouble ( str [0]) ;
                //读取x[i]
                y[i] =Convert .ToDouble  (str [1] );
                //读取y[i]
                for (int j = 0; j < (n + 1); j++)
                {
                    X[i, j] = Math.Pow(x[i], (double)j);
                }//计算矩阵X
            }

            for (int i = 0; i < (n + 1); i++)
            {
                for (int j = 0; j < linesNo; j++)
                {
                    XT[i, j] = X[j, i];
                }
            }//计算X的转置XT            

            for (int i = 0; i < (n + 1); i++)
            {
                for (int j = 0; j < (n + 1); j++)
                {
                    for (int k = 0; k < linesNo ; k++)
                    {
                        XTX[i, j] += XT[i, k] * X[k, j];
                    }
                }
            }//计算XTX

            double[,] newMatrix = XTX;
            int[] T = new int[n+1];
            double alpha = 0;
            for (int k = 0; k < (n+1); k++)
            {
                double w = newMatrix[k, k];
                int I = k;
                T[k] = k;
                for (int i = k + 1; i <(n+1); i++)
                {
                    if (Math.Abs(newMatrix[i, k]) > Math.Abs(w))
                    {
                        w = newMatrix[i, k];
                        I = i;
                    }
                }//选主元
                if (w == 0)
                {
                    MessageBox.Show("Singular!");
                    return;
                }

                if (I != k)
                {
                    T[k] = I;
                    for (int j = 0; j < (n+1); j++)
                    {
                        double temp = newMatrix[k, j];
                        newMatrix[k, j] = newMatrix[I, j];
                        newMatrix[I, j] = temp;
                    }
                }//行交换

                alpha = 1 / newMatrix[k, k];
                newMatrix[k, k] = alpha;
                for (int i = 0; i < (n+1); i++)
                {
                    if (i == k)
                    {
                        continue;
                    }
                    newMatrix[i, k] = (-1) * alpha * newMatrix[i, k];
                }//计算第k列元素

                for (int i = 0; i < (n+1); i++)
                {
                    if (i == k)
                    {
                        continue;
                    }
                    for (int j = 0; j < (n+1); j++)
                    {
                        if (j == k)
                        {
                            continue;
                        }
                        newMatrix[i, j] += newMatrix[i, k] * newMatrix[k, j];
                    }
                }//计算除第k列、k行以外其余元素

                for (int j = 0; j < (n+1); j++)
                {
                    if (j == k)
                    {
                        continue;
                    }
                    newMatrix[k, j] = alpha * newMatrix[k, j];
                }//计算第k行其余元素
            }
            for (int k = n; k >= 0; k--)
            {
                if (T[k] != k)
                {
                    int I = T[k];
                    for (int i = 0; i < (n+1); i++)
                    {
                        double temp = newMatrix[i, I];
                        newMatrix[i, I] = newMatrix[i, k];
                        newMatrix[i, k] = temp;
                    }
                }
            }//列交换
            XTX1 = newMatrix;
            //计算XTX的逆矩阵

            for (int i = 0; i < (n + 1); i++)
            {
                for (int j = 0; j < linesNo; j++)
                {
                    for (int k = 0; k < (n + 1); k++)
                    {
                        XTX1XT[i, j] += XTX1[i, k] * XT[k, j];
                    }
                }
            }//计算XTX的逆与XT的乘积

            for (int i = 0; i < (n+1); i++)
            {
                for (int k = 0; k < linesNo; k++)
                {
                    b[i] += XTX1XT[i, k] * y[k];
                    double temp = b[i] * x[i];
                    chart1.Series["拟合曲线"].Points.AddXY(x[i], temp);
                    chart1.Invalidate();
                }
            }//计算最小二乘解b[]

       }//拟合过程





        private void 使用方法ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("help.html");
        }//打开帮助文件









        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }//退出











        private void 选择数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LabelX.Text = "X:";//显示X的条数
            LabelY.Text = "Y:";//显示Y的条数
            chart1.Series["原始曲线"].Points.Clear();//图形清空

            openFileDialog1.ShowDialog();//打开文件
            name = openFileDialog1.FileName;
            if (openFileDialog1.FileName == "")
            {
                return;
            }
            if (!name.EndsWith(".txt"))
            {
                MessageBox.Show("数据格式为文本文件,请重新选择!");
                return;
            }//打开数据文件
            //System.Diagnostics.Process.Start(openFileDialog1 .FileName );

            dataGridView1.Rows.Clear();//数据清空
            StreamReader dataFile = new StreamReader(name);
            linesNo = Int32.Parse(dataFile.ReadLine());//记录条数
            double[,] data = new double[linesNo, 2];
            for (int i = 0; i < linesNo; i++)
            {
                string temp = dataFile.ReadLine();
                string[] str = System.Text.RegularExpressions.Regex.Split(temp, @"[\t]+");
                for (int j = 0; j < 2; j++)
                {
                    data[i, j] = Convert.ToDouble(str[j]);

                }
                dataGridView1.Rows.Add(data[i, 0], data[i, 1]);//向DBview中添加记录
                //chart1.Series.Clear();
                //chart1.Invalidate();
                chart1.Series["原始曲线"].Points.AddXY(data[i,0],data [i,1]);
                chart1.Invalidate();//画图
            }
            LabelX.Text += linesNo;//显示新的X的条数
            LabelY.Text += linesNo;//显示新的Y的条数
            //读取数据并显示
        }










        private void 拟合次数ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();//新窗体
            n = Int32.Parse(f2.textBox1.Text);
        }//读取拟合次数








        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog2.ShowDialog();
            //string name=openFileDialog2 .FileName ; 
            try
            {
                System.Diagnostics.Process.Start(openFileDialog2.FileName);
            }
            catch (IOException)
            {
                MessageBox.Show("Error","无法打开文件!",MessageBoxButtons.OK,MessageBoxIcon .Error );
            }
        }





        private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog();
        }




        private void 清空ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            chart1.Series["原始曲线"].Points.Clear();
            chart1.Series["拟合曲线"].Points.Clear();
            chart1.Invalidate();
        }//数据,图像清空







    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -