我正在读取一个名为reg.dat的文件,并将每列中的第一个变量设置为变量Y的索引,将每列中的其余变量设置为X的索引。然后,我希望将X和Y输入dgesv函数,以计算线性回归。
我的代码如下(块,因为我不能一次把它全部包含在这个网站上)。运行gcc -ansi -pedantic readReg.c -o readReg -llapack -lblas -lgfortran
时遇到的错误如下所示:
readReg.c: In function ‘main’:
readReg.c:18: warning: ISO C90 forbids variable length array ‘ipiv’
readReg.c:19: warning: ISO C90 forbids variable length array ‘X1’
readReg.c:19: warning: ISO C90 forbids variable length array ‘X1’
readReg.c:19: warning: ISO C90 forbids variable length array ‘XtX’
readReg.c:19: warning: ISO C90 forbids variable length array ‘XtY’
readReg.c:48: error: subscripted value is neither array nor pointer
例如,如果文件reg.dat是:
5.1 3.5 1.4
4.9 3 1.4
4.7 3.2 1.3
4.6 3.1 1.5
5 3.6 1.4
然后X= 5.1、4.9、4.7、4.6、5和Y= 3.5、1.4、3、1.4、3.2、1.3、3.1、1.5、3.6、1.4
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int getCol(char *myStr);
int getRow(char *fileName);
int assignY(int nCol, int nRow, double *Y, char *fileName);
int assignX(int nCol, int nRow, double *X, char *fileName);
void dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
int main(){
FILE *f;
char myStr[1000];
int strL;
int nCol;
int nRow;
char *fileName = "reg.dat";
int i, j, k, n1=nCol, n2=1, ipiv[nCol], info;
double X1[nRow][nCol], XtX[(nCol) * (nCol)], XtY[nCol];
double *X;
double *Y;
f = fopen(fileName, "r");
if (f == NULL) perror ("Error opening file");
else {
if (fgets(myStr, 1000, f) != NULL )
puts(myStr);
fclose(f);
}
strL = strlen(myStr);
nCol = getCol(myStr);
nRow = getRow(fileName);
printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);
X = (double *) malloc(sizeof(double) * ((nCol-1) * nRow));
Y = (double *) malloc(sizeof(double) * nRow);
assignY(nCol, nRow, Y, fileName);
assignX(nCol, nRow, X, fileName);
接下来我操纵X和Y..。
/* The following is for doing the dgesv function */
/* design matrix */
for (i=0; i<nRow; i++){
X1[i][0] = 1;
for (j=1; j<n1; j++)
X1[i][j] = X[i][j-1];
}
/* t(X1) %*% X1 */
for (i=0; i<n1; i++){
for (j=0; j<n1; j++){
XtX[i*n1+j] = 0;
for (k=0; k<nRow; k++)
XtX[i*n1+j] += X1[k][i] * X1[k][j];
}
}
/* t(X1) %*% Y */
for (i=0; i<n1; i++){
XtY[i] = 0;
for (j=0; j<nRow; j++){
XtY[i] += X1[j][i] * Y[j];
}
}
接下来我打印结果
/* XtX is symmetric, no transpose needed before passing to Fortran subrountine */
dgesv_(&n1, &n2, XtX, &n1, ipiv, XtY, &n1, &info);
if (info!=0) printf("failure with error %d\n", info);
/* print beta */
printf("The regression coefficients: ");
for (i=0; i<n1; i++){
printf("%f ", XtY[i]);
}
printf("\n");
return 0;
}
助手函数..。
int assignY(int nCol, int nRow, double *Y, char *fileName){
int i=0;
int j;
char string[1000];
char* data = NULL;
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof(string), f) != NULL){
data = strtok(string, " ");
for (j=0; NULL != data && j<nCol; j++){
if (data[strlen(data) - 1] == '\n')
data[strlen(data) - 1] = '\0';
if (j==0){
Y[i] = atof(data);
i++;
}
data = strtok(NULL, " ");
}
}
for (i=0;i<nRow;i++){
printf("%f\n", Y[i]);
}
return 0;
}
助手函数..。
int assignX(int nCol, int nRow, double *X, char *fileName){
int i=0;
int j;
char string[1000];
char* data = NULL;
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof(string), f) != NULL){
data = strtok(string, " ");
for (j=0; NULL != data && j<nCol; j++){
if (data[strlen(data) - 1] == '\n')
data[strlen(data) - 1] = '\0';
if (j!=0){
X[i] = atof(data);
i++;
}
data = strtok(NULL, " ");
}
}
for (i=0;i<(nRow*(nCol-1));i++){
printf("%f\n", X[i]);
}
return 0;
}
助手函数..。
int getCol(char *myStr){
int length,i,count=0;
char prev;
length=strlen(myStr);
if(length > 0){
prev = myStr[0];
}
for(i=0; i<=length; i++){
if(myStr[i]==' ' && prev != ' '){
count++;
}
prev = myStr[i];
}
if(count > 0 && myStr[i] != ' '){
count++;
}
return count;
}
int getRow(char *fileName){
char ch;
int count=0;
FILE *f;
f = fopen(fileName, "r");
while(!feof(f)){
ch = fgetc(f);
if(ch == '\n')
{
count++;
}
}
fclose(f);
return count;
}
编辑:
我现在更改为X1、XtY、XtX和ipiv的malloc()。我现在还为X1使用了多维动态数组。当我跑gcc的时候,所有的错误都消失了,除了:
readReg.c: In function ‘main’:
readReg.c:62: error: subscripted value is neither array nor pointer
以下是最新的主要职能:
int main(){
FILE *f;
char myStr[1000];
int strL;
int nCol;
int nRow;
char *fileName = "reg.dat";
int i, j, k, n1=nCol, n2=1, info;
double *X;
double *Y;
double **X1;
double *XtX;
double *XtY;
int *ipiv;
double *temp;
f = fopen(fileName, "r");
if (f == NULL) perror ("Error opening file");
else {
if (fgets(myStr, 1000, f) != NULL )
puts(myStr);
fclose(f);
}
strL = strlen(myStr);
nCol = getCol(myStr);
nRow = getRow(fileName);
printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);
X = (double *) malloc(sizeof(double) * ((nCol-1) * nRow));
Y = (double *) malloc(sizeof(double) * nRow);
XtX = (double *) malloc(sizeof(double) * (nCol*nCol));
XtY = (double *) malloc(sizeof(double) * nCol);
ipiv = (int *) malloc(sizeof(int) * nCol);
assignY(nCol, nRow, Y, fileName);
assignX(nCol, nRow, X, fileName);
X1 = malloc(nRow * sizeof(double*));
temp = malloc(nRow * nCol * sizeof(double));
for (i= 0; i < nRow; i++) {
X1[i] = temp + (i * nCol);
}
...
}
发布于 2015-03-24 08:24:38
首先声明nRow和nCol,而不赋值:
int nCol;
int nRow;
...and现在定义了四个使用nRow和nCol的可变长度数组:
int i, j, k, n1=nCol, n2=1, ipiv[nCol], info;
double X1[nRow][nCol], XtX[(nCol) * (nCol)], XtY[nCol];
首先,在C90中禁止变长阵列.为此使用malloc()
。您似乎知道如何基于代码使用malloc()
。
其次,在为nCol
和nRow
赋值之前,如何期望编译器在声明数组时知道数组的大小?
其中一个数组是多维的。有关如何使用动态多维数组的更多信息,请参见How do I work with dynamic multi-dimensional arrays in C?。
https://stackoverflow.com/questions/29227724
复制相似问题