~kamalmostafa/ubuntu/lucid/pdp/fix-504941-ftbfs

« back to all changes in this revision

Viewing changes to system/type/pdp_matrix.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-03-15 22:21:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050315222105-1q287rsihmd9j1tb
Tags: 1:0.12.4-2
* fixed the hardcoded depends
* added 3dp library

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
#include <string.h>
3
 
#include "pdp_matrix.h"
4
 
#include "pdp_packet.h"
5
 
#include "pdp_symbol.h"
6
 
#include "pdp_internals.h" // for pdp_packet_new, which is not a proper constructor
7
 
#include "pdp_post.h"
8
 
#include "pdp_type.h"
9
 
 
10
 
/* the class object */
11
 
static t_pdp_class *matrix_class;
12
 
 
13
 
 
14
 
 
15
 
/* declare header and subheader variables and exit with errval if invalid */
16
 
#define VALID_MATRIX_HEADER(packet, header, subheader, mtype, errval)   \
17
 
t_pdp *    header    = pdp_packet_header( packet );                     \
18
 
t_matrix * subheader = (t_matrix *)pdp_packet_subheader( packet );      \
19
 
if (! header ) return errval;                                           \
20
 
if (PDP_MATRIX != header->type) return errval;                          \
21
 
if (mtype) {if (subheader->type != mtype) return errval;}
22
 
 
23
 
 
24
 
int pdp_packet_matrix_isvalid(int p)
25
 
{
26
 
    VALID_MATRIX_HEADER(p, h, m, 0, 0);
27
 
    return 1;
28
 
}
29
 
 
30
 
 
31
 
void *pdp_packet_matrix_get_gsl_matrix(int p, u32 type)
32
 
{
33
 
    VALID_MATRIX_HEADER(p, h, m, type, 0);
34
 
    return &m->matrix;
35
 
}
36
 
 
37
 
void *pdp_packet_matrix_get_gsl_vector(int p, u32 type)
38
 
{
39
 
    VALID_MATRIX_HEADER(p, h, m, type, 0);
40
 
    return &m->vector;
41
 
}
42
 
 
43
 
int pdp_packet_matrix_get_type(int p)
44
 
{
45
 
    VALID_MATRIX_HEADER(p, h, m, 0, 0);
46
 
    return m->type;
47
 
}
48
 
 
49
 
int pdp_packet_matrix_isvector(int p)
50
 
{
51
 
    VALID_MATRIX_HEADER(p, h, m, 0, 0);
52
 
    return ((m->rows == 1) || (m->columns == 1));
53
 
}
54
 
 
55
 
int pdp_packet_matrix_ismatrix(int p)
56
 
{
57
 
    VALID_MATRIX_HEADER(p, h, m, 0, 0);
58
 
    return ((m->rows != 1) && (m->columns != 1));
59
 
}
60
 
 
61
 
 
62
 
 
63
 
 
64
 
/* gsl blas matrix/vector multiplication:
65
 
 
66
 
vector.vector
67
 
 
68
 
 (const gsl_vector * x, const gsl_vector * y, double * result) 
69
 
 
70
 
gsl_blas_sdot
71
 
gsl_blas_ddot
72
 
gsl_blas_cdot
73
 
gsl_blas_zdot
74
 
gsl_blas_cdotu
75
 
gsl_blas_zdotu
76
 
 
77
 
matrix.vector
78
 
 (
79
 
   CBLAS_TRANSPOSE_t 
80
 
   TransA, 
81
 
   double alpha, 
82
 
   const gsl_matrix * A, 
83
 
   const gsl_vector * x, 
84
 
   double beta, 
85
 
   gsl_vector * y
86
 
 )
87
 
 
88
 
gsl_blas_sgemv
89
 
gsl_blas_dgemv
90
 
gsl_blas_cgemv
91
 
gsl_blas_zgemv
92
 
 
93
 
matrix.matrix
94
 
 (
95
 
   CBLAS_TRANSPOSE_t TransA, 
96
 
   CBLAS_TRANSPOSE_t TransB, 
97
 
   double alpha, 
98
 
   const gsl_matrix * A, 
99
 
   const gsl_matrix * B, 
100
 
   double beta, 
101
 
   gsl_matrix * C
102
 
 )
103
 
 
104
 
gsl_blas_sgemm
105
 
gsl_blas_dgemm
106
 
gsl_blas_cgemm
107
 
gsl_blas_zgemm
108
 
 
109
 
*/
110
 
 
111
 
/* compute the matrix inverse using the LU decomposition */
112
 
/* it only works for double real/complex */
113
 
int pdp_packet_matrix_LU_to_inverse(int p)
114
 
{
115
 
    int new_p;
116
 
    u32 n;
117
 
    int type = pdp_packet_matrix_get_type(p);
118
 
    t_matrix *sheader = (t_matrix *)pdp_packet_subheader(p);
119
 
    gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p, type);
120
 
    gsl_matrix *im;
121
 
    if (!m) return -1;
122
 
    n = m->gsl_rows; 
123
 
    if (n != m->gsl_columns) return -1;
124
 
    new_p = pdp_packet_new_matrix(n, n, type);
125
 
    if (-1 == new_p) return -1;
126
 
    im = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(new_p, type);
127
 
 
128
 
    switch(type){
129
 
    case PDP_MATRIX_TYPE_RDOUBLE:
130
 
        gsl_linalg_LU_invert (m, &sheader->perm, im); break;
131
 
    case PDP_MATRIX_TYPE_CDOUBLE:
132
 
        gsl_linalg_complex_LU_invert ((gsl_matrix_complex *)m, &sheader->perm, (gsl_matrix_complex *)im); break;
133
 
    default:
134
 
        pdp_packet_mark_unused(new_p);
135
 
        new_p = -1;
136
 
    }
137
 
    return new_p;
138
 
}
139
 
/* compute the LU decomposition of a square matrix */
140
 
/* it only works for double real/complex */
141
 
int pdp_packet_matrix_LU(int p)
142
 
{
143
 
    int p_LU, bytes;
144
 
    u32 n;
145
 
    int type = pdp_packet_matrix_get_type(p);
146
 
    t_matrix *sh_m_LU;
147
 
    t_matrix *sh_m = (t_matrix *)pdp_packet_subheader(p);
148
 
    gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p, type);
149
 
    gsl_matrix *m_LU;
150
 
    if (!m) return -1;
151
 
    n = m->gsl_rows; 
152
 
    if (n != m->gsl_columns) return -1;
153
 
    p_LU = pdp_packet_new_matrix(n, n, type);
154
 
    if (-1 == p_LU) return -1;
155
 
    sh_m_LU  = (t_matrix *)pdp_packet_subheader(p_LU);
156
 
    m_LU = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p_LU, type);
157
 
    /* copy matrix data: move this to copy method */
158
 
    memcpy(pdp_packet_data(p_LU), pdp_packet_data(p), sh_m->block.size); 
159
 
 
160
 
    switch(type){
161
 
    case PDP_MATRIX_TYPE_RDOUBLE:
162
 
        gsl_linalg_LU_decomp (m_LU, &sh_m_LU->perm, &sh_m_LU->signum); break; 
163
 
    case PDP_MATRIX_TYPE_CDOUBLE:
164
 
        gsl_linalg_complex_LU_decomp ((gsl_matrix_complex *)m_LU, &sh_m_LU->perm, &sh_m_LU->signum); break; 
165
 
    default:
166
 
        pdp_packet_mark_unused(p_LU);
167
 
        p_LU = -1;
168
 
    }
169
 
    return p_LU;
170
 
}
171
 
 
172
 
int pdp_packet_matrix_LU_solve(int p_matrix, int p_vector)
173
 
{
174
 
    int type = pdp_packet_matrix_get_type(p_matrix);
175
 
    int p_result_vector = pdp_packet_clone_rw(p_vector);
176
 
    gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p_matrix, type);
177
 
    gsl_vector *v = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(p_vector, type);
178
 
    gsl_vector *rv = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(p_result_vector, type);
179
 
    t_matrix *sh_m = (t_matrix *)pdp_packet_subheader(p_matrix);
180
 
 
181
 
    if (!(m && v && rv)) goto error;
182
 
 
183
 
    switch(type){
184
 
    case PDP_MATRIX_TYPE_RDOUBLE:
185
 
        if (gsl_linalg_LU_solve (m, &sh_m->perm, v, rv)) goto error; break;
186
 
    case PDP_MATRIX_TYPE_CDOUBLE:
187
 
        if(gsl_linalg_complex_LU_solve ((gsl_matrix_complex*)m, &sh_m->perm, 
188
 
                (gsl_vector_complex *)v, (gsl_vector_complex *)rv)) goto error; break;
189
 
    default:
190
 
        goto error;
191
 
    }
192
 
    return p_result_vector;
193
 
 
194
 
 error:
195
 
    pdp_packet_mark_unused(p_result_vector);
196
 
    //post("error");
197
 
    return -1;
198
 
}
199
 
 
200
 
/* matrix matrix mul: C is defining type 
201
 
   returns 0 on success */
202
 
int pdp_packet_matrix_blas_mm
203
 
(
204
 
 CBLAS_TRANSPOSE_t TransA,
205
 
 CBLAS_TRANSPOSE_t TransB,
206
 
 int pA,
207
 
 int pB,
208
 
 int pC,
209
 
 float scale_r,
210
 
 float scale_i
211
 
)
212
 
{
213
 
    gsl_complex_float cf_scale = {{scale_r, scale_i}};
214
 
    gsl_complex cd_scale = {{(double)scale_r, (double)scale_i}};
215
 
    gsl_complex_float cf_one = {{1.0f, 0.0f}};
216
 
    gsl_complex cd_one = {{1.0, 0.0}};
217
 
    gsl_matrix *mA, *mB, *mC;
218
 
    int type;
219
 
    type = pdp_packet_matrix_get_type(pC);
220
 
    mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA,type);
221
 
    mB = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pB,type);
222
 
    mC = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pC,type);
223
 
 
224
 
    if (!(mA && mB)) return 1;
225
 
 
226
 
 
227
 
    switch(type){
228
 
    case PDP_MATRIX_TYPE_RFLOAT:
229
 
        return gsl_blas_sgemm(TransA, TransB, scale_r, (gsl_matrix_float *)mA, 
230
 
                              (gsl_matrix_float *)mB, 1.0f, (gsl_matrix_float *)mC); 
231
 
    case PDP_MATRIX_TYPE_RDOUBLE:
232
 
        return gsl_blas_dgemm(TransA, TransB, (double)scale_r, (gsl_matrix *)mA, 
233
 
                              (gsl_matrix *)mB, 1.0, (gsl_matrix *)mC);
234
 
    case PDP_MATRIX_TYPE_CFLOAT:
235
 
        return gsl_blas_cgemm(TransA, TransB, cf_scale, (gsl_matrix_complex_float *)mA, 
236
 
                              (gsl_matrix_complex_float *)mB, cf_one, (gsl_matrix_complex_float *)mC); 
237
 
    case PDP_MATRIX_TYPE_CDOUBLE:
238
 
        return gsl_blas_zgemm(TransA, TransB, cd_scale, (gsl_matrix_complex *)mA, 
239
 
                              (gsl_matrix_complex *)mB, cd_one, (gsl_matrix_complex *)mC); 
240
 
    default:
241
 
        return 0;
242
 
    }
243
 
}
244
 
 
245
 
/* matrix vector mul: C is defining type 
246
 
   returns 0 on success */
247
 
int pdp_packet_matrix_blas_mv
248
 
(
249
 
 CBLAS_TRANSPOSE_t TransA,
250
 
 int pA,
251
 
 int pb,
252
 
 int pc,
253
 
 float scale_r,
254
 
 float scale_i
255
 
)
256
 
{
257
 
    gsl_complex_float cf_scale = {{scale_r, scale_i}};
258
 
    gsl_complex cd_scale = {{(double)scale_r, (double)scale_i}};
259
 
    gsl_complex_float cf_one = {{1.0f, 0.0f}};
260
 
    gsl_complex cd_one = {{1.0, 0.0}};
261
 
    gsl_matrix *mA;
262
 
    gsl_vector *vb, *vc;
263
 
    int type;
264
 
    type = pdp_packet_matrix_get_type(pA);
265
 
    mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA,type);
266
 
    vb = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(pb,type);
267
 
    vc = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(pc,type);
268
 
 
269
 
    if (!(vb && vc)) return 1;
270
 
 
271
 
 
272
 
    switch(type){
273
 
    case PDP_MATRIX_TYPE_RFLOAT:
274
 
        return gsl_blas_sgemv(TransA, scale_r, (gsl_matrix_float *)mA, 
275
 
                              (gsl_vector_float *)vb, 1.0f, (gsl_vector_float *)vc); 
276
 
    case PDP_MATRIX_TYPE_RDOUBLE:
277
 
        return gsl_blas_dgemv(TransA, (double)scale_r, (gsl_matrix *)mA, 
278
 
                              (gsl_vector *)vb, 1.0, (gsl_vector *)vc);
279
 
    case PDP_MATRIX_TYPE_CFLOAT:
280
 
        return gsl_blas_cgemv(TransA, cf_scale, (gsl_matrix_complex_float *)mA, 
281
 
                              (gsl_vector_complex_float *)vb, cf_one, (gsl_vector_complex_float *)vc); 
282
 
    case PDP_MATRIX_TYPE_CDOUBLE:
283
 
        return gsl_blas_zgemv(TransA, cd_scale, (gsl_matrix_complex *)mA, 
284
 
                              (gsl_vector_complex *)vb, cd_one, (gsl_vector_complex *)vc); 
285
 
    default:
286
 
        return 0;
287
 
    }
288
 
}
289
 
 
290
 
 
291
 
 
292
 
t_pdp_symbol *_pdp_matrix_get_description(t_pdp *header)
293
 
{
294
 
    t_matrix *m = (t_matrix *)(&header->info.raw);
295
 
    char description[100];
296
 
    char *c = description;
297
 
    int encoding;
298
 
 
299
 
    if (!header) return pdp_gensym("invalid");
300
 
    else if (!header->desc){
301
 
        /* if description is not defined, try to reconstruct it (for backwards compat) */
302
 
        if (header->type == PDP_MATRIX){
303
 
 
304
 
            c += sprintf(c, "matrix");
305
 
 
306
 
            switch(m->type){
307
 
            case PDP_MATRIX_TYPE_RFLOAT: c += sprintf(c, "/float/real"); break;
308
 
            case PDP_MATRIX_TYPE_CFLOAT: c += sprintf(c, "/float/complex"); break;
309
 
            case PDP_MATRIX_TYPE_RDOUBLE: c += sprintf(c, "/double/real"); break;
310
 
            case PDP_MATRIX_TYPE_CDOUBLE: c += sprintf(c, "/double/complex"); break;
311
 
            default:
312
 
                c += sprintf(c, "/unknown"); goto exit;
313
 
            }
314
 
 
315
 
            c += sprintf(c, "/%dx%d", (int)m->rows, (int)m->columns);
316
 
            
317
 
        exit:
318
 
            return pdp_gensym(description);
319
 
        } 
320
 
        else return pdp_gensym("unknown");
321
 
    }
322
 
    else return header->desc;
323
 
}
324
 
 
325
 
 
326
 
 
327
 
static void _pdp_matrix_copy(t_pdp *dst, t_pdp *src);
328
 
static void _pdp_matrix_clone(t_pdp *dst, t_pdp *src);
329
 
static void _pdp_matrix_reinit(t_pdp *dst);
330
 
static void _pdp_matrix_cleanup(t_pdp *dst);
331
 
 
332
 
static size_t _pdp_matrix_mdata_byte_size(u32 rows, u32 columns, u32 type)
333
 
{
334
 
    size_t dsize = rows * columns;
335
 
    switch (type){
336
 
    case PDP_MATRIX_TYPE_RFLOAT:   dsize *= sizeof(float);    break;
337
 
    case PDP_MATRIX_TYPE_CFLOAT:   dsize *= 2*sizeof(float);  break;
338
 
    case PDP_MATRIX_TYPE_RDOUBLE:  dsize *= sizeof(double);   break;
339
 
    case PDP_MATRIX_TYPE_CDOUBLE:  dsize *= 2*sizeof(double); break;
340
 
    default: dsize = 0;
341
 
    }
342
 
    return dsize;
343
 
}
344
 
 
345
 
 
346
 
static size_t _pdp_matrix_pdata_vector_size(u32 rows, u32 columns)
347
 
{
348
 
    return (rows>columns ? rows : columns);
349
 
}
350
 
 
351
 
 
352
 
static void _pdp_matrix_init(t_pdp *dst, u32 rows, u32 columns, u32 type)
353
 
{
354
 
    int i;
355
 
    t_matrix *m = (t_matrix *)(&dst->info.raw);
356
 
    void *d = ((void *)dst) + PDP_HEADER_SIZE;
357
 
    int matrix_bytesize = _pdp_matrix_mdata_byte_size(rows, columns, type);
358
 
    int permsize =  _pdp_matrix_pdata_vector_size(rows, columns);
359
 
 
360
 
    /* set meta data */
361
 
    m->type = type;
362
 
    m->rows = rows;
363
 
    m->columns = columns;
364
 
 
365
 
    /* set the block data */
366
 
    m->block.size = matrix_bytesize;
367
 
    m->block.data = (double *)d;
368
 
 
369
 
    /* set the vector view */
370
 
    m->vector.size = (1==columns) ? rows : columns;
371
 
    m->vector.stride = 1;
372
 
    m->vector.data = (double *)d;
373
 
    m->vector.block = &m->block;
374
 
    m->vector.owner = 0;
375
 
 
376
 
    /* set the matrix view */
377
 
    m->matrix.gsl_rows = rows;
378
 
    m->matrix.gsl_columns = columns;
379
 
    m->matrix.tda = columns;
380
 
    m->matrix.data = (double *)d;
381
 
    m->matrix.block = &m->block;
382
 
    m->matrix.owner = 0;
383
 
 
384
 
    /* set the permutation object & init */
385
 
    m->perm.size = permsize;
386
 
    m->perm.data = (size_t *)(d + matrix_bytesize);
387
 
    for(i=0; i<permsize; i++) m->perm.data[i] = i;
388
 
    m->signum = -1;
389
 
    
390
 
    /* init packet header */
391
 
    dst->theclass = matrix_class;
392
 
    dst->desc = _pdp_matrix_get_description(dst);
393
 
 
394
 
}
395
 
 
396
 
static void _pdp_matrix_clone(t_pdp *dst, t_pdp *src)
397
 
{
398
 
    t_matrix *m = (t_matrix *)(&src->info.raw);
399
 
    _pdp_matrix_init(dst, m->rows, m->columns, m->type);
400
 
 
401
 
}
402
 
static void _pdp_matrix_copy(t_pdp *dst, t_pdp *src)
403
 
{
404
 
    _pdp_matrix_clone(dst, src);
405
 
    memcpy(dst + PDP_HEADER_SIZE, src + PDP_HEADER_SIZE, src->size - PDP_HEADER_SIZE);
406
 
    //post("matrix copy successful");
407
 
}
408
 
static void _pdp_matrix_reinit(t_pdp *dst)
409
 
{
410
 
    /* nothing to do, assuming data is correct */
411
 
}
412
 
static void _pdp_matrix_cleanup(t_pdp *dst)
413
 
{
414
 
    /* no extra memory to free */
415
 
}
416
 
 
417
 
int pdp_packet_new_matrix(u32 rows, u32 columns, u32 type)
418
 
{
419
 
    t_pdp *header;
420
 
    int dsize, p;
421
 
 
422
 
    /* compute the blocksize for the matrix data */
423
 
    /* if 0, something went wrong -> return invalid packet */
424
 
    if (!(dsize = _pdp_matrix_mdata_byte_size(rows, columns, type))) return -1;
425
 
    dsize += sizeof(size_t) * _pdp_matrix_pdata_vector_size(rows, columns);
426
 
 
427
 
    p = pdp_packet_new(PDP_MATRIX, dsize);
428
 
    if (-1 == p) return -1;
429
 
    header = pdp_packet_header(p);
430
 
    
431
 
    _pdp_matrix_init(header, rows, columns, type);
432
 
 
433
 
    return p;
434
 
}
435
 
 
436
 
int pdp_packet_new_matrix_product_result(CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, int pA, int pB)
437
 
{
438
 
    gsl_matrix *mA, *mB;
439
 
    u32 type = pdp_packet_matrix_get_type(pA);
440
 
 
441
 
    u32 colA, colB, rowA, rowB;
442
 
   
443
 
    /* check if A is a matrix */
444
 
    if (!type) return -1;
445
 
 
446
 
    mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA, type);
447
 
    mB = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pB, type);
448
 
 
449
 
    /* check if A and B are same type */
450
 
    if (!mB) return -1;
451
 
 
452
 
    /* get dims A */
453
 
    if (TransA == CblasNoTrans){
454
 
        rowA = mA->gsl_rows;
455
 
        colA = mA->gsl_columns;
456
 
    }
457
 
    else {
458
 
        rowA = mA->gsl_columns;
459
 
        colA = mA->gsl_rows;
460
 
    }
461
 
 
462
 
    /* get dims B */
463
 
    if (TransB == CblasNoTrans){
464
 
        rowB = mB->gsl_rows;
465
 
        colB = mB->gsl_columns;
466
 
    }
467
 
    else {
468
 
        rowB = mB->gsl_columns;
469
 
        colB = mB->gsl_rows;
470
 
    }
471
 
 
472
 
    /* check if sizes are compatible */
473
 
    if (colA != rowB) return -1;
474
 
 
475
 
    /* create new packet */
476
 
    return pdp_packet_new_matrix(rowA, colB, type);
477
 
}
478
 
 
479
 
void pdp_packet_matrix_setzero(int p)
480
 
{
481
 
    t_matrix *m;
482
 
    if (!pdp_packet_matrix_isvalid(p)) return;
483
 
    m = (t_matrix *) pdp_packet_subheader(p);
484
 
    memset(m->block.data, 0, m->block.size);
485
 
}
486
 
 
487
 
 
488
 
 
489
 
/* type conversion programs */
490
 
static int _pdp_packet_convert_matrix_to_greyimage(int packet, t_pdp_symbol *dest_template)
491
 
{
492
 
    t_pdp *header = pdp_packet_header(packet);
493
 
    t_matrix *matrix = (t_matrix *)pdp_packet_subheader(packet);
494
 
    void *data = pdp_packet_data(packet);
495
 
    s16 *new_data;
496
 
    u32 c,r, nbelements;
497
 
    int new_p;
498
 
    u32 i;
499
 
 
500
 
    c = matrix->columns;
501
 
    r = matrix->rows;
502
 
    nbelements = c*r;
503
 
 
504
 
    new_p = pdp_packet_new_image_grey(c,r);
505
 
    if (-1 == new_p) return -1;
506
 
    new_data = (s16 *)pdp_packet_data(new_p);
507
 
 
508
 
    /* convert first channel */
509
 
    switch(matrix->type){
510
 
    case PDP_MATRIX_TYPE_RFLOAT:
511
 
        for (i=0; i<nbelements; i++) (new_data)[i] = (s16)(((float *)data)[i] * (float)0x8000); break;
512
 
    case PDP_MATRIX_TYPE_CFLOAT: //only copy real channel
513
 
        for (i=0; i<nbelements; i++) (new_data)[i] = (s16)(((float *)data)[i<<1] * (float)0x8000); break;
514
 
    case PDP_MATRIX_TYPE_RDOUBLE:
515
 
        for (i=0; i<nbelements; i++) (new_data)[i] = (s16)(((double *)data)[i] * (float)0x8000); break;
516
 
    case PDP_MATRIX_TYPE_CDOUBLE: //only copy real channel
517
 
        for (i=0; i<nbelements; i++) (new_data)[i] = (s16)(((double *)data)[i<<1] * (float)0x8000); break;
518
 
    default:
519
 
        pdp_packet_mark_unused(new_p);
520
 
        new_p = -1;
521
 
    }   
522
 
    return new_p;
523
 
}
524
 
 
525
 
static int _pdp_packet_convert_image_to_matrix(int packet, t_pdp_symbol *dest_template, int type)
526
 
{
527
 
    t_pdp *header = pdp_packet_header(packet);
528
 
    t_image *image = pdp_packet_image_info(packet);
529
 
    s16 *data = (s16 *)pdp_packet_data(packet);
530
 
    void *new_data;
531
 
    u32 w,h, nbelements;
532
 
    int new_p;
533
 
    int encoding = image->encoding;
534
 
    u32 i;
535
 
 
536
 
    if (!pdp_packet_image_isvalid(packet)) return -1;
537
 
    w = image->width;
538
 
    h = image->height;
539
 
    nbelements = w*h;
540
 
 
541
 
    new_p = pdp_packet_new_matrix(h,w, type);
542
 
    if (-1 == new_p) return -1;
543
 
    new_data = pdp_packet_data(new_p);
544
 
 
545
 
    switch (encoding){
546
 
    case PDP_IMAGE_YV12:
547
 
    case PDP_IMAGE_GREY:
548
 
    case PDP_IMAGE_MCHP:
549
 
        /* convert first channel */
550
 
        switch(type){
551
 
        case PDP_MATRIX_TYPE_RFLOAT:
552
 
            for (i=0; i<nbelements; i++)
553
 
                ((float *)new_data)[i] = ((float)data[i]) * (1.0f / (float)0x8000); break;
554
 
        case PDP_MATRIX_TYPE_RDOUBLE:
555
 
            for (i=0; i<nbelements; i++)
556
 
                ((double *)new_data)[i] = ((double)data[i]) * (1.0f / (double)0x8000); break;
557
 
        case PDP_MATRIX_TYPE_CFLOAT:
558
 
            for (i=0; i<nbelements; i++){
559
 
                ((float *)new_data)[i*2] = ((float)data[i]) * (1.0f / (float)0x8000); 
560
 
                ((float *)new_data)[i*2+1] = 0.0f;
561
 
            }
562
 
            break;
563
 
        case PDP_MATRIX_TYPE_CDOUBLE:
564
 
            for (i=0; i<nbelements; i++){
565
 
                ((double *)new_data)[i*2] = ((double)data[i]) * (1.0f / (double)0x8000); 
566
 
                ((double *)new_data)[i*2+1] = 0.0;
567
 
            }
568
 
            break;
569
 
        default:
570
 
            pdp_post("_pdp_packet_convert_image_to_matrix: INTERNAL ERROR");
571
 
        }
572
 
        break;
573
 
    default:
574
 
        pdp_packet_mark_unused(new_p);
575
 
        new_p = -1;
576
 
        break;
577
 
    }
578
 
 
579
 
    return new_p;
580
 
 
581
 
}
582
 
 
583
 
static int _pdp_packet_convert_image_to_floatmatrix(int packet, t_pdp_symbol *dest_template){
584
 
    return _pdp_packet_convert_image_to_matrix(packet, dest_template, PDP_MATRIX_TYPE_RFLOAT);}
585
 
static int _pdp_packet_convert_image_to_doublematrix(int packet, t_pdp_symbol *dest_template){
586
 
    return _pdp_packet_convert_image_to_matrix(packet, dest_template, PDP_MATRIX_TYPE_RDOUBLE);}
587
 
static int _pdp_packet_convert_image_to_complexfloatmatrix(int packet, t_pdp_symbol *dest_template){
588
 
    return _pdp_packet_convert_image_to_matrix(packet, dest_template, PDP_MATRIX_TYPE_CFLOAT);}
589
 
static int _pdp_packet_convert_image_to_complexdoublematrix(int packet, t_pdp_symbol *dest_template){
590
 
    return _pdp_packet_convert_image_to_matrix(packet, dest_template, PDP_MATRIX_TYPE_CDOUBLE);}
591
 
 
592
 
 
593
 
static int _pdp_packet_matrix_convert_fallback(int packet, t_pdp_symbol *dest_template)
594
 
{
595
 
    pdp_post("can't convert image type %s to %s",
596
 
         pdp_packet_get_description(packet)->s_name, dest_template->s_name);
597
 
 
598
 
    return -1;
599
 
}
600
 
 
601
 
 
602
 
/* this seems like a nice spot to place a dummy gsl signal handler */
603
 
static void _gsl_error_handler (const char * reason, 
604
 
              const char * file, 
605
 
              int line, 
606
 
              int gsl_errno)
607
 
{
608
 
    //pdp_post("gsl error:\nREASON: %s\nFILE:%s\nLINE:%d\nERRNO:%d", reason, file, line, gsl_errno);
609
 
}
610
 
 
611
 
static int pdp_matrix_factory(t_pdp_symbol *type)
612
 
{
613
 
    return -1;
614
 
}
615
 
void pdp_matrix_setup(void)
616
 
{
617
 
    t_pdp_conversion_program *program;
618
 
 
619
 
 
620
 
    /* setup the class */
621
 
    matrix_class = pdp_class_new(pdp_gensym("matrix/*/*/*"), pdp_matrix_factory);
622
 
    matrix_class->copy = _pdp_matrix_copy;
623
 
    //matrix_class->clone = _pdp_matrix_clone; // is now solved through (symbol based) constructor
624
 
    matrix_class->wakeup = _pdp_matrix_reinit;
625
 
    matrix_class->cleanup = _pdp_matrix_cleanup;
626
 
    
627
 
 
628
 
    /* image -> matrix: default = double/real (most ops available) */
629
 
    program = pdp_conversion_program_new(_pdp_packet_convert_image_to_doublematrix, 0);
630
 
    pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/double/real/*"), program);
631
 
    program = pdp_conversion_program_new(_pdp_packet_convert_image_to_floatmatrix, 0);
632
 
    pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/float/real/*"), program);
633
 
    program = pdp_conversion_program_new(_pdp_packet_convert_image_to_complexdoublematrix, 0);
634
 
    pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/double/complex/*"), program);
635
 
    program = pdp_conversion_program_new(_pdp_packet_convert_image_to_complexfloatmatrix, 0);
636
 
    pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/float/complex/*"), program);
637
 
 
638
 
    /* matrix -> image */
639
 
    program = pdp_conversion_program_new(_pdp_packet_convert_matrix_to_greyimage, 0);
640
 
    pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("image/grey/*"), program);
641
 
 
642
 
    /* fallbacks */
643
 
    program = pdp_conversion_program_new(_pdp_packet_matrix_convert_fallback, 0);
644
 
    pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("image/*/*"), program);
645
 
    pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("bitmap/*/*"), program);
646
 
    pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/*/*/*/*"), program);
647
 
    pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("matrix/*/*/*/*"), program);
648
 
 
649
 
    /* setup gsl handler */
650
 
    if(gsl_set_error_handler(_gsl_error_handler)){
651
 
        pdp_post("pdp_matrix_setup: WARNING: overriding gsl error handler.");
652
 
    }    
653
 
 
654
 
}