69,382
社区成员
发帖
与我相关
我的任务
分享
// multiple_linear_regression_call.cpp : Defines the entry point for the console application.
//
#include "multiple_linear_regression.h"
#include <stdio.h>
#include <math.h>
double data[15][5] = {
{ 316, 1536, 874, 981, 3894 },
{ 385, 1771, 777, 1386, 4628 },
{ 299, 1565, 678, 1672, 4569 },
{ 326, 1970, 785, 1864, 5340 },
{ 441, 1890, 785, 2143, 5449 },
{ 460, 2050, 709, 2176, 5599 },
{ 470, 1873, 673, 1769, 5010 },
{ 504, 1955, 793, 2207, 5694 },
{ 348, 2016, 968, 2251, 5792 },
{ 400, 2199, 944, 2390, 6126 },
{ 496, 1328, 749, 2287, 5025 },
{ 497, 1920, 952, 2388, 5924 },
{ 533, 1400, 1452, 2093, 5657 },
{ 506, 1612, 1587, 2083, 6019 },
{ 458, 1613, 1485, 2390, 6141 },
};
void display(double *dat, double *answer, double *square_poor, int rows, int cols)
{
double v, *p;
int i, j;
printf("regression equation; Y = %.5lf", answer[0]);
for (i = 1; i < cols; i ++)
printf(" + %.5lf*X%d", answer[i], i);
printf(" ");
printf("回归显著性检验: ");
printf("回归平方和:%12.4lf 回归方差:%12.4lf ", square_poor[0], square_poor[2]);
printf("剩余平方和:%12.4lf 剩余方差:%12.4lf ", square_poor[1], square_poor[3]);
printf("离差平方和:%12.4lf 标准误差:%12.4lf ", square_poor[0] + square_poor[1], sqrt(square_poor[3]));
printf("F 检 验:%12.4lf 相关系数:%12.4lf ", square_poor[2] / square_poor[3],
sqrt(square_poor[0] / (square_poor[0] + square_poor[1])));
printf("剩余分析: ");
printf(" 观察值 估计值 剩余值 剩余平方 ");
for (i = 0, p = dat; i < rows; i ++, p ++)
{
v = answer[0];
for (j = 1; j < cols; j ++, p ++)
v += *p * answer[j];
printf("%12.2lf%12.2lf%12.2lf%12.2lf ", *p, v, *p - v, (*p - v) * (*p - v));
}
}
int main(int argc, char* argv[])
{
double answer[5], square_poor[4];
/*
* Y = B0 + B1X1 + B2X2 + ...B4X4
*/
if (multiple_linear_regression((double*)data, 15, 5, answer, square_poor) == 0)
display((double*)data, answer, square_poor, 15, 5);
system("pause");
return 0;
}
// MultiLinearRegression.cpp : Defines the exported functions for the DLL application.
//
#include <stdlib.h>
#include <string.h>
#include "multiple_linear_regression.h"
void free_data(double **dat, double *d, int count)
{
int i;
free(d);
for (i = 0; i < count; i ++)
free(dat[i]);
free(dat);
}
/*
* data[count*(count+1)] matrix array
* count:equation element
* answer[count]:answer array
* return:0--sucess,-1--no solution or infinite solution
*/
int linear_equations(double *data, int count, double *answer)
{
int j, m, n;
double tmp, **dat, *d = data;
dat = (double**)malloc(count * sizeof(double*));
for (m = 0; m < count; m ++, d += (count + 1))
{
dat[m] = (double*)malloc((count + 1) * sizeof(double));
memcpy(dat[m], d, (count + 1) * sizeof(double));
}
d = (double*)malloc((count + 1) * sizeof(double));
for (m = 0; m < count - 1; m ++)
{
for (n = m + 1; n < count && dat[m][m] == 0.0; n ++)
{
if ( dat[n][m] != 0.0)
{
memcpy(d, dat[m], (count + 1) * sizeof(double));
memcpy(dat[m], dat[n], (count + 1) * sizeof(double));
memcpy(dat[n], d, (count + 1) * sizeof(double));
}
}
if (dat[m][m] == 0.0)
{
free_data(dat, d, count);
return -1;
}
for (n = m + 1; n < count; n ++)
{
tmp = dat[n][m] / dat[m][m];
for (j = m; j <= count; j ++)
dat[n][j] -= tmp * dat[m][j];
}
}
for (j = 0; j < count; j ++)
d[j] = 0.0;
answer[count - 1] = dat[count - 1][count] / dat[count - 1][count - 1];
for (m = count - 2; m >= 0; m --)
{
for (j = count - 1; j > m; j --)
d[m] += answer[j] * dat[m][j];
answer[m] = (dat[m][count] - d[m]) / dat[m][m];
}
free_data(dat, d, count);
return 0;
}
int32_t
multiple_linear_regression(double *data,
int32_t rows,
int32_t columns,
double *answer,
double *square_poor)
{
int m, n, i, count = columns - 1;
double *dat, *p, a, b;
if (data == 0 || answer == 0 || rows < 2 || columns < 2)
return -1;
dat = (double*)malloc(columns * (columns + 1) * sizeof(double));
dat[0] = (double)rows;
for (n = 0; n < count; n ++) // n = 0 to columns - 2
{
a = b = 0.0;
for (p = data + n, m = 0; m < rows; m ++, p += columns)
{
a += *p;
b += (*p * *p);
}
dat[n + 1] = a; // dat[0, n+1] = Sum(Xn)
dat[(n + 1) * (columns + 1)] = a; // dat[n+1, 0] = Sum(Xn)
dat[(n + 1) * (columns + 1) + n + 1] = b; // dat[n+1,n+1] = Sum(Xn * Xn)
for (i = n + 1; i < count; i ++) // i = n+1 to columns - 2
{
for (a = 0.0, p = data, m = 0; m < rows; m ++, p += columns)
a += (p[n] * p[i]);
dat[(n + 1) * (columns + 1) + i + 1] = a; // dat[n+1, i+1] = Sum(Xn * Xi)
dat[(i + 1) * (columns + 1) + n + 1] = a; // dat[i+1, n+1] = Sum(Xn * Xi)
}
}
for (b = 0.0, m = 0, p = data + n; m < rows; m ++, p += columns)
b += *p;
dat[columns] = b; // dat[0, columns] = Sum(Y)
for (n = 0; n < count; n ++)
{
for (a = 0.0, p = data, m = 0; m < rows; m ++, p += columns)
a += (p[n] * p[count]);
dat[(n + 1) * (columns + 1) + columns] = a; // dat[n+1, columns] = Sum(Xn * Y)
}
n = linear_equations(dat, columns, answer);
if (n == 0 && square_poor)
{
b = b / rows;
square_poor[0] = square_poor[1] = 0.0;
p = data;
for (m = 0; m < rows; m ++, p ++)
{
for (i = 1, a = answer[0]; i < columns; i ++, p ++)
a += (*p * answer[i]);
square_poor[0] += ((a - b) * (a - b));
square_poor[1] += ((*p - a) * (*p - a));
}
square_poor[2] = square_poor[0] / count;
if (rows - columns > 0.0)
square_poor[3] = square_poor[1] / (rows - columns);
else
square_poor[3] = 0.0;
}
free(dat);
return n;
return 0;
}
class multiple_linear_regression
{
// java不需要free_data
// java没有指针,故使用类属性与方法实现输入与输出
private double[] data;
private int rows;
private int columns;
private double[] answer;
private double[] square_poor;
private int ret;
public double[] getAnswer()
{
return this.answer;
}
public double[] getSquare_poor()
{
return this.square_poor;
}
public int getRet()
{
return this.ret;
}
private int linear_equations(double[] data)
{
int count = this.columns;
this.answer = new double[count];
double dat[][] = new double[count][];
int di = 0; // d换成索引di
for (int m = 0; m != count; ++m, di += (count + 1))
{
dat[m] = new double[count + 1];
System.arraycopy(data, di, dat[m], 0, count + 1);
}
double d[] = new double[count + 1];
for (int m = 0; m != count - 1; ++m)
{
for (int n = m + 1; n < count && dat[m][n] == 0.0; ++n)
{
if (dat[n][m] != 0.0)
{
d = dat[m];
dat[m] = dat[n];
dat[n] = d;
}
}
if (dat[m][m] == 0.0) { return -1; }
for (int n = m + 1; n < count; ++n)
{
double tmp = dat[n][m] / dat[m][m];
for (int j = m; j <= count; ++j)
{
dat[n][j] -= tmp * dat[m][j];
}
}
}
for (int j = 0; j != count; ++j)
{
d[j] = 0.0;
}
this.answer[count - 1] = dat[count - 1][count] / dat[count - 1][count - 1];
for (int m = count - 2; m >= 0; --m)
{
for (int j = count - 1; j > m; --j)
{
d[m] += answer[j] * dat[m][j];
}
answer[m] = (dat[m][count] - d[m]) / dat[m][m];
}
return 0;
}
public multiple_linear_regression(double[][] data)
{
if (data != null || data.length < 2 || data[0].length < 2)
{
this.ret = -1;
}
this.rows = data.length;
this.columns = data[0].length;
this.data = new double[this.rows * this.columns];
for (int i = 0; i != this.rows; ++i)
{
System.arraycopy(
data[i], 0,
this.data, i * this.columns,
this.columns
);
}
int count = this.columns - 1;
double dat[] = new double[this.columns * (this.columns + 1)];
dat[0] = (double)this.rows;
int n;
for (n = 0; n != count; ++n)
{
double a = 0.0, b = 0.0;
for (int pi = n, m = 0; m != rows; ++m, pi += columns) // p换成索引pi
{
a += this.data[pi];
b += this.data[pi] * this.data[pi];
}
dat[n + 1] = a;
dat[(n + 1) * (this.columns + 1)] = a;
dat[(n + 1) * (this.columns + 1) + n + 1] = b;
for (int i = n + 1; i < count; ++i)
{
a = 0.0;
for (int pi = 0, m = 0; m != this.rows; ++m, pi += this.columns)
{
a += this.data[pi + n] * this.data[pi + i];
}
dat[(n + 1) * (this.columns + 1) + i + 1] = a;
dat[(i + 1) * (this.columns + 1) + n + 1] = a;
}
}
double b = 0.0;
for (int m = 0, pi = n; m != this.rows; ++m, pi += this.columns)
{
b += this.data[pi];
}
dat[this.columns] = b;
for (n = 0; n != count; ++n)
{
double a = 0.0;
for (int pi = 0, m = 0; m != this.rows; ++m, pi += this.columns)
{
a += this.data[pi + n] * this.data[pi + count];
}
dat[(n + 1) * (this.columns + 1) + this.columns] = a;
}
n = this.linear_equations(dat);
if (n == 0)
{
this.square_poor = new double[4];
b = b / this.rows;
this.square_poor[0] = this.square_poor[1] = 0.0;
for (int m = 0, pi = 0; m < this.rows; ++m, ++pi) // p用pi表示
{
double a = this.answer[0];
for (int i = 1; i < this.columns; ++i, ++pi)
{
a += this.data[pi] * this.answer[i];
}
this.square_poor[0] += (a - b) * (a - b);
this.square_poor[1] += (this.data[pi] - a) * (this.data[pi] - a);
}
this.square_poor[2] = this.square_poor[0] / count;
this.square_poor[3] = (
this.rows - this.columns > 0.0 ?
this.square_poor[1] / (this.rows - this.columns)
: 0.0
);
}
this.ret = n;
}
public void display()
{
System.out.printf("regression equation; Y = %.5f" , this.answer[0]);
for (int i = 1; i < this.columns; ++i)
{
System.out.printf(" + %.5f*X%d", this.answer[i], i);
}
System.out.print(" ");
System.out.print("回归显著性检验:");
System.out.printf("回归平方和: %12.4f 回归方差: %12.4f ", this.square_poor[0], this.square_poor[2]);
System.out.printf("剩余平方和: %12.4f 剩余方差: %12.4f ", this.square_poor[1], this.square_poor[3]);
System.out.printf("离差平方和: %12.4f 标准误差: %12.4f ", this.square_poor[0] + this.square_poor[1], Math.sqrt(this.square_poor[3]));
System.out.printf("F 检 验: %12.4f 相关系数: %12.4f ", this.square_poor[2] / this.square_poor[3],
Math.sqrt(this.square_poor[0] / (this.square_poor[0] + this.square_poor[1])));
System.out.print("剩余分析: ");
System.out.print(" 观察值 估计值 剩余值 剩余平方 ");
double v;
for (int i = 0, pi = 0; i != this.rows; ++i, ++pi)
{
v = this.answer[0];
for (int j = 1; j < this.columns; ++j, ++pi)
{
v += this.data[pi] * this.answer[j];
}
System.out.printf("%12.2f%12.2f%12.2f%12.2f ", this.data[pi], v, this.data[pi] - v, (this.data[pi] - v) * (this.data[pi] - v));
}
}
public static void main(String[] args)
{
double data[][] = {
{ 316, 1536, 874, 981, 3894 },
{ 385, 1771, 777, 1386, 4628 },
{ 299, 1565, 678, 1672, 4569 },
{ 326, 1970, 785, 1864, 5340 },
{ 441, 1890, 785, 2143, 5449 },
{ 460, 2050, 709, 2176, 5599 },
{ 470, 1873, 673, 1769, 5010 },
{ 504, 1955, 793, 2207, 5694 },
{ 348, 2016, 968, 2251, 5792 },
{ 400, 2199, 944, 2390, 6126 },
{ 496, 1328, 749, 2287, 5025 },
{ 497, 1920, 952, 2388, 5924 },
{ 533, 1400, 1452, 2093, 5657 },
{ 506, 1612, 1587, 2083, 6019 },
{ 458, 1613, 1485, 2390, 6141 }
};
multiple_linear_regression m = new multiple_linear_regression(data);
if (m.getRet() == 0)
{
m.display();
}
}
}
不知道对不对. 基本照抄, 只是把malloc换成new, 指针换成索引.