46 const MatrixXd& matGain,
47 const MatrixXd& matData,
52 const int nChannels =
static_cast<int>(matGain.rows());
53 const int nSources =
static_cast<int>(matGain.cols());
54 const int nTimes =
static_cast<int>(matData.cols());
57 MatrixXd matGtG = matGain.transpose() * matGain;
58 MatrixXd matGtM = matGain.transpose() * matData;
61 VectorXd vecWeights = VectorXd::Ones(nSources);
62 VectorXd vecWeightsOld = vecWeights;
65 std::vector<int> activeIdx(nSources);
66 std::iota(activeIdx.begin(), activeIdx.end(), 0);
69 MatrixXd matX = MatrixXd::Zero(nSources, nTimes);
71 int actualIterations = 0;
73 for (
int iter = 0; iter < nIterations; ++iter) {
74 actualIterations = iter + 1;
76 const int nActive =
static_cast<int>(activeIdx.size());
81 MatrixXd matGtG_active(nActive, nActive);
82 MatrixXd matGtM_active(nActive, nTimes);
84 for (
int i = 0; i < nActive; ++i) {
85 matGtM_active.row(i) = matGtM.row(activeIdx[i]);
86 for (
int j = 0; j < nActive; ++j) {
87 matGtG_active(i,j) = matGtG(activeIdx[i], activeIdx[j]);
92 VectorXd vecWdiag(nActive);
93 for (
int i = 0; i < nActive; ++i) {
94 double w = vecWeights(activeIdx[i]);
95 vecWdiag(i) = 1.0 / (w * w);
99 MatrixXd matLhs = matGtG_active;
100 matLhs.diagonal() += alpha * vecWdiag;
102 MatrixXd matX_active = matLhs.ldlt().solve(matGtM_active);
106 for (
int i = 0; i < nActive; ++i) {
107 matX.row(activeIdx[i]) = matX_active.row(i);
111 vecWeightsOld = vecWeights;
112 for (
int i = 0; i < nSources; ++i) {
113 vecWeights(i) = std::max(matX.row(i).norm(), 1e-10);
117 std::vector<int> newActive;
118 newActive.reserve(nActive);
119 for (
int i = 0; i < nSources; ++i) {
120 if (vecWeights(i) >= 1e-8) {
121 newActive.push_back(i);
124 activeIdx = newActive;
127 double maxChange = 0.0;
128 for (
int idx : activeIdx) {
129 maxChange = std::max(maxChange, std::abs(vecWeights(idx) - vecWeightsOld(idx)));
131 if (maxChange < tolerance)
140 QVector<int> finalActive;
141 for (
int i = 0; i < nSources; ++i) {
142 if (matX.row(i).norm() >= 1e-8) {
143 finalActive.append(i);
149 const int nActiveFinal = finalActive.size();
150 MatrixXd matActiveSol(nActiveFinal, nTimes);
151 VectorXi vecActiveVerts(nActiveFinal);
152 for (
int i = 0; i < nActiveFinal; ++i) {
153 matActiveSol.row(i) = matX.row(finalActive[i]);
154 vecActiveVerts(i) = finalActive[i];
161 MatrixXd matResidual = matData - matGain * matX;