Ejemplo n.º 1
0
        private void button_Regression_Click(object sender, EventArgs e)
        {
            string ColNums = textBox_Cols.Text;
            char[] separator = { ',' };
            //string是以逗号分隔的
            string[] AllNum = ColNums.Split(separator);
            //按照逗号分割
            List<int> Cols = new List<int>();
            foreach (string SingleNum in AllNum)
            {
                if (SingleNum != "")
                {
                    Cols.Add(Convert.ToInt32(SingleNum) - 1);
                }
            }

            int[] AllColNums = Cols.ToArray();
            int yCol = Tabulation.FindCol(MainForm.MainDT,comboBox_y.Text);
            List<List<string>> data = new List<List<string>>();
            int RowsCount = MainForm.MainDT.Rows.Count;
            int  InputColsCount = AllColNums.Length;
            //计算总共要录入的列数
            int count = 0;
            //计算实际录入数据数
            List<string>Ydata = new List<string>();
            for (int i = 0; i < InputColsCount; i++)
            {
                data.Add(new List<string>());
            }
                for (int i = 0; i < RowsCount; i++)
                {
                    if (Tabulation.IdentifyNARow(MainForm.MainDT, i, AllColNums))
                    {
                        //确认该行无空格
                        if (MainForm.MainDT.Rows[i][yCol].ToString().Trim() != "")
                        {
                            Ydata.Add(MainForm.MainDT.Rows[i][yCol].ToString().Trim());
                            for (int j = 0; j < InputColsCount; j++)
                            {
                                data[j].Add(MainForm.MainDT.Rows[i][j].ToString());
                                
                            }
                            count++;
                        }
                    }
                }

            if (count > 2)
            {
                BigDecimal[,] IndependentVariables = new BigDecimal[count, InputColsCount + 1];
                //第一列全是1
                for (int i = 0; i < count; i++)
                {
                    IndependentVariables[i, 0] = 1;
                }
                for (int i = 0; i < count; i++)
                {
                    for (int j = 0; j < InputColsCount; j++)
                    {
                        //录入时,BigDecimal数组列数要+1,因为第一列全是1
                        IndependentVariables[i, j + 1] = data[j][i];
                    }
                }
                BigDecimal[,] DependentVariable = new BigDecimal[count,1];
                for (int i = 0; i < count; i++){
                    DependentVariable[i,0]= Ydata[i];
                }
                BigDecimal[,] bhat = Stat.MultiRegBeta(IndependentVariables, DependentVariable);
                StringBuilder Result = new StringBuilder();
                Result.Append(comboBox_y.Text);
                Result.Append(" = ");
                int ColumnNumberCount = 0;
                foreach (BigDecimal EachNum in bhat)
                {
                    if (ColumnNumberCount == 0)
                    {
                        Result.Append(MathV.NumberPolish(EachNum.ToString()));
                        Result.Append(" + ");
                    }
                    else if (ColumnNumberCount == InputColsCount)
                    {
                        Result.Append(MathV.NumberPolish(EachNum.ToString()));
                        Result.Append(" ");
                        Result.Append(MainForm.MainDT.Columns[AllColNums[ColumnNumberCount-1]].ColumnName);
                    }
                    else
                    {
                        Result.Append(MathV.NumberPolish(EachNum.ToString()));
                        Result.Append(" ");
                        Result.Append(MainForm.MainDT.Columns[AllColNums[ColumnNumberCount - 1]].ColumnName);
                        Result.Append(" + ");
                    }
                    ColumnNumberCount++;
                }
                MainForm.S.richTextBox1.AppendText(Result.ToString());
            }
        }
Ejemplo n.º 2
0
        public static BigDecimal[,] MatInv(BigDecimal[,] dMatrix, int Level)
        {
            BigDecimal dMatrixValue = MatValue(dMatrix, Level);

            if (dMatrixValue == 0)
            {
                return(null);       //A为该矩阵 若|A| =0 则该矩阵不可逆 返回空
            }
            BigDecimal[,] dReverseMatrix = new BigDecimal[Level, 2 * Level];

            BigDecimal x, c;

            // Init Reverse matrix

            for (int i = 0; i < Level; i++)     //创建一个矩阵(A|I) 以对其进行初等变换 求得其矩阵的逆
            {
                for (int j = 0; j < 2 * Level; j++)
                {
                    if (j < Level)
                    {
                        dReverseMatrix[i, j] = dMatrix[i, j];   //该 (A|I)矩阵前 Level列为矩阵A  后面为数据全部为0
                    }
                    else
                    {
                        dReverseMatrix[i, j] = 0;
                    }
                }

                dReverseMatrix[i, Level + i] = 1;
            }



            for (int i = 0, j = 0; i < Level && j < Level; i++, j++)
            {
                if (dReverseMatrix[i, j] == 0)   //判断一行对角线 是否为0
                {
                    int m = i;

                    for (; dMatrix[m, j] == 0; m++)
                    {
                        ;
                    }

                    if (m == Level)
                    {
                        return(null);  //某行对角线为0的时候 判断该行该数据所在的列在该数据后 是否为0 都为0 的话不可逆 返回空值
                    }
                    else
                    {
                        // Add i-row with m-row

                        for (int n = j; n < 2 * Level; n++)   //如果对角线为0 则该i行加上m行 m行为(初等变换要求对角线为1,0-->1先加上某行,下面在变1)

                        {
                            dReverseMatrix[i, n] += dReverseMatrix[m, n];
                        }
                    }
                }

                x = dReverseMatrix[i, j];

                if (x != 1)                  //如果对角线元素不为1  执行以下
                {
                    for (int n = j; n < 2 * Level; n++)
                    {
                        if (dReverseMatrix[i, n] != 0)
                        {
                            dReverseMatrix[i, n] /= x;   //相除  使i行第一个数字为1
                        }
                    }
                }

                // Set 0 to the current column in the rows after current row

                for (int s = Level - 1; s > i; s--)         //该对角线数据为1 时,这一列其他数据 要转换为0
                {
                    x = dReverseMatrix[s, j];

                    for (int t = j; t < 2 * Level; t++)
                    {
                        dReverseMatrix[s, t] -= (dReverseMatrix[i, t] * x);
                    }
                }
            }

            // Format the first matrix into unit-matrix

            for (int i = Level - 2; i >= 0; i--)

            //处理第一行二列的数据 思路如上 就是把除了对角线外的元素转换为0
            {
                for (int j = i + 1; j < Level; j++)
                {
                    if (dReverseMatrix[i, j] != 0)
                    {
                        c = dReverseMatrix[i, j];

                        for (int n = j; n < 2 * Level; n++)
                        {
                            dReverseMatrix[i, n] -= (c * dReverseMatrix[j, n]);
                        }
                    }
                }
            }

            BigDecimal[,] dReturn = new BigDecimal[Level, Level];

            for (int i = 0; i < Level; i++)
            {
                for (int j = 0; j < Level; j++)
                {
                    dReturn[i, j] = dReverseMatrix[i, j + Level];
                }
            }

            return(dReturn);
        }
Ejemplo n.º 3
0
        public static string NumberPolish(string Number)
        {
            //首先要判别输入的数字是否为科学计数法
            int Char_E = Number.IndexOf('E');

            if (Char_E != -1)
            {
                //如果是科学计数法则先转化为常规格式
                Number = (new BigNumber(Number.Substring(0, Char_E - 1))
                          * MathV.Pow(10, Number.Substring(Char_E + 1,
                                                           Number.Length - Char_E - 1))).ToString();
            }
            //目标为控制位数在10位
            Number = Number.Trim();
            int        CountDecimalPoint = 0;
            int        ScientificNumber;
            string     ScientificNotation = "";
            int        digits_part;
            BigDecimal NumberProcess = 0;
            string     ProcessedNumber;

            char[] separator = { '.' };
            //用于分割小数点
            string[] NumberParts = new string[2];
            int      IsNegative  = 0;
            //用来判定数字是否为负
            int zero_count = 0;

            //用于计算小数点后有多少个零
            NumberParts = Number.Split(separator);
            if (NumberParts[0].Length + 5 > 10)
            //四位小数加上1个小数点
            {
                if (Number[0] == '-')
                {
                    IsNegative = 1;
                }
                foreach (char FindDecimalPoint in Number)
                {
                    if (FindDecimalPoint == '.')
                    {
                        CountDecimalPoint = 1;
                        break;
                    }
                }
                if (CountDecimalPoint == 0)
                {
                    //无小数点则只有整数部分
                    ScientificNumber = Number.Length - IsNegative - 1;
                    //转换为科学计数法
                    if (ScientificNumber <= 9 && ScientificNumber > 0)
                    {
                        ScientificNotation = "0" + ScientificNumber.ToString();
                        //如果科学计数法为个位要补零
                    }
                    else
                    {
                        ScientificNotation = ScientificNumber.ToString();
                    }
                    //数字正负无需考虑
                    if (ScientificNotation.Length + 1 + 2 <= 9)
                    {
                        //例如:-3.1415E+05
                        //数字负号占一位,E和科学计数法的符号占两位
                        //大于9的情况不做考虑,数字太大。
                        digits_part = 9 - (ScientificNotation.Length + 1 + 2);
                        //小数位由此算出
                        NumberProcess   = new BigDecimal(Number.ToString()) / Math.Pow(10, ScientificNumber);
                        ProcessedNumber = MathV.round(NumberProcess.ToString(), digits_part, 0) + "E+" + ScientificNotation;
                    }
                    else
                    {
                        //如果已经大于已经大于九位了,则不作处理
                        //这种情况极为罕见,不考虑
                        NumberProcess   = new BigDecimal(Number.ToString()) / Math.Pow(10, ScientificNumber);
                        ProcessedNumber = MathV.round(NumberProcess.ToString(), 0, 0) + "E+" + ScientificNotation;
                    }
                }
                else
                {
                    //有小数点的情况
                    NumberParts = Number.Split(separator);
                    if (NumberParts[0] != "0")
                    {
                        if (NumberParts[0].Length + 1 + 4 >= 9)
                        {
                            //如果保留四位小数之后依旧总长度超过九,则进行如下操作
                            //判断整数部分是否为0
                            //如果不为0,继续科学计数法的处理,舍去小数部分
                            ScientificNumber = NumberParts[0].Length - IsNegative - 1;
                            //转换为科学计数法
                            if (ScientificNumber <= 9 && ScientificNumber > 0)
                            {
                                ScientificNotation = "0" + ScientificNumber.ToString();
                                //如果科学计数法为个位要补零
                            }
                            else
                            {
                                ScientificNotation = ScientificNumber.ToString();
                            }
                            //数字正负无需考虑
                            if (ScientificNotation.Length + 1 + 2 <= 9)
                            {
                                //例如:-3.1415E+05
                                //数字负号占一位,E和科学计数法的符号占两位
                                //大于9的情况不做考虑,数字太大。
                                digits_part = 9 - (ScientificNotation.Length + 1 + 2);
                                //小数位由此算出
                                NumberProcess   = new BigDecimal(Number.ToString()) / Math.Pow(10, ScientificNumber);
                                ProcessedNumber = MathV.round(NumberProcess.ToString(), digits_part, 0) + "E+" + ScientificNotation;
                            }
                            else
                            {
                                //如果已经大于已经大于九位了,则不作处理
                                //这种情况极为罕见,不考虑
                                NumberProcess   = new BigDecimal(Number.ToString()) / Math.Pow(10, ScientificNumber);
                                ProcessedNumber = MathV.round(NumberProcess.ToString(), 0, 0) + "E+" + ScientificNotation;
                            }
                        }
                        else
                        {
                            ProcessedNumber = MathV.round(Number, 4, 0);
                        }
                    }
                    else
                    {
                        zero_count = 0;
                        foreach (char EachDigit in NumberParts[1])
                        {
                            if (EachDigit == '0')
                            {
                                zero_count++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        ScientificNumber = zero_count + 1;
                        //科学计数法的数字为零的个数加1
                        if (ScientificNumber <= 9 && ScientificNumber > 0)
                        {
                            ScientificNotation = "0" + ScientificNumber.ToString();
                            //如果科学计数法为个位要补零
                        }
                        else
                        {
                            ScientificNotation = ScientificNumber.ToString();
                        }
                        if (ScientificNotation.Length + 1 + 2 <= 9)
                        {
                            //例如:-2.654E-05
                            //数字负号占一位,E和科学计数法的符号占两位
                            //大于9的情况不做考虑,数字太大。
                            digits_part = 9 - (ScientificNotation.Length + 1 + 2);
                            //小数位由此算出
                            NumberProcess   = new BigDecimal(Number.ToString()) * Math.Pow(10, ScientificNumber);
                            ProcessedNumber = MathV.round(NumberProcess.ToString(), digits_part, 0) + "E-" + ScientificNotation;
                        }
                        else
                        {
                            //如果已经大于已经大于九位了,则不作处理
                            //这种情况极为罕见,不考虑
                            NumberProcess   = new BigDecimal(Number.ToString()) * Math.Pow(10, ScientificNumber);
                            ProcessedNumber = MathV.round(NumberProcess.ToString(), 0, 0) + "E-" + ScientificNotation;
                        }
                    }
                }
            }
            else
            {
                ProcessedNumber = MathV.round(Number, 4, 0);
                //如果本身长度就在十个单位以内,则不作处理
                //保留四位小数
            }
            if (ProcessedNumber.Length < 11)
            {
                ProcessedNumber = ProcessedNumber.PadLeft(11, ' ');
                //11个单位的长度是为了预留量,以免出现连续进位的情况
            }
            return(ProcessedNumber);
        }
Ejemplo n.º 4
0
        //行列式值计算
        public static BigDecimal MatValue(BigDecimal[,] MatrixList, int Level) //求得|A| 如果为0 说明不可逆
        {
            BigDecimal[,] dMatrix = new BigDecimal[Level, Level];              //定义二维数组,行列数相同

            for (int i = 0; i < Level; i++)
            {
                for (int j = 0; j < Level; j++)
                {
                    dMatrix[i, j] = MatrixList[i, j];     //将参数的值,付给定义的数组
                }
            }
            BigDecimal c, x;
            BigDecimal k = 1;

            for (int i = 0, j = 0; i < Level && j < Level; i++, j++)
            {
                if (dMatrix[i, j] == 0)   //判断对角线上的数据是否为0
                {
                    int m = i;

                    for (; m < Level && dMatrix[m, j] == 0; m++)
                    {
                        ;                                        //如果对角线上数据为0,从该数据开始依次往后判断是否为0
                    }
                    m--;
                    if (m == Level - 1)                      //当该行从对角线开始数据都为0 的时候 返回0

                    {
                        return(0);
                    }

                    else
                    {
                        // Row change between i-row and m-row

                        for (int n = j; n < Level; n++)
                        {
                            c = dMatrix[i, n];

                            dMatrix[i, n] = dMatrix[m, n];

                            dMatrix[m, n] = c;
                        }

                        // Change value pre-value

                        k = k * (-1);
                    }
                }

                // Set 0 to the current column in the rows after current row

                for (int s = Level - 1; s > i; s--)
                {
                    x = dMatrix[s, j];

                    for (int t = j; t < Level; t++)
                    {
                        dMatrix[s, t] -= dMatrix[i, t] * (x / dMatrix[i, j]);
                    }
                }
            }

            BigDecimal sn = 1;

            for (int i = 0; i < Level; i++)
            {
                if (dMatrix[i, i] != 0)
                {
                    sn *= dMatrix[i, i];
                }

                else
                {
                    return(0);
                }
            }

            return(k * sn);
        }