Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从输入 浮动x,y; printf(“输入新的X坐标:”); scanf(“%f”、&x); printf(“输入新的Y坐标:”); 扫描频率(“%f”和“y”); //TODO:检查合法输入边界 //将输入存储在内存中 gsl_向量_集(coords,0,x); gsl_向量_集(coords,1,y); printf(“x:%3.3f,y:%3.3f\n”,x,y); //一切都好,回报成功 返回GSL_成功; } //------------------------------------------------------------------------------ int 打印状态(大小iter、gsl、多根fdfsolver*s) { printf(“iter=%3ux=%.6f%.6f” “f(x)=%.3e%.3e\n”, 国际热核聚变实验堆, gsl_向量_get(s->x,0), gsl_向量_get(s->x,1), gsl_向量_get(s->f,0), gsl_向量_-get(s->f,1)); //一切都好,回报成功 返回GSL_成功; }_C_Io_Gsl - Fatal编程技术网

从输入 浮动x,y; printf(“输入新的X坐标:”); scanf(“%f”、&x); printf(“输入新的Y坐标:”); 扫描频率(“%f”和“y”); //TODO:检查合法输入边界 //将输入存储在内存中 gsl_向量_集(coords,0,x); gsl_向量_集(coords,1,y); printf(“x:%3.3f,y:%3.3f\n”,x,y); //一切都好,回报成功 返回GSL_成功; } //------------------------------------------------------------------------------ int 打印状态(大小iter、gsl、多根fdfsolver*s) { printf(“iter=%3ux=%.6f%.6f” “f(x)=%.3e%.3e\n”, 国际热核聚变实验堆, gsl_向量_get(s->x,0), gsl_向量_get(s->x,1), gsl_向量_get(s->f,0), gsl_向量_-get(s->f,1)); //一切都好,回报成功 返回GSL_成功; }

从输入 浮动x,y; printf(“输入新的X坐标:”); scanf(“%f”、&x); printf(“输入新的Y坐标:”); 扫描频率(“%f”和“y”); //TODO:检查合法输入边界 //将输入存储在内存中 gsl_向量_集(coords,0,x); gsl_向量_集(coords,1,y); printf(“x:%3.3f,y:%3.3f\n”,x,y); //一切都好,回报成功 返回GSL_成功; } //------------------------------------------------------------------------------ int 打印状态(大小iter、gsl、多根fdfsolver*s) { printf(“iter=%3ux=%.6f%.6f” “f(x)=%.3e%.3e\n”, 国际热核聚变实验堆, gsl_向量_get(s->x,0), gsl_向量_get(s->x,1), gsl_向量_get(s->f,0), gsl_向量_-get(s->f,1)); //一切都好,回报成功 返回GSL_成功; },c,io,gsl,C,Io,Gsl,简短回答:s->x存储解算器的状态,不应使用输入数组角度获取输出。这是在我修复了一些小细节之后,您代码的结果 iter = 0 x = 2.443461 0.523599 f(x) = 9.998e-02 -2.905e-01 iter = 1 x = 2.308197 0.897453 f(x) = -4.876e-02 8.863e-02 iter = 2 x = 2.336417 0.808354 f(x) = -2.295e-03 1.077e-02 ite

简短回答:
s->x
存储解算器的状态,不应使用输入数组
角度
获取输出。这是在我修复了一些小细节之后,您代码的结果

iter =   0 x =  2.443461  0.523599 f(x) =  9.998e-02 -2.905e-01
iter =   1 x =  2.308197  0.897453 f(x) = -4.876e-02  8.863e-02
iter =   2 x =  2.336417  0.808354 f(x) = -2.295e-03  1.077e-02
iter =   3 x =  2.342411  0.799205 f(x) = -1.653e-05  2.539e-04
iter =   4 x =  2.342579  0.799014 f(x) = -2.884e-09  3.705e-06
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
status = success
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
calc_angles worked
Calculated angles: alpha:  2.342582, beta:  0.799011
这是实际的代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_multiroots.h>
#include <gsl/gsl_sf.h>

// constants
const double LENGTH = 6.0;
const double TOL    = 1.0e-6;

// params struct
struct rparams
{
    double x, y;
};

// calculate the primary and secondary angles for the given coordinates in coords
int calc_angles(gsl_vector* coords, gsl_vector* result_angles);
int coords_f(const gsl_vector* angles, void* params, gsl_vector* f);
int coords_df(const gsl_vector* angles, void* params, gsl_matrix* J);
int coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J);

// IO functions
int get_coords(gsl_vector* coords);

// helper/debug functions
int print_state(size_t iter, gsl_multiroot_fdfsolver* s);

int
main(int argc, char* argv[])
{
    const size_t n = 2;
    // initialize vectors: input coords, initial guess, result angles
    gsl_vector* coords = gsl_vector_alloc(n);
    gsl_vector* result_angles = gsl_vector_alloc(n);
    gsl_vector_set(result_angles, 0, 0.0);  // set result angles to zero
    gsl_vector_set(result_angles, 1, 0.0);

    // TODO: read coordinates from input
    // get_coords(coords);
    gsl_vector_set(coords, 0, 0.0);
    gsl_vector_set(coords, 1, 8.6);

    // calc new angles
    if(!calc_angles(coords, result_angles)) { printf("calc_angles worked\n"); }

    // output new angles
    printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
           gsl_vector_get(result_angles, 0),
           gsl_vector_get(result_angles, 1) );

    // deallocate memory
    gsl_vector_free(coords);
    gsl_vector_free(result_angles);

    return 0;
}

//------------------------------------------------------------------------------
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
    const gsl_multiroot_fdfsolver_type* T;
    gsl_multiroot_fdfsolver* s;

    int status;
    size_t iter = 0;
    const size_t n = 2;

    // coordinates whose's angles is to be found
    struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
    gsl_multiroot_function_fdf f = { &coords_f,
                                     &coords_df,
                                     &coords_fdf,
                                     n, &p};

    // TODO: calculate inital guess
    double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
    gsl_vector* angles = gsl_vector_alloc(n);

    gsl_vector_set(angles, 0, angles_init[0]);
    gsl_vector_set(angles, 1, angles_init[1]);

    T = gsl_multiroot_fdfsolver_gnewton;
    s = gsl_multiroot_fdfsolver_alloc(T, n);
    gsl_multiroot_fdfsolver_set(s, &f, angles);

    print_state(iter, s);

    do
    {
        iter++;
        status = gsl_multiroot_fdfsolver_iterate(s);

        print_state(iter, s);

        if(status) { break; }

        status = gsl_multiroot_test_residual(s->f, 1e-7);
    } while (status == GSL_CONTINUE && iter < 1000);

    printf("status = %s\n", gsl_strerror(status));
    print_state(iter, s);

    // store results in result_angles
    gsl_vector_memcpy(result_angles, s -> x);

    // sanity check
    if(gsl_vector_equal(result_angles, angles))
    {
        printf("Vectors are equal\n");
    }

    gsl_multiroot_fdfsolver_free(s);
    gsl_vector_free(angles);

    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_f(const gsl_vector* angles, void* params, gsl_vector* f)
{
    // extract c and y coordinates
    double x = ((struct rparams*) params)->x;
    double y = ((struct rparams*) params)->y;

    // extract input angles
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate coordinates from angles
    const double x0 = gsl_sf_cos(alpha) + gsl_sf_cos(beta) - x / LENGTH;
    const double y0 = gsl_sf_sin(alpha) + gsl_sf_sin(beta) - y / LENGTH;

    // save results
    gsl_vector_set(f, 0, x0);
    gsl_vector_set(f, 1, y0);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_df(const gsl_vector* angles, void* params, gsl_matrix* J)
{
    // extract input angle
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate partial derivatives for Jacobian matrix
    const double df00 = -gsl_sf_sin(alpha);
    const double df01 = -gsl_sf_sin(beta);
    const double df10 =  gsl_sf_cos(alpha);
    const double df11 =  gsl_sf_sin(beta);

    // set Jacobian matrix
    gsl_matrix_set(J, 0, 0, df00);
    gsl_matrix_set(J, 0, 1, df01);
    gsl_matrix_set(J, 1, 0, df10);
    gsl_matrix_set(J, 1, 1, df11);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J)
{
    coords_f(angles, params, f);
    coords_df(angles, params, J);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
get_coords(gsl_vector* coords)
{
    // TODO: replace with platform specific code
    // read new coordinates from input
    float x, y;
    printf("Enter new X coordinate: ");
    scanf("%f", &x);
    printf("Enter new Y coordinate: ");
    scanf("%f", &y);

    // TODO: check for legal input bounds

    // store input in memory
    gsl_vector_set(coords, 0, x);
    gsl_vector_set(coords, 1, y);

    printf("x: %3.3f, y: %3.3f\n", x, y);
    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
    printf("iter = %3ld x = % .6f % .6f "
           "f(x) = % .3e % .3e\n",
           iter,
           gsl_vector_get(s->x, 0),
           gsl_vector_get(s->x, 1),
           gsl_vector_get(s->f, 0),
           gsl_vector_get(s->f, 1) );

    // all good, return success
    return GSL_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//常数
常数双倍长度=6.0;
常数双TOL=1.0e-6;
//参数结构
结构参数
{
双x,y;
};
//计算坐标系中给定坐标的主角度和次角度
int计算角度(gsl_向量*坐标,gsl_向量*结果_角度);
int coords_f(常数gsl_向量*角度,void*参数,gsl_向量*f);
int coords_df(常数gsl_向量*角度,void*参数,gsl_矩阵*J);
int coords_fdf(常数gsl_向量*角度,void*参数,gsl_向量*f,gsl_矩阵*J);
//IO功能
int get_坐标(gsl_向量*坐标);
//助手/调试函数
int打印状态(大小iter、gsl、多根fdfsolver*s);
int
main(int argc,char*argv[])
{
常数大小n=2;
//初始化向量:输入坐标、初始猜测、结果角度
gsl_向量*coords=gsl_向量_alloc(n);
gsl_向量*结果_角度=gsl_向量_alloc(n);
gsl_vector_set(结果角度,0,0.0);//将结果角度设置为零
gsl_向量_集(结果_角,1,0.0);
//TODO:从输入读取坐标
//获得协调(coords);
gsl_向量_集(coords,0,0.0);
gsl_向量_集(coords,1,8.6);
//计算新角度
如果(!计算角度(坐标,结果角度)){printf(“计算角度”\n”);}
//输出新角度
printf(“计算角度:α:%.6f,β:%.6f\n”,
gsl_矢量_get(结果角度,0),
gsl_向量_get(结果角,1));
//释放内存
gsl_矢量_自由(coords);
无gsl矢量(结果角);
返回0;
}
//------------------------------------------------------------------------------
int
计算角度(gsl_向量*坐标,gsl_向量*结果_角度)
{
常数gsl_多根函数fdfsolver_type*T;
gsl_multiroot_fdfsolver*s;
智力状态;
尺寸=0;
常数大小n=2;
//要找到其角度的坐标
结构参数p={gsl_vector_get(coords,0),gsl_vector_get(coords,1)};
gsl_多根函数_fdf={&coords_f,
&coords_df,
&库德斯夫,
n、 &p};
//TODO:计算初始猜测
双角度_init[2]={140.0*M_PI/180.0,30*M_PI/180.0};
gsl_向量*角度=gsl_向量_alloc(n);
gsl_向量_集(角度,0,角度_初始[0]);
gsl_向量_集(角度,1,角度_初始[1]);
T=gsl\u多根\u fdfsolver\u gnewton;
s=gsl_多根_fdfsolver_alloc(T,n);
gsl_多根_fdfsolver_集(s和f,角度);
印刷状态(iter,s);
做
{
iter++;
状态=gsl\u多根\u fdfsolver\u迭代;
印刷状态(iter,s);
如果(状态){break;}
状态=gsl\U多根测试\U残差(s->f,1e-7);
}而(状态==GSL_CONTINUE&&iter<1000);
printf(“状态=%s\n”,gsl_strerror(状态));
印刷状态(iter,s);
//将结果存储在结果中
gsl_vector_memcpy(结果角度,s->x);
//健康检查
if(gsl_向量_相等(结果_角度,角度))
{
printf(“向量相等\n”);
}
gsl_multiroot_fdfsolver_free(s);
无矢量(角度);
返回GSL_成功;
}
//------------------------------------------------------------------------------
int
坐标f(常数gsl_向量*角度,无效*参数,gsl_向量*f)
{
//提取c和y坐标
双x=((结构参数*)参数)->x;
双y=((结构参数*)参数)->y;
//提取输入角度
常数double alpha=gsl_向量_get(角度,0);
常数双β=gsl_向量_get(角度,1);
//从角度计算坐标
常数双x0=gsl\u sf\u cos(α)+gsl\u sf\u cos(β)-x/长度;
常数双y0=gsl_sf_sin(α)+gsl_sf_sin(β)-y/长度;
//保存结果
gsl_向量_集(f,0,x0);
gsl_向量_集(f,1,y0);
//一切都好,回报成功
返回GSL_成功;
}
//------------------------------------------------------------------------------
int
坐标df(常数gsl_向量*角度,无效*参数,gsl_矩阵*J)
{
//提取输入角度
常数double alpha=gsl_向量_get(角度,0);
常数双β=gsl_向量_get(角度,1);
//计算雅可比矩阵的偏导数
常数双df00=-gsl\u sf\u sin(α);
常数双df01=-gsl\u sf\u sin(β);
常数双df10=gsl\u sf\u cos(α);
常数双df11=gsl_sf_sin(β);
//集合雅可比矩阵
gsl_矩阵_集(J,0,0,df00);
gsl_矩阵_集(J,0,1,df01);
gsl_矩阵_集(J,1,0,df10);
gsl_矩阵_集(J,1,1,df11);
//一切都好,回报成功
返回GSL_成功;
}
//------------------------------------------------------------------------------
int
坐标fdf(常数gsl_向量*角度,无效*参数,gsl_向量*f,gsl_矩阵*J)
{
坐标f(角度、参数、f);
协调
./bin/example_app 
iter =   0 x =  2.443461  0.523599 f(x) =  9.998e-02 -2.905e-01
iter =   1 x =  2.308197  0.897453 f(x) = -4.876e-02  8.863e-02
iter =   2 x =  2.336417  0.808354 f(x) = -2.295e-03  1.077e-02
iter =   3 x =  2.342411  0.799205 f(x) = -1.653e-05  2.539e-04
iter =   4 x =  2.342579  0.799014 f(x) = -2.884e-09  3.705e-06
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
status = success
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
Vectors are equal
Calculated angles: alpha:  2.443461, beta:  0.523599
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_sf.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_multiroots.h>

// constants
const double LENGTH = 6.0;
const double TOL    = 1.0e-6;

// params struct
struct rparams
{
    double x, y;
};

// calculate the primary and secondary angles for the given coordinates in coords
int calc_angles(gsl_vector* coords, gsl_vector* result_angles);
int coords_f(const gsl_vector* angles, void* params, gsl_vector* f);
int coords_df(const gsl_vector* angles, void* params, gsl_matrix* J);
int coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J);

// IO functions
int get_coords(gsl_vector* coords);

// helper/debug functions
int print_state(size_t iter, gsl_multiroot_fdfsolver* s);

int
main(int argc, char* argv[])
{
    const size_t n = 2;
    // initialize vectors: input coords, initial guess, result angles
    gsl_vector* coords = gsl_vector_alloc(n);
    gsl_vector* result_angles = gsl_vector_alloc(n);
    gsl_vector_set(result_angles, 0, 0.0);  // set result angles to zero
    gsl_vector_set(result_angles, 1, 0.0);

    // TODO: read coordinates from input
    // get_coords(coords);
    gsl_vector_set(coords, 0, 0.0);
    gsl_vector_set(coords, 1, 8.6);

    // calc new angles
    if(calc_angles(coords, result_angles)) { printf("calc_angles worked"); }

    // output new angles
    printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
           gsl_vector_get(result_angles, 0),
           gsl_vector_get(result_angles, 1) );

    // deallocate memory
    gsl_vector_free(coords);
    gsl_vector_free(result_angles);

    return 0;
}

//------------------------------------------------------------------------------
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
    const gsl_multiroot_fdfsolver_type* T;
    gsl_multiroot_fdfsolver* s;

    int status;
    size_t i, iter = 0;
    const size_t n = 2;

    // coordinates whose's angles is to be found
    struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
    gsl_multiroot_function_fdf f = { &coords_f,
                                     &coords_df,
                                     &coords_fdf,
                                     n, &p};

    // TODO: calculate inital guess
    double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
    gsl_vector* angles = gsl_vector_alloc(n);

    gsl_vector_set(angles, 0, angles_init[0]);
    gsl_vector_set(angles, 1, angles_init[1]);

    T = gsl_multiroot_fdfsolver_gnewton;
    s = gsl_multiroot_fdfsolver_alloc(T, n);
    gsl_multiroot_fdfsolver_set(s, &f, angles);

    print_state(iter, s);

    do
    {
        iter++;
        status = gsl_multiroot_fdfsolver_iterate(s);

        print_state(iter, s);

        if(status) { break; }

        status = gsl_multiroot_test_residual(s->f, 1e-7);
    } while (status == GSL_CONTINUE && iter < 1000);

    printf("status = %s\n", gsl_strerror(status));
    print_state(iter, s);

    // store results in result_angles
    gsl_vector_memcpy(result_angles, angles);

    // sanity check
    if(gsl_vector_equal(result_angles, angles))
    {
        printf("Vectors are equal\n");
    }

    gsl_multiroot_fdfsolver_free(s);
    gsl_vector_free(angles);

    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_f(const gsl_vector* angles, void* params, gsl_vector* f)
{
    // extract c and y coordinates
    double x = ((struct rparams*) params)->x;
    double y = ((struct rparams*) params)->y;

    // extract input angles
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate coordinates from angles
    const double x0 = gsl_sf_cos(alpha) + gsl_sf_cos(beta) - x / LENGTH;
    const double y0 = gsl_sf_sin(alpha) + gsl_sf_sin(beta) - y / LENGTH;

    // save results
    gsl_vector_set(f, 0, x0);
    gsl_vector_set(f, 1, y0);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_df(const gsl_vector* angles, void* params, gsl_matrix* J)
{
    // extract input angle
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate partial derivatives for Jacobian matrix
    const double df00 = -gsl_sf_sin(alpha);
    const double df01 = -gsl_sf_sin(beta);
    const double df10 =  gsl_sf_cos(alpha);
    const double df11 =  gsl_sf_sin(beta);

    // set Jacobian matrix
    gsl_matrix_set(J, 0, 0, df00);
    gsl_matrix_set(J, 0, 1, df01);
    gsl_matrix_set(J, 1, 0, df10);
    gsl_matrix_set(J, 1, 1, df11);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J)
{
    coords_f(angles, params, f);
    coords_df(angles, params, J);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
get_coords(gsl_vector* coords)
{
    // TODO: replace with platform specific code
    // read new coordinates from input
    float x, y;
    printf("Enter new X coordinate: ");
    scanf("%f", &x);
    printf("Enter new Y coordinate: ");
    scanf("%f", &y);

    // TODO: check for legal input bounds

    // store input in memory
    gsl_vector_set(coords, 0, x);
    gsl_vector_set(coords, 1, y);

    printf("x: %3.3f, y: %3.3f\n", x, y);
    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
    printf("iter = %3u x = % .6f % .6f "
           "f(x) = % .3e % .3e\n",
           iter,
           gsl_vector_get(s->x, 0),
           gsl_vector_get(s->x, 1),
           gsl_vector_get(s->f, 0),
           gsl_vector_get(s->f, 1) );

    // all good, return success
    return GSL_SUCCESS;
}
iter =   0 x =  2.443461  0.523599 f(x) =  9.998e-02 -2.905e-01
iter =   1 x =  2.308197  0.897453 f(x) = -4.876e-02  8.863e-02
iter =   2 x =  2.336417  0.808354 f(x) = -2.295e-03  1.077e-02
iter =   3 x =  2.342411  0.799205 f(x) = -1.653e-05  2.539e-04
iter =   4 x =  2.342579  0.799014 f(x) = -2.884e-09  3.705e-06
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
status = success
iter =   5 x =  2.342582  0.799011 f(x) = -7.438e-15  5.048e-08
calc_angles worked
Calculated angles: alpha:  2.342582, beta:  0.799011
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_multiroots.h>
#include <gsl/gsl_sf.h>

// constants
const double LENGTH = 6.0;
const double TOL    = 1.0e-6;

// params struct
struct rparams
{
    double x, y;
};

// calculate the primary and secondary angles for the given coordinates in coords
int calc_angles(gsl_vector* coords, gsl_vector* result_angles);
int coords_f(const gsl_vector* angles, void* params, gsl_vector* f);
int coords_df(const gsl_vector* angles, void* params, gsl_matrix* J);
int coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J);

// IO functions
int get_coords(gsl_vector* coords);

// helper/debug functions
int print_state(size_t iter, gsl_multiroot_fdfsolver* s);

int
main(int argc, char* argv[])
{
    const size_t n = 2;
    // initialize vectors: input coords, initial guess, result angles
    gsl_vector* coords = gsl_vector_alloc(n);
    gsl_vector* result_angles = gsl_vector_alloc(n);
    gsl_vector_set(result_angles, 0, 0.0);  // set result angles to zero
    gsl_vector_set(result_angles, 1, 0.0);

    // TODO: read coordinates from input
    // get_coords(coords);
    gsl_vector_set(coords, 0, 0.0);
    gsl_vector_set(coords, 1, 8.6);

    // calc new angles
    if(!calc_angles(coords, result_angles)) { printf("calc_angles worked\n"); }

    // output new angles
    printf("Calculated angles: alpha: % .6f, beta: % .6f\n",
           gsl_vector_get(result_angles, 0),
           gsl_vector_get(result_angles, 1) );

    // deallocate memory
    gsl_vector_free(coords);
    gsl_vector_free(result_angles);

    return 0;
}

//------------------------------------------------------------------------------
int
calc_angles(gsl_vector* coords, gsl_vector* result_angles)
{
    const gsl_multiroot_fdfsolver_type* T;
    gsl_multiroot_fdfsolver* s;

    int status;
    size_t iter = 0;
    const size_t n = 2;

    // coordinates whose's angles is to be found
    struct rparams p = { gsl_vector_get(coords, 0), gsl_vector_get(coords, 1) };
    gsl_multiroot_function_fdf f = { &coords_f,
                                     &coords_df,
                                     &coords_fdf,
                                     n, &p};

    // TODO: calculate inital guess
    double angles_init[2] = { 140.0*M_PI/180.0, 30*M_PI/180.0 };
    gsl_vector* angles = gsl_vector_alloc(n);

    gsl_vector_set(angles, 0, angles_init[0]);
    gsl_vector_set(angles, 1, angles_init[1]);

    T = gsl_multiroot_fdfsolver_gnewton;
    s = gsl_multiroot_fdfsolver_alloc(T, n);
    gsl_multiroot_fdfsolver_set(s, &f, angles);

    print_state(iter, s);

    do
    {
        iter++;
        status = gsl_multiroot_fdfsolver_iterate(s);

        print_state(iter, s);

        if(status) { break; }

        status = gsl_multiroot_test_residual(s->f, 1e-7);
    } while (status == GSL_CONTINUE && iter < 1000);

    printf("status = %s\n", gsl_strerror(status));
    print_state(iter, s);

    // store results in result_angles
    gsl_vector_memcpy(result_angles, s -> x);

    // sanity check
    if(gsl_vector_equal(result_angles, angles))
    {
        printf("Vectors are equal\n");
    }

    gsl_multiroot_fdfsolver_free(s);
    gsl_vector_free(angles);

    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_f(const gsl_vector* angles, void* params, gsl_vector* f)
{
    // extract c and y coordinates
    double x = ((struct rparams*) params)->x;
    double y = ((struct rparams*) params)->y;

    // extract input angles
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate coordinates from angles
    const double x0 = gsl_sf_cos(alpha) + gsl_sf_cos(beta) - x / LENGTH;
    const double y0 = gsl_sf_sin(alpha) + gsl_sf_sin(beta) - y / LENGTH;

    // save results
    gsl_vector_set(f, 0, x0);
    gsl_vector_set(f, 1, y0);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_df(const gsl_vector* angles, void* params, gsl_matrix* J)
{
    // extract input angle
    const double alpha = gsl_vector_get(angles, 0);
    const double beta  = gsl_vector_get(angles, 1);

    // calculate partial derivatives for Jacobian matrix
    const double df00 = -gsl_sf_sin(alpha);
    const double df01 = -gsl_sf_sin(beta);
    const double df10 =  gsl_sf_cos(alpha);
    const double df11 =  gsl_sf_sin(beta);

    // set Jacobian matrix
    gsl_matrix_set(J, 0, 0, df00);
    gsl_matrix_set(J, 0, 1, df01);
    gsl_matrix_set(J, 1, 0, df10);
    gsl_matrix_set(J, 1, 1, df11);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
coords_fdf(const gsl_vector* angles, void* params, gsl_vector* f, gsl_matrix* J)
{
    coords_f(angles, params, f);
    coords_df(angles, params, J);

    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
get_coords(gsl_vector* coords)
{
    // TODO: replace with platform specific code
    // read new coordinates from input
    float x, y;
    printf("Enter new X coordinate: ");
    scanf("%f", &x);
    printf("Enter new Y coordinate: ");
    scanf("%f", &y);

    // TODO: check for legal input bounds

    // store input in memory
    gsl_vector_set(coords, 0, x);
    gsl_vector_set(coords, 1, y);

    printf("x: %3.3f, y: %3.3f\n", x, y);
    // all good, return success
    return GSL_SUCCESS;
}

//------------------------------------------------------------------------------
int
print_state(size_t iter, gsl_multiroot_fdfsolver* s)
{
    printf("iter = %3ld x = % .6f % .6f "
           "f(x) = % .3e % .3e\n",
           iter,
           gsl_vector_get(s->x, 0),
           gsl_vector_get(s->x, 1),
           gsl_vector_get(s->f, 0),
           gsl_vector_get(s->f, 1) );

    // all good, return success
    return GSL_SUCCESS;
}