#include <stdio.h>
#define dx 1e-7
double findGrad(double *a, double *y, double *x, int n, int i, double fm);
double func(double *a, double *y, double *x, int n);
void multiply(double *mat, double *x, int n);
int main(void){
int n, i;
n = 2;
double a[n*n], x[n], y[n], df[n], fm;
x[0] = 0; x[1] = 0;
y[0] = 8; y[1] = 18;
for(i=0;i<n*n;i++){
a[i] = i+1;
}
fm = func(a,y,x,n);
printf("%f\n", fm);
for(i=0; i<n; i++){
df[i] = findGrad(a, y, x, n, i, fm);
printf("%f ", df[i]);
}
printf("\n");
}
double findGrad(double *a, double *y, double *x, int n, int i, double fm){
double fx, xNew[n];
int k;
for(k=0; k<n; k++){
xNew[k] = x[k];
//printf("xNew: %f, %f\n", xNew[0], xNew[1]);
}
xNew[i] = x[i] + dx;
//printf("xNew: %f\n", xNew[i]);
fx = 0;
//printf("fx: %f\n", fx);
fx = func(a,y,xNew,n);
//printf("fx: %f\n", (fx-fm)/dx);
return (fx-fm)/dx;
}
double func(double *a, double *y, double *x, int n){
int i;
double v[n], norm = 0;
multiply(a, x, n); //calculate a*x and put the result in x;
for(i=0; i<n; i++){
v[i] = x[i]-y[i];
norm += v[i]*v[i];
}
return norm;
}
void multiply(double *mat, double *x, int n){
double v[n], w[n];
int i, j;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
v[j] = mat[i*n+j]*x[j];
w[i] += v[j];
}
}
//copy v to x
for(i=0; i<n; i++){
x[i] = w[i];
}
}
f(x) = 10x[1]^2 - 124x[1] +28x[1]x[2] + 20x[2]^2 - 176x[2] + 388
勾配は
df/dx[1] = 20x[1] + 28x[2] -124
df/dx[2] = 40x[2] + 28x[1] - 176
であり、x[1] = 0, x[2] = 0のときそれぞれ-124, -176となるはずですが、実際には
x[1] = -123.999999
x[2] = -299.999994
となってしまい、x[2]のほうがなぜかx[1] + x[2]のように上書きされてしまっているようです。
しかしdouble findGrad(double *a, double *y, double *x, int n, int i, double fm)内各変数の値をprintfで確認すると以下のように正常な値を出力します。
x[1] = -123.999999
x[2] = -175.999999
色々な変数をprintfでチェックしてみたのですが、どのケースもprintfを使ったときは正常な値を出すのですが、printfを使わない場合は上書きされた値が出力されました。
なぜこのようなことが起こるのでしょうか。
どなたか御教示いただけると幸いです。