C言語の課題で悩んでいます
線形最小2乗法と直接探索法の併用により、あるデータを最小2乗近似によって係数を求めるプログラムを作りました。
プログラムを実行したところ以下の警告が出て悩んでいます。
114行目 互換性のないポインタ型からの引数 1 個の `sweep' を渡しますです
114行目 互換性のないポインタ型からの引数 5 個の `sweep' を渡しますです
分りやすいように114行目のところに@がつけてあります。
どなたかご指摘お願いします。
#include<stdio.h>
#include<math.h>
#define eps 1.e-5
void sweep(double *,double *,int,int,int *,int);
void DSO(double *,double *,int *,double *,double *,int,int);
void FUN(double *,double *,double *,int,double *,int *);
int main(void)
{
double a[1],da[1],x[7],y[7];
int i,n,delta[1];
scanf("%d",&n);
for(i=0;i<n;++i) scanf("%lf %lf",&x[i],&y[i]);
scanf("%lf %lf",&a[0],&da[0]);
printf("Iteration b(1) b(2) b(3) a f\n");
DSO(a,da,delta,x,y,1,n);
}
/*DSO*/
void DSO(double *pa,double *pda,int *pdelta,double *px,double *py,int m,int n)
{
double ak,akp,akm,f0,fp,fm;
int k,j,iteration=0;
for(k=0;k<m;++k){
*(pdelta+k)=1;
}
FUN(pa,px,py,n,&f0,&iteration);
do{
j=0;
for(k=0;k<m;++k){
ak=*(pa+k);
akp=*(pa+k)+*(pda+k);
akm=*(pa+k)-*(pda+k);
if(*(pdelta+k)==1){
*(pa+k)=akp;
FUN(pa,px,py,n,&fp,&iteration);
if(f0>fp){
*(pdelta+k)=1;
f0=fp;
break;
}
else{
*(pa+k)=akm;
FUN(pa,px,py,n,&fm,&iteration);
if(f0>fm){
*(pdelta+k)=-1;
f0=fm;
break;
}
else{
j++;
*(pa+k)=ak;
}
}
}
else{
*(pa+k)=akm;
FUN(pa,px,py,n,&fm,&iteration);
if(f0>fm){
*(pdelta+k)=-1;
f0=fm;
break;
}
else{
*(pa+k)=akp;
FUN(pa,px,py,n,&fp,&iteration);
if(f0>fp){
*(pdelta+k)=1;
f0=fp;
break;
}
else{
j++;
*(pa+k)=ak;
}
}
}
}
}while(j!=m);
printf("*** SOLVED ***\n");
FUN(pa,px,py,n,&f0,&iteration);
return;
}
/*Function for sum of square errors*/
void FUN(double *pa,double *px,double *py,int n,double *pf,int *pi)
{
double b[3],c[3][4],iwork[3],t[3],yi;
int i,ILL;
c[0][0]=n;
c[0][1]=0.;
c[0][2]=0.;
c[0][3]=0.;
c[1][1]=0.;
c[1][2]=0.;
c[1][3]=0.;
c[2][2]=0.;
c[2][3]=0.;
for(i=0;i<n;i++){
c[0][1]+=log10(*(px+i));
c[1][1]+=log10(*(px+i))*log10(*(px+i));
c[0][2]+=pow(log10(*(px+i)),*(pa+0));
c[1][2]+=pow(log10(*(px+i)),*(pa+0)+1.);
c[2][2]+=pow(log10(*(px+i)),2.**(pa+0));
c[0][3]+=*(py+i);
c[1][3]+=*(py+i)*log10(*(px+i));
c[2][3]+=*(py+i)*pow(log10(*(px+i)),*(pa+0));
}
c[1][0]=c[0][1];
c[2][0]=c[0][2];
c[2][1]=c[1][2];
sweep(c,t,3,4,iwork,ILL); @114行目
for(i=0;i<3;++i){
b[i]=c[i][3];
}
*pf=0.;
for(i=0;i<n;++i){
yi=b[0]+b[1]*log10(*(px+i))+b[2]*pow(log10(*(px+i)),*(pa+0));
*pf+=(*(py+i)-yi)*(*(py+i)-yi);
}
printf("%6d %12.3e%12.3e%12.3e%7.2f%11.2e\n",
*pi,b[0],b[1],b[2],*(pa+0),*pf);
++*pi;
return;
}
/*Gauss-Jordan method*/
void sweep(double *pa,double *pt,int n,int m,int *piwork,int ILL)
{
double max,w;
int i,j,k,iw,p,q;
for(i=0;i<n;++i){
max=fabs(*(pa+m*i));
for(j=0;j<n;++j){
if(max<fabs(*(pa+m*i+j)))max=fabs(*(pa+m*i+j));
}
for(j=0;j<m;++j) *(pa+m*i+j)=*(pa+m*i+j)/max;
}
for(j=0;j<n;++j){
max=fabs(*(pa+j));
for(i=0;i<n;++i){
if(max<fabs(*(pa+m*i+j)))max=fabs(*(pa+m*i+j));
}
*(pt+j)=max;
for(i=0;i<n;++i) *(pa+m*i+j)=*(pa+m*i+j)/max;
}
for(i=0;i<n;++i){
*(piwork+i)=i;
}
for(k=0;k<n;++k){
max=fabs(*(pa+m*k+k));
p=k;
q=k;
for(j=k;j<n;++j){
for(i=k;i<n;++i){
if(max<fabs(*(pa+m*i+j))){
max=fabs(*(pa+m*i+j));
p=i;
q=j;
}
}
}
if(max<=eps){
ILL=1;
printf("MATRIX IS ILL\n");
return;
}
for(i=0;i<n;++i){
w=*(pa+m*i+k);
*(pa+m*i+k)=*(pa+m*i+q);
*(pa+m*i+q)=w;
}
for(j=k;j<m;++j){
w=*(pa+m*k+j);
*(pa+m*k+j)=*(pa+m*p+j);
*(pa+m*p+j)=w;
}
i=*(piwork+k);
*(piwork+k)=*(piwork+q);
*(piwork+q)=i;
for(j=k+1;j<m;++j){
*(pa+m*k+j)=*(pa+m*k+j)/(*(pa+m*k+k));
}
for(i=0;i<n;++i){
if(i!=k){
for(j=k+1;j<m;++j){
*(pa+m*i+j)=*(pa+m*i+j)-*(pa+m*i+k)*(*(pa+m*k+j));
}
}
}
}
for(j=n;j<m;++j){
for(i=0;i<n;++i){
iw=*(piwork+i);
*(pa+m*iw+n-1)=*(pa+m*i+j);
}
for(i=0;i<n;++i){
*(pa+m*i+j)=*(pa+m*i+n-1)/(*(pt+i));
}
}
return;
}
補足
返信が大変遅くなってしまい申し訳ありません。 ご指摘有り難うございます。 ご指摘頂いた通りnCkを加え実際に計算してみたのですが、それでもうまくいきませんでした。 ※結果は0となり(※正確には100桁ほど小数点以下を表示すると値は入っているのですが・・・) Excelの二項分布関数で計算したものと大きく結果が異なってしまいます。 自分としては、公式通りに計算したつもりだったのですが、間違っている点がどうしても分かりません。 もし問題点が分かるようでしたら、こちらにつきましてもご指摘頂けませんでしょうか? 尚、実行したプログラムと条件は以下の通りです。 条件: 確率1/287で毎回独立に起こる事象が5000回のうち25回起こる確率を計算 プログラム: - (void)viewDidLoad { [super viewDidLoad]; double b = 1; double c = 287; double p = b/c; double n = 5000.0; double bk = 25.0; double a = [self binomial_p:n p:p bk:bk]; //0.018579552になるはず NSLog(@"a:%.9f",a); } //確率pで毎回独立に起こる事象がn回のうちk回起こる確率を計算 - (double)binomial_p:(double)n p:(double)p bk:(double)bk { double q = 1. - p; unsigned long long comb = [self combination:n r:bk]; double b = pow(p,bk); double c = pow(q,n-bk); return comb * b * c; } // 組合せ数 nCr の計算 - (unsigned long long)combination:(int)n r:(int)r { int nn = n; unsigned long long* a = (unsigned long long*)calloc(n,sizeof(unsigned long long)); unsigned long long retv; if ( nn-r < r ) r = nn-r; if ( r == 0 ) return 1; if ( r == 1 ) return nn; for ( int i=1; i<r; i++ ) a[i] = i+2; for ( int i=3; i<=nn-r+1; i++ ) { a[0] = i; for ( int j=1; j<r; j++ ) a[j] += a[j-1]; } retv = a[r-1]; free(a); return retv; }