/*
  rb_gsl_array.h
  Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
    (C) Copyright 2001-2004 by Yoshiki Tsunesada

  Ruby/GSL is free software: you can redistribute it and/or modify it
  under the terms of the GNU General Public License.
  This library is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY
*/

#ifndef ___RB_GSL_ARRAY_H___
#define ___RB_GSL_ARRAY_H___

#include "ruby.h"
#include "rubyio.h"
#include <gsl/gsl_complex.h>
#include <gsl/gsl_block.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_vector_complex.h>
#include <gsl/gsl_vector_complex_double.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_matrix_complex_double.h>
#include <gsl/gsl_permutation.h>
#include <gsl/gsl_combination.h>
#include <gsl/gsl_sort.h>
#include <gsl/gsl_sort_vector.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_eigen.h>
#include <gsl/gsl_odeiv.h>
#include <gsl/gsl_blas.h>
#include "rb_gsl_common.h"
/*#include "rb_gsl.h"*/

EXTERN VALUE mgsl;
EXTERN VALUE cgsl_block;
EXTERN VALUE cgsl_vector, cgsl_vector_complex;

EXTERN VALUE cgsl_vector_col;
EXTERN VALUE cgsl_vector_col_view;
EXTERN VALUE cgsl_vector_complex_col;
EXTERN VALUE cgsl_vector_complex_col_view;
EXTERN VALUE cgsl_vector_view, cgsl_vector_complex_view;
EXTERN VALUE cgsl_vector_view_ro;
EXTERN VALUE cgsl_vector_complex_view_ro;
EXTERN VALUE cgsl_matrix, cgsl_matrix_complex;
EXTERN VALUE cgsl_matrix_view_ro;
EXTERN VALUE cgsl_matrix_complex_view_ro;
EXTERN VALUE cgsl_matrix_view, cgsl_matrix_complex_view;
EXTERN VALUE cgsl_permutation;
EXTERN VALUE cgsl_combination;
EXTERN VALUE cgsl_range, cgsl_linspace, cgsl_logspace;;
EXTERN VALUE cgsl_function;
EXTERN VALUE mgsl_narray;

gsl_matrix_view* gsl_matrix_view_alloc();
void gsl_matrix_view_free(gsl_matrix_view * mv);
gsl_vector_view* gsl_vector_view_alloc();
void gsl_vector_view_free(gsl_vector_view * v);
gsl_vector_complex_view* gsl_vector_complex_view_alloc();
void gsl_vector_complex_view_free(gsl_vector_view * vv);
gsl_matrix_complex_view* gsl_matrix_complex_view_alloc();
void gsl_matrix_complex_view_free(gsl_matrix_view * vv);

VALUE rb_gsl_vector_new(int argc, VALUE *argv, VALUE klass);

gsl_vector* get_cvector(VALUE v);
VALUE make_rarray_from_cvector(gsl_vector *v);
VALUE make_rarray_from_cpermutation(gsl_permutation *v);
gsl_vector* make_cvector_from_rarrays(VALUE a);
gsl_vector* make_cvector_from_rarray(VALUE a);
void cvector_set_from_carray(gsl_vector *v, const double *a);
void cvector_set_from_rarrays(gsl_vector *v, VALUE ary);
void cvector_set_from_rarray(gsl_vector *v, VALUE ary);
void carray_set_from_cvector(double *a, gsl_vector *v);
void carray_set_from_rarrays(double *a, VALUE ary);
void carray_set_from_rarray(double *a, VALUE ary);
int is_vector_p(VALUE obj);
void check_vector(VALUE obj);
int is_vector_complex_p(VALUE obj);
void check_vector_complex(VALUE obj);
int is_matrix_p(VALUE obj);
void check_matrix(VALUE obj);
int is_matrix_complex_p(VALUE obj);
void check_matrix_complex(VALUE obj);
gsl_complex* make_complex(double re, double im);
int is_permutation_p(VALUE obj);
void check_permutation(VALUE obj);
int is_combination_p(VALUE obj);
void check_combination(VALUE obj);
gsl_vector* get_vector(VALUE ary);
gsl_matrix* make_matrix_clone(gsl_matrix *m);
VALUE make_matrix_clone2(VALUE vm);
gsl_matrix_complex* make_matrix_complex_clone(gsl_matrix_complex *m);
int is_matrix_complex_p(VALUE obj);
void check_matrix_complex(VALUE obj);

double* get_vector_ptr(VALUE ary, size_t *stride, size_t *n);


gsl_matrix_complex* matrix_to_complex(gsl_matrix *m);

void gsl_matrix_complex_mul(gsl_matrix_complex *mnew, gsl_matrix_complex *m, 
			    gsl_matrix_complex *mb);
void gsl_matrix_mul(gsl_matrix *mnew, gsl_matrix *m, gsl_matrix *b);
void gsl_matrix_complex_mul_vector(gsl_vector_complex *vnew, gsl_matrix_complex *m, 
				   gsl_vector_complex *v);
void gsl_matrix_mul_vector(gsl_vector *vnew, gsl_matrix *m, gsl_vector *v);
gsl_vector_complex* vector_to_complex(gsl_vector *v);

gsl_vector* make_vector_clone(gsl_vector *v);
gsl_vector_complex* make_vector_complex_clone(gsl_vector_complex *v);
int gsl_vector_complex_add(gsl_vector_complex *cv, const gsl_vector_complex *cv2);
int gsl_vector_complex_sub(gsl_vector_complex *cv, const gsl_vector_complex *cv2);
int gsl_vector_complex_mul(gsl_vector_complex *cv, const gsl_vector_complex *cv2);
int gsl_vector_complex_div(gsl_vector_complex *cv, const gsl_vector_complex *cv2);
int gsl_vector_complex_add_constant(gsl_vector_complex *cv, gsl_complex b);
int gsl_vector_complex_scale(gsl_vector_complex *cv, gsl_complex b);
gsl_vector_view* rb_gsl_make_vector_view(double *data, size_t size, size_t stride);

void Init_gsl_array_complex();
void Init_gsl_range();
void Init_gsl_vector();
void Init_gsl_vector_complex();
void Init_gsl_matrix();
void Init_gsl_matrix_complex();
void Init_gsl_matrix();
void Init_gsl_permutation();
void Init_gsl_combination();
#endif
