60 const MatrixXd& matGain,
61 const MatrixXd& matData,
66 const int nChannels =
static_cast<int>(matGain.rows());
67 const int nSources =
static_cast<int>(matGain.cols());
68 const int nTimes =
static_cast<int>(matData.cols());
71 MatrixXd matGtG = matGain.transpose() * matGain;
72 MatrixXd matGtM = matGain.transpose() * matData;
75 VectorXd vecWeights = VectorXd::Ones(nSources);
76 VectorXd vecWeightsOld = vecWeights;
79 std::vector<int> activeIdx(nSources);
80 std::iota(activeIdx.begin(), activeIdx.end(), 0);
83 MatrixXd matX = MatrixXd::Zero(nSources, nTimes);
85 int actualIterations = 0;
87 for (
int iter = 0; iter < nIterations; ++iter) {
88 actualIterations = iter + 1;
90 const int nActive =
static_cast<int>(activeIdx.size());
95 MatrixXd matGtG_active(nActive, nActive);
96 MatrixXd matGtM_active(nActive, nTimes);
98 for (
int i = 0; i < nActive; ++i) {
99 matGtM_active.row(i) = matGtM.row(activeIdx[i]);
100 for (
int j = 0; j < nActive; ++j) {
101 matGtG_active(i,j) = matGtG(activeIdx[i], activeIdx[j]);
106 VectorXd vecWdiag(nActive);
107 for (
int i = 0; i < nActive; ++i) {
108 double w = vecWeights(activeIdx[i]);
109 vecWdiag(i) = 1.0 / (w * w);
113 MatrixXd matLhs = matGtG_active;
114 matLhs.diagonal() += alpha * vecWdiag;
116 MatrixXd matX_active = matLhs.ldlt().solve(matGtM_active);
120 for (
int i = 0; i < nActive; ++i) {
121 matX.row(activeIdx[i]) = matX_active.row(i);
125 vecWeightsOld = vecWeights;
126 for (
int i = 0; i < nSources; ++i) {
127 vecWeights(i) = std::max(matX.row(i).norm(), 1e-10);
131 std::vector<int> newActive;
132 newActive.reserve(nActive);
133 for (
int i = 0; i < nSources; ++i) {
134 if (vecWeights(i) >= 1e-8) {
135 newActive.push_back(i);
138 activeIdx = newActive;
141 double maxChange = 0.0;
142 for (
int idx : activeIdx) {
143 maxChange = std::max(maxChange, std::abs(vecWeights(idx) - vecWeightsOld(idx)));
145 if (maxChange < tolerance)
154 QVector<int> finalActive;
155 for (
int i = 0; i < nSources; ++i) {
156 if (matX.row(i).norm() >= 1e-8) {
157 finalActive.append(i);
163 const int nActiveFinal = finalActive.size();
164 MatrixXd matActiveSol(nActiveFinal, nTimes);
165 VectorXi vecActiveVerts(nActiveFinal);
166 for (
int i = 0; i < nActiveFinal; ++i) {
167 matActiveSol.row(i) = matX.row(finalActive[i]);
168 vecActiveVerts(i) = finalActive[i];
175 MatrixXd matResidual = matData - matGain * matX;