File: mlgsl_wavelet.c

package info (click to toggle)
ocamlgsl 0.6.0-3
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 4,024 kB
  • ctags: 3,091
  • sloc: ml: 8,539; ansic: 7,338; makefile: 262; sh: 150; awk: 13
file content (123 lines) | stat: -rw-r--r-- 3,186 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* ocamlgsl - OCaml interface to GSL                        */
/* Copyright (©) 2005 - Olivier Andrieu                     */
/* distributed under the terms of the GPL version 2         */

#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/callback.h>
#include <caml/bigarray.h>

#include <gsl/gsl_errno.h>
#include <gsl/gsl_wavelet.h>
#include <gsl/gsl_wavelet2d.h>

#include "mlgsl_matrix_double.h"
#include "wrappers.h"

static const gsl_wavelet_type *
gslwavelettype_val (value v)
{
  const gsl_wavelet_type *w_type[] = {
    gsl_wavelet_daubechies,
    gsl_wavelet_daubechies_centered,
    gsl_wavelet_haar,
    gsl_wavelet_haar_centered,
    gsl_wavelet_bspline,
    gsl_wavelet_bspline_centered };
  return w_type [ Int_val (v) ] ;
}

CAMLprim value
ml_gsl_wavelet_alloc (value ty, value k)
{
  value r;
  gsl_wavelet *w;
  w = gsl_wavelet_alloc (gslwavelettype_val (ty), Long_val (k));
  Abstract_ptr (r, w);
  return r;
}

#define Wavelet_val(v) (gsl_wavelet *)Field(v, 0)

ML1 (gsl_wavelet_free, Wavelet_val, Unit)
ML1 (gsl_wavelet_name, Wavelet_val, copy_string)

CAMLprim value
ml_gsl_wavelet_workspace_alloc (value n)
{
  value r;
  gsl_wavelet_workspace *ws;
  ws = gsl_wavelet_workspace_alloc (Long_val (n));
  Abstract_ptr (r, ws);
  return r;
}

#define WS_val(v) (gsl_wavelet_workspace *)Field(v, 0)

CAMLprim value
ml_gsl_wavelet_workspace_size (value ws)
{
  return Val_long ((WS_val (ws))->n);
}

ML1 (gsl_wavelet_workspace_free, WS_val, Unit)

static inline gsl_wavelet_direction
gsl_direction_val (value v)
{
  static const gsl_wavelet_direction conv[] = { 
    gsl_wavelet_forward, 
    gsl_wavelet_backward };
  return conv [ Int_val (v) ];
}

static void
check_array (value vf)
{
  mlsize_t len = Double_array_length (Field (vf, 0));
  size_t off    = Long_val (Field (vf, 1));
  size_t n      = Long_val (Field (vf, 2));
  size_t stride = Long_val (Field (vf, 3));
  if (off + (n - 1) * stride >= len)
    GSL_ERROR_VOID ("Inconsistent array specification", GSL_EBADLEN);
}

CAMLprim value
ml_gsl_wavelet_transform (value w, value dir, value vf, value ws)
{
  double *data  = Double_array_val (Field (vf, 0)) + Long_val (Field (vf, 1));
  size_t n = Long_val (Field (vf, 2));
  size_t stride = Long_val (Field (vf, 3));
  check_array (vf);
  gsl_wavelet_transform (Wavelet_val (w), data, stride, n,
			 gsl_direction_val (dir), WS_val (ws));
  return Val_unit;
}

CAMLprim value
ml_gsl_wavelet_transform_bigarray (value w, value dir, value b, value ws)
{
  struct caml_bigarray *bigarr = Bigarray_val(b);
  double *data  = bigarr->data;
  size_t n      = bigarr->dim[0];
  gsl_wavelet_transform (Wavelet_val (w), data, 1, n,
			 gsl_direction_val (dir), WS_val (ws));
  return Val_unit;
}


/* 2D transforms */
CAMLprim value
ml_gsl_wavelet2d_transform_matrix (value w, value ordering,
				   value dir, value a, value ws)
{
  _DECLARE_MATRIX(a);
  _CONVERT_MATRIX(a);
  if (Int_val (ordering) == 0)
    gsl_wavelet2d_transform_matrix (Wavelet_val (w), &m_a,
				    gsl_direction_val (dir), WS_val (ws));
  else
    gsl_wavelet2d_nstransform_matrix (Wavelet_val (w), &m_a,
				      gsl_direction_val (dir), WS_val (ws));
  return Val_unit;
}