我们来模拟一下信号的输入与输出,设定两组信号源,也就是两个人的说话声源信号:
接下来我们来看看放在角落里的两个话筒的声音采样数据,当然这是声音被混合之后的结果:
下面我们来看一下程序的实现代码:
double ica_sigmoid(double s)
{
return 1.0 / (1.0 + pow(M_E, -s));
}
// w_i为行向量,W为参数矩阵
int ica_get_W_i(s_Matrix* w_i, s_Matrix* W, int i)
{
if (w_i == NULL)
{
return -1;
}
if (W == NULL)
{
return -1;
}
//由于w_i为行向量,其只能有一行
if (w_i->m != 1)
{
return -1;
}
for (int j = 0; j < W->n; j++)
{
w_i->v[j] = W->v[i * W->n + j];
}
return 0;
}
// x_i为列向量
int ica_get_x_i(s_Matrix* x_i, s_Sample* sample, int i)
{
if (x_i == NULL)
{
return -1;
}
if (sample == NULL)
{
return -1;
}
if (x_i->n != 1)
{
return -1;
}
for (int j = 0; j < sample->countf; j++)
{
x_i->v[j] = sample->x[i * sample->countf + j];
}
return 0;
}
int ica_split_single(s_Matrix* W, s_Sample* sample)
{
if (W == NULL)
{
return -1;
}
if (sample == NULL)
{
return -1;
}
double alpha = 1e-15;
//行向量
s_Matrix w_i;
matrix_init(&w_i, 1, W->n);
//样本列向量
s_Matrix x_i;
matrix_init(&x_i, W->n, 1);
//样本列向量转置
s_Matrix x_i_T;
matrix_init(&x_i_T, 1, W->n);
s_Matrix w_temp;
matrix_init(&w_temp, W->m, 1);
s_Matrix w_mult;
matrix_init(&w_mult, 1, 1);
s_Matrix w_mult2;
matrix_init(&w_mult2, W->m, W->n);
s_Matrix W_add;
matrix_init(&W_add, W->m, W->n);
s_Matrix W_T;
matrix_init(&W_T, W->m, W->n);
s_Matrix W_T_inv;
matrix_init(&W_T_inv, W->m, W->n);
s_Matrix W_result;
matrix_init(&W_result, W->m, W->n);
for (int t = 0; t < 100; t++)
{
for (int i = 0; i < sample->countx; i++)
{
matrix_transposition(&W_T, W);
matrix_inv(&W_T_inv, &W_T);
//取得当前样本x并转为列向量x_i
ica_get_x_i(&x_i, sample, i);
for (int j = 0; j < W_T.m; j++)
{
ica_get_W_i(&w_i, &W_T, j);
matrix_mult(&w_mult, &w_i, &x_i);
w_temp.v[j] = 1.0 - 2.0 * ica_sigmoid(w_mult.v[0]);
}
matrix_transposition(&x_i_T, &x_i);
matrix_mult(&w_mult2, &w_temp, &x_i_T);
matrix_add(&W_add, &w_mult2, &W_T_inv);
matrix_mult_num_self(&W_add, alpha);
matrix_add(&W_result, W, &W_add);
matrix_copy(W, &W_result);
matrix_display(W);
printf("\n");
}
}
matrix_destory(&w_i);
matrix_destory(&x_i);
matrix_destory(&x_i_T);
matrix_destory(&w_temp);
matrix_destory(&w_mult);
matrix_destory(&w_mult2);
matrix_destory(&W_add);
matrix_destory(&W_T);
matrix_destory(&W_T_inv);
matrix_destory(&W_result);
return 0;
}
最后我们再来看看通过独立成分分析分离出的两个原始信号源:
Copyright © 2015-2023 问渠网 辽ICP备15013245号