/* Substraction. Throw exception if their dimensions don't match. */ Mat operator -(const Mat& rhs){ if (rhs.get_n()!=n || rhs.get_m()!=m){ throw invalid_argument("Matrix dimensions are not consistent when trying '+' two matrices"); return Mat(); } Mat res = Mat(*this); for (int i=0; i<res.get_n(); i++){ for (int j=0; j<res.get_m(); j++) res[i][j] -= rhs.get(i, j); } return res; }
/* Objective function value calculator: Takes Doc feature matrix and Word feature matrix, as well as ground truth counts, return objective function value and a vector of error value for each case. The objective function is F = acc_error + doc_reg + word_reg = sum_{(doc_id, word_id, cnt):train_vec} (cnt - D(doc_id)*W(word_id))^2 + 0.5*lambda*(|D|^2 + |W|^2) */ double CalcObj(const Mat &D, const Mat &W, const vector<Triplet> &train_vec, const int &begin_idx, const int &end_idx, const double &lambda, const double &mean_cnt, Mat &error, Mat &pred_out){ double acc_error = 0.0, doc_reg = 0.0, word_reg = 0.0; error = Mat(end_idx-begin_idx+1, 1, 0); pred_out = Mat(end_idx-begin_idx+1, 1, 0); for (int i = begin_idx; i <= end_idx; i++){ int doc_id = train_vec[i].doc_id, word_id = train_vec[i].word_id; double cnt = train_vec[i].cnt; // calculate the prediction: inner product of D(doc_id), W(word_id) double predict = 0.0; for (int j=0; j < D.get_m(); j++){ double dd = D.get(doc_id, j), ww = W.get(word_id, j); predict += (dd*ww); doc_reg += sqr(dd); word_reg += sqr(ww); } pred_out[i-begin_idx][0] = predict + mean_cnt; error[i - begin_idx ][0] = pred_out[i-begin_idx][0] - train_vec[i].cnt; // calculate the error between predict and ground truth cnt acc_error += sqr(pred_out[i-begin_idx][0] - train_vec[i].cnt); } // Objective function value double F = acc_error + 0.5*lambda*(doc_reg + word_reg); return F; }
/* Return a matrix which is the elementwise square. */ Mat Sqr(){ Mat res = Mat(*this); for (int i=0; i<res.get_n(); i++) for (int j=0; j<res.get_m(); j++) res[i][j] = res[i][j]*res[i][j]; return res; }
/* Multiply by a number. */ Mat operator *(const double& mult){ Mat res = Mat(*this); for (int i=0; i<res.get_n(); i++){ for (int j=0; j<res.get_m(); j++) res[i][j] *= mult; } return res; }
/* Copy constructor. Deep copy. */ Mat(const Mat &cp){ InitMat(cp.get_n(),cp.get_m()); for (int i=0; i<n; i++) for (int j=0; j<m; j++) arr[i][j] = cp.get(i,j); }