kopia lustrzana https://github.com/Dsplib/libdspl-2.0
added matrix_lu decomposition
rodzic
b50b0529a5
commit
ef1ba40bfb
|
@ -103,6 +103,34 @@ int DSPL_API decimate_cmplx(complex_t* x, int n, int dec,
|
|||
return RES_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Find max(|a|)
|
||||
*******************************************************************************/
|
||||
int DSPL_API find_max_abs(double* a, int n, double* m, int* ind)
|
||||
{
|
||||
int k, i;
|
||||
double t;
|
||||
if(!a)
|
||||
return ERROR_PTR;
|
||||
if(n < 1)
|
||||
return ERROR_SIZE;
|
||||
t = fabs(a[0]);
|
||||
i = 0;
|
||||
for(k = 1; k < n; k++)
|
||||
{
|
||||
if(fabs(a[k]) > t)
|
||||
{
|
||||
t = a[k];
|
||||
i = k;
|
||||
}
|
||||
}
|
||||
if(m)
|
||||
*m = t;
|
||||
if(ind)
|
||||
*ind = i;
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Flip real array in place
|
||||
|
|
|
@ -88,6 +88,9 @@ int win_rect (double *w, int n);
|
|||
|
||||
int fir_linphase_lpf(int ord, double wp, int wintype,
|
||||
double winparam, double* h);
|
||||
|
||||
#define MATRIX_SINGULAR_THRESHOLD 1E-14
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -59,7 +59,43 @@ int DSPL_API matrix_create(matrix_t* a, int n, int m, int type)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
matrix_create eye
|
||||
*******************************************************************************/
|
||||
int DSPL_API matrix_create_eye(matrix_t* a, int n, int type)
|
||||
{
|
||||
double *pr;
|
||||
complex_t *pc;
|
||||
int err, m, k;
|
||||
|
||||
err = matrix_create(a, n, n, type);
|
||||
if(err != RES_OK)
|
||||
return RES_OK;
|
||||
|
||||
k = 0;
|
||||
if((a->type & DAT_MASK) == DAT_DOUBLE)
|
||||
{
|
||||
pr = (double*) a->dat;
|
||||
memset(pr, 0, n*n*sizeof(double));
|
||||
for(m = 0; m < n; m++)
|
||||
{
|
||||
pr[k] = 1.0;
|
||||
k += n+1;
|
||||
}
|
||||
}
|
||||
|
||||
if((a->type & DAT_MASK) == DAT_COMPLEX)
|
||||
{
|
||||
pc = (complex_t*) a->dat;
|
||||
memset(pc, 0, n*n*sizeof(complex_t));
|
||||
for(m = 0; m < n; m++)
|
||||
{
|
||||
RE(pc[k]) = 1.0;
|
||||
k += n+1;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -76,7 +112,68 @@ void DSPL_API matrix_free(matrix_t* a)
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
matrix LU decomposition
|
||||
*******************************************************************************/
|
||||
int DSPL_API matrix_lu(matrix_t* a, matrix_t* L, matrix_t* U, matrix_t* P)
|
||||
{
|
||||
int err, k, n, m, N, ind;
|
||||
double *ra, *rl, *ru, mu, ukk, gmax;
|
||||
|
||||
if(!a || !L || !U || !P)
|
||||
return ERROR_PTR;
|
||||
|
||||
if(a->n != a->m || a->n < 1)
|
||||
return ERROR_MATRIX_SIZE;
|
||||
|
||||
N = a->n;
|
||||
err = matrix_create(L, N, N, a->type);
|
||||
if(err != RES_OK)
|
||||
return err;
|
||||
|
||||
err = matrix_create(U, N, N, a->type);
|
||||
if(err != RES_OK)
|
||||
return err;
|
||||
err = matrix_create_eye(P, N, a->type);
|
||||
if(err != RES_OK)
|
||||
return err;
|
||||
|
||||
if((a->type & DAT_MASK) == DAT_DOUBLE)
|
||||
{
|
||||
rl = (double*)L->dat;
|
||||
ru = (double*)U->dat;
|
||||
|
||||
memcpy(ru, (double*)a->dat, N*N*sizeof(double));
|
||||
memset(rl, 0, N*N*sizeof(double));
|
||||
|
||||
find_max_abs(ru, N*N, &gmax, NULL);
|
||||
for(k = 0; k < N; k++)
|
||||
{
|
||||
find_max_abs(ru+k*N+k, N-k, NULL, &ind);
|
||||
ind += k;
|
||||
matrix_swap_rows(U, k, ind);
|
||||
matrix_swap_rows(L, k, ind);
|
||||
matrix_swap_rows(P, k, ind);
|
||||
ukk = ru[N*k+k];
|
||||
if(fabs(ukk / gmax) < MATRIX_SINGULAR_THRESHOLD)
|
||||
return ERROR_MATRIX_SINGULAR;
|
||||
|
||||
for(m = k+1; m < N; m++)
|
||||
{
|
||||
mu = ru[m+k*N] / ukk;
|
||||
rl[m+k*N] = mu;
|
||||
for(n = k; n < N; n++)
|
||||
{
|
||||
ru[m + n*N] -= ru[k + n*N] * mu;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(n =0; n < N; n++)
|
||||
rl[n+n*N] = 1.0;
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -125,7 +222,65 @@ int DSPL_API matrix_print(matrix_t* a, const char* name, const char* format)
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
matrix swap 2 elements
|
||||
*******************************************************************************/
|
||||
int DSPL_API matrix_swap(matrix_t* a, int r0, int c0, int r1, int c1)
|
||||
{
|
||||
double tr;
|
||||
complex_t tc;
|
||||
double *pr;
|
||||
complex_t *pc;
|
||||
|
||||
if(!a)
|
||||
return ERROR_PTR;
|
||||
if(r0 >= a->n || r1 >= a->n || c0 >= a->m || c1 >= a->m)
|
||||
return ERROR_MATRIX_INDEX;
|
||||
|
||||
if((a->type & DAT_MASK) == DAT_DOUBLE)
|
||||
{
|
||||
pr = (double*)(a->dat);
|
||||
tr = pr[r0 + c0 * a->n];
|
||||
pr[r0 + c0 * a->n] = pr[r1 + c1 * a->n];
|
||||
pr[r1 + c1 * a->n] = tr;
|
||||
}
|
||||
|
||||
if((a->type & DAT_MASK) == DAT_COMPLEX)
|
||||
{
|
||||
pc = (complex_t*)(a->dat);
|
||||
RE(tc) = RE(pc[r0 + c0 * a->n]);
|
||||
IM(tc) = IM(pc[r0 + c0 * a->n]);
|
||||
|
||||
RE(pc[r0 + c0 * a->n]) = RE(pc[r1 + c1 * a->n]);
|
||||
IM(pc[r0 + c0 * a->n]) = IM(pc[r1 + c1 * a->n]);
|
||||
|
||||
RE(pc[r1 + c1 * a->n]) = RE(tc);
|
||||
IM(pc[r1 + c1 * a->n]) = IM(tc);
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
matrix swap 2 rows
|
||||
*******************************************************************************/
|
||||
int DSPL_API matrix_swap_rows(matrix_t* a, int r0, int r1)
|
||||
{
|
||||
int c, err;
|
||||
if(!a)
|
||||
return ERROR_PTR;
|
||||
if(r0 >= a->n || r1 >= a->n)
|
||||
return ERROR_MATRIX_INDEX;
|
||||
|
||||
for(c = 0; c < a->m; c++)
|
||||
{
|
||||
err = matrix_swap(a, r0, c, r1, c);
|
||||
if(err != RES_OK)
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ p_fft_shift fft_shift ;
|
|||
p_fft_shift_cmplx fft_shift_cmplx ;
|
||||
p_filter_iir filter_iir ;
|
||||
p_filter_zp2ab filter_zp2ab ;
|
||||
p_find_max_abs find_max_abs ;
|
||||
p_fir_linphase fir_linphase ;
|
||||
p_flipip flipip ;
|
||||
p_flipip_cmplx flipip_cmplx ;
|
||||
|
@ -104,8 +105,11 @@ p_low2bp low2bp ;
|
|||
p_low2high low2high ;
|
||||
p_low2low low2low ;
|
||||
p_matrix_create matrix_create ;
|
||||
p_matrix_create_eye matrix_create_eye ;
|
||||
p_matrix_free matrix_free ;
|
||||
p_matrix_print matrix_print ;
|
||||
p_matrix_swap matrix_swap ;
|
||||
p_matrix_swap_rows matrix_swap_rows ;
|
||||
p_matrix_transpose matrix_transpose ;
|
||||
p_matrix_transpose_hermite matrix_transpose_hermite ;
|
||||
p_poly_z2a_cmplx poly_z2a_cmplx ;
|
||||
|
@ -234,6 +238,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(fft_shift_cmplx);
|
||||
LOAD_FUNC(filter_iir);
|
||||
LOAD_FUNC(filter_zp2ab);
|
||||
LOAD_FUNC(find_max_abs);
|
||||
LOAD_FUNC(fir_linphase);
|
||||
LOAD_FUNC(flipip);
|
||||
LOAD_FUNC(flipip_cmplx);
|
||||
|
@ -255,8 +260,11 @@ void* dspl_load()
|
|||
LOAD_FUNC(low2high);
|
||||
LOAD_FUNC(low2low);
|
||||
LOAD_FUNC(matrix_create);
|
||||
LOAD_FUNC(matrix_create_eye);
|
||||
LOAD_FUNC(matrix_free);
|
||||
LOAD_FUNC(matrix_print);
|
||||
LOAD_FUNC(matrix_swap);
|
||||
LOAD_FUNC(matrix_swap_rows);
|
||||
LOAD_FUNC(matrix_transpose);
|
||||
LOAD_FUNC(matrix_transpose_hermite);
|
||||
LOAD_FUNC(poly_z2a_cmplx);
|
||||
|
|
|
@ -111,7 +111,9 @@ typedef struct
|
|||
/* K 0x11xxxxxx*/
|
||||
/* L 0x12xxxxxx*/
|
||||
/* M 0x13xxxxxx*/
|
||||
#define ERROR_MATRIX_SIZE 0x13011909
|
||||
#define ERROR_MATRIX_INDEX 0x13010914
|
||||
#define ERROR_MATRIX_SINGULAR 0x13011914
|
||||
#define ERROR_MATRIX_SIZE 0x13011926
|
||||
/* N 0x14xxxxxx*/
|
||||
#define ERROR_NEGATIVE 0x14050701
|
||||
/* O 0x15xxxxxx*/
|
||||
|
@ -472,6 +474,11 @@ DECLARE_FUNC(int, filter_zp2ab, complex_t*
|
|||
COMMA double*
|
||||
COMMA double*);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, find_max_abs, double* a
|
||||
COMMA int n
|
||||
COMMA double* m
|
||||
COMMA int* ind);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, fir_linphase, int ord
|
||||
COMMA double w0
|
||||
COMMA double w1
|
||||
|
@ -613,14 +620,32 @@ DECLARE_FUNC(int, matrix_create, matrix_t* a
|
|||
COMMA int n
|
||||
COMMA int m
|
||||
COMMA int type);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_create_eye, matrix_t* a
|
||||
COMMA int n
|
||||
COMMA int type);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(void, matrix_free, matrix_t* a);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_lu, matrix_t* a
|
||||
COMMA matrix_t* L
|
||||
COMMA matrix_t* U
|
||||
COMMA matrix_t* P);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_print, matrix_t* a
|
||||
COMMA const char* name
|
||||
COMMA const char* format);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_swap, matrix_t* a
|
||||
COMMA int r0
|
||||
COMMA int c0
|
||||
COMMA int r1
|
||||
COMMA int c1);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_swap_rows, matrix_t* a
|
||||
COMMA int r0
|
||||
COMMA int r1);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_transpose, matrix_t* a
|
||||
COMMA matrix_t* b);
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -83,6 +83,7 @@ p_fft_shift fft_shift ;
|
|||
p_fft_shift_cmplx fft_shift_cmplx ;
|
||||
p_filter_iir filter_iir ;
|
||||
p_filter_zp2ab filter_zp2ab ;
|
||||
p_find_max_abs find_max_abs ;
|
||||
p_fir_linphase fir_linphase ;
|
||||
p_flipip flipip ;
|
||||
p_flipip_cmplx flipip_cmplx ;
|
||||
|
@ -104,8 +105,11 @@ p_low2bp low2bp ;
|
|||
p_low2high low2high ;
|
||||
p_low2low low2low ;
|
||||
p_matrix_create matrix_create ;
|
||||
p_matrix_create_eye matrix_create_eye ;
|
||||
p_matrix_free matrix_free ;
|
||||
p_matrix_print matrix_print ;
|
||||
p_matrix_swap matrix_swap ;
|
||||
p_matrix_swap_rows matrix_swap_rows ;
|
||||
p_matrix_transpose matrix_transpose ;
|
||||
p_matrix_transpose_hermite matrix_transpose_hermite ;
|
||||
p_poly_z2a_cmplx poly_z2a_cmplx ;
|
||||
|
@ -234,6 +238,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(fft_shift_cmplx);
|
||||
LOAD_FUNC(filter_iir);
|
||||
LOAD_FUNC(filter_zp2ab);
|
||||
LOAD_FUNC(find_max_abs);
|
||||
LOAD_FUNC(fir_linphase);
|
||||
LOAD_FUNC(flipip);
|
||||
LOAD_FUNC(flipip_cmplx);
|
||||
|
@ -255,8 +260,11 @@ void* dspl_load()
|
|||
LOAD_FUNC(low2high);
|
||||
LOAD_FUNC(low2low);
|
||||
LOAD_FUNC(matrix_create);
|
||||
LOAD_FUNC(matrix_create_eye);
|
||||
LOAD_FUNC(matrix_free);
|
||||
LOAD_FUNC(matrix_print);
|
||||
LOAD_FUNC(matrix_swap);
|
||||
LOAD_FUNC(matrix_swap_rows);
|
||||
LOAD_FUNC(matrix_transpose);
|
||||
LOAD_FUNC(matrix_transpose_hermite);
|
||||
LOAD_FUNC(poly_z2a_cmplx);
|
||||
|
|
|
@ -111,7 +111,9 @@ typedef struct
|
|||
/* K 0x11xxxxxx*/
|
||||
/* L 0x12xxxxxx*/
|
||||
/* M 0x13xxxxxx*/
|
||||
#define ERROR_MATRIX_SIZE 0x13011909
|
||||
#define ERROR_MATRIX_INDEX 0x13010914
|
||||
#define ERROR_MATRIX_SINGULAR 0x13011914
|
||||
#define ERROR_MATRIX_SIZE 0x13011926
|
||||
/* N 0x14xxxxxx*/
|
||||
#define ERROR_NEGATIVE 0x14050701
|
||||
/* O 0x15xxxxxx*/
|
||||
|
@ -472,6 +474,11 @@ DECLARE_FUNC(int, filter_zp2ab, complex_t*
|
|||
COMMA double*
|
||||
COMMA double*);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, find_max_abs, double* a
|
||||
COMMA int n
|
||||
COMMA double* m
|
||||
COMMA int* ind);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, fir_linphase, int ord
|
||||
COMMA double w0
|
||||
COMMA double w1
|
||||
|
@ -613,14 +620,32 @@ DECLARE_FUNC(int, matrix_create, matrix_t* a
|
|||
COMMA int n
|
||||
COMMA int m
|
||||
COMMA int type);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_create_eye, matrix_t* a
|
||||
COMMA int n
|
||||
COMMA int type);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(void, matrix_free, matrix_t* a);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_lu, matrix_t* a
|
||||
COMMA matrix_t* L
|
||||
COMMA matrix_t* U
|
||||
COMMA matrix_t* P);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_print, matrix_t* a
|
||||
COMMA const char* name
|
||||
COMMA const char* format);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_swap, matrix_t* a
|
||||
COMMA int r0
|
||||
COMMA int c0
|
||||
COMMA int r1
|
||||
COMMA int c1);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_swap_rows, matrix_t* a
|
||||
COMMA int r0
|
||||
COMMA int r1);
|
||||
//------------------------------------------------------------------------------
|
||||
DECLARE_FUNC(int, matrix_transpose, matrix_t* a
|
||||
COMMA matrix_t* b);
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
Ładowanie…
Reference in New Issue