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()); } }
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); }
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); }
//行列式值计算 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); }