/*** * @Date: 2020-09-12 19:01:56 * @Author: Qing Shuai * @LastEditors: Qing Shuai * @LastEditTime: 2022-07-29 22:38:40 * @FilePath: /EasyMocapPublic/library/pymatch/include/matchSVT.hpp */ #pragma once #include "base.h" #include "projfunc.hpp" #include "Timer.hpp" #include "visualize.hpp" namespace match { struct Config { bool debug; int max_iter; float tol; float w_rank; float w_sparse; Config(Control& control){ debug = (control["debug"] > 0.); max_iter = int(control["maxIter"]); tol = control["tol"]; w_rank = control["w_rank"]; w_sparse = control["w_sparse"]; } }; // dimGroups: [0, nF1, nF1 + nF2, ...] ListList getBlocksFromDimGroups(const List& dimGroups){ ListList block; for(int i=0;i 0.); int max_iter = int(control["maxIter"]); float tol = control["tol"]; int N = M_aff.rows(); auto dual_blocks = getBlocksFromDimGroups(dimGroups); // 对角线约束 for(int i=0;i 0.7 && block[1] > 1 && block[3] > 1){ // 如果大于0.9,说明区分度不够高啊,认为观测是虚假的 M_obs.block(block[0], block[2], block[1], block[3]).setZero(); } } // set the diag of M_aff to zeros M_aff.diagonal().setConstant(0); Mat X = M_aff; Mat Y = Mat::Zero(N, N); Mat Q = M_aff; Mat W = (control["w_sparse"] - M_aff.array()).matrix(); float mu = 64; Timer timer; timer.tic(); for (int iter = 0; iter < max_iter; iter++) { Mat X0 = X; // update Q with SVT Q = 1.0 / mu * Y + X; Eigen::BDCSVD UDV(Q.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV)); Array Ds(Dsoft(UDV.singularValues(), control["w_rank"] / mu)); Mat Qnew(UDV.matrixU() * Ds.matrix().asDiagonal() * UDV.matrixV().adjoint()); Q = Qnew; // update X X = Q - (M_obs.array() * W.array() + Y.array()).matrix() / mu; X = (X.array() * M_constr.array()).matrix(); // set the diagonal X.diagonal().setOnes(); // 注意这个min,max X = X.cwiseMin(1.f).cwiseMax(0.f); #pragma omp parallel for for(int i=0;i + alpha||x||_* + beta||x||_1, st. X \in C // + alpha/2||A||^2 + alpha/2||B||^2 // st AB^T = Z, Z\in \Omega const Config cfg(control); Mat W = (M_aff + M_aff.transpose())/2; // set the diag of W to zeros for(int i=0;i maxRank){ maxRank = dimGroups[i+1]-dimGroups[i]; } } std::cout << "[matchALS] set the max rank = " << maxRank << std::endl; Mat eyeRank = Mat::Identity(maxRank, maxRank); // initial value Mat A = Mat::Random(n, maxRank); Mat B; for(int iter=0;iter