17 using namespace Eigen;
26 const malsar_options& options)
33 int n_tasks = options.n_tasks;
39 MatrixXd Ws = MatrixXd::Zero(n_feats, n_tasks);
40 VectorXd Cs = VectorXd::Zero(n_tasks);
41 MatrixXd Wz=Ws, Wzp=Ws, Wz_old=Ws, delta_Wzp=Ws, gWs=Ws;
42 VectorXd Cz=Cs, Czp=Cs, Cz_old=Cs, delta_Czp=Cs, gCs=Cs;
45 double gamma=1, gamma_inc=2;
46 double obj=0.0, obj_old=0.0;
52 while (!done && iter <= options.max_iter)
54 double alpha = double(t_old - 1)/t;
57 Ws = (1+alpha)*Wz - alpha*Wz_old;
58 Cs = (1+alpha)*Cz - alpha*Cz_old;
66 for (task=0; task<n_tasks; task++)
69 int n_task_vecs = task_idx.
vlen;
70 for (
int i=0; i<n_task_vecs; i++)
72 double aa = -y[task_idx[i]]*(features->
dense_dot(task_idx[i], Ws.col(task).data(), n_feats)+Cs[task]);
76 Fs += (CMath::log(CMath::exp(-bb) + CMath::exp(aa-bb)) + bb)/n_task_vecs;
77 double b = -y[task_idx[i]]*(1 - 1/(1+CMath::exp(aa)))/n_task_vecs;
83 gWs.noalias() += 2*rho_L2*Ws;
87 Fs += rho_L2*Ws.squaredNorm();
93 while (inner_iter <= 1000)
98 JacobiSVD<MatrixXd> svd((Ws - gWs/gamma).transpose(),ComputeThinU | ComputeThinV);
99 for (
int i=0; i<svd.singularValues().size(); i++)
101 if (svd.singularValues()[i] > rho/gamma)
102 Wzp += (svd.matrixU().col(i)*
103 svd.singularValues()[i]*
104 svd.matrixV().col(i).transpose()).transpose();
108 Czp = Cs - gCs/gamma;
112 for (task=0; task<n_tasks; task++)
115 int n_task_vecs = task_idx.
vlen;
116 for (
int i=0; i<n_task_vecs; i++)
118 double aa = -y[task_idx[i]]*(features->
dense_dot(task_idx[i], Wzp.col(task).
data(), n_feats)+Czp[task]);
121 Fzp += (CMath::log(CMath::exp(-bb) + CMath::exp(aa-bb)) + bb)/n_task_vecs;
124 Fzp += rho_L2*Wzp.squaredNorm();
127 delta_Wzp = Wzp - Ws;
128 delta_Czp = Czp - Cs;
131 double nrm_delta_Wzp = delta_Wzp.squaredNorm();
132 double nrm_delta_Czp = delta_Czp.squaredNorm();
134 double r_sum = (nrm_delta_Wzp + nrm_delta_Czp)/2;
136 double Fzp_gamma = Fs + (delta_Wzp.transpose()*gWs).trace() +
137 (delta_Czp.transpose()*gCs).trace() +
138 (gamma/2)*nrm_delta_Wzp +
139 (gamma/2)*nrm_delta_Czp;
149 if (Fzp <= Fzp_gamma)
164 JacobiSVD<MatrixXd> svd(Wzp, EigenvaluesOnly);
165 obj += rho*svd.singularValues().sum();
170 switch (options.termination)
175 if ( CMath::abs(obj-obj_old) <= options.tolerance )
182 if ( CMath::abs(obj-obj_old) <= options.tolerance*CMath::abs(obj_old))
187 if (CMath::abs(obj) <= options.tolerance)
191 if (iter>=options.max_iter)
198 t = 0.5 * (1 + CMath::sqrt(1.0 + 4*t*t));
201 SG_SDEBUG(
"%d iteration passed, objective = %f\n",iter,obj)
204 for (
int i=0; i<n_feats; i++)
206 for (task=0; task<n_tasks; task++)
207 tasks_w(i,task) = Wzp(i,task);
210 for (
int i=0; i<n_tasks; i++) tasks_c[i] = Czp[i];
211 return malsar_result_t(tasks_w, tasks_c);
virtual float64_t dense_dot(int32_t vec_idx1, const float64_t *vec2, int32_t vec2_len)=0
virtual int32_t get_num_vectors() const =0
virtual void add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t *vec2, int32_t vec2_len, bool abs_val=false)=0
Features that support dot products among other operations.
virtual int32_t get_dim_feature_space() const =0
malsar_result_t malsar_low_rank(CDotFeatures *features, double *y, double rho, const malsar_options &options)
all of classes and functions are contained in the shogun namespace
Matrix::Scalar max(Matrix m)