virtual float predict(const record & rcd) const{
		unsigned int i = rcd.user - 1, j = rcd.movie - 1;
		double result = as_scalar(U.col(i).t() * V.col(j)) + A(i) + B(j) + mu;
		return result;
	}
예제 #2
0
mat nnls_solver_with_missing(const mat & A, const mat & W, const mat & W1, const mat & H2, const umat & mask, 
	const double & eta, const double & beta, int max_iter, double rel_tol, int n_threads)
{
	// A = [W, W1, W2] [H, H1, H2]^T.
	// Where A may have missing values
	// Note that here in the input W = [W, W2]
	// compute x = [H, H1]^T given W, W2
	// A0 = W2*H2 is empty when H2 is empty (no partial info in H)
	// Return: x = [H, H1]

	int n = A.n_rows, m = A.n_cols;
	int k = W.n_cols - H2.n_cols;
	int kW = W1.n_cols;
	int nH = k+kW;

	mat x(nH, m, fill::zeros);

	if (n_threads < 0) n_threads = 0;
	bool is_masked = !mask.empty();

	#pragma omp parallel for num_threads(n_threads) schedule(dynamic)
	for (int j = 0; j < m; j++)
	{
		// break if all entries of col_j are masked
		if (is_masked && arma::all(mask.col(j))) 
			continue;
		
		uvec non_missing = find_finite(A.col(j));
		mat WtW(nH, nH); // WtW
		update_WtW(WtW, W.rows(non_missing), W1.rows(non_missing), H2);
		if (beta > 0) WtW += beta;
		if (eta > 0) WtW.diag() += eta;

		mat mu(nH, 1); // -WtA
		uvec jv(1);
		jv(0) = j;
		//non_missing.t().print("non_missing = ");
		//std::cout << "1.1" << std::endl;
		if (H2.empty())
			update_WtA(mu, W.rows(non_missing), W1.rows(non_missing), H2, A.submat(non_missing, jv));
		else
			update_WtA(mu, W.rows(non_missing), W1.rows(non_missing), H2.rows(j, j), A.submat(non_missing, jv));
		//std::cout << "1.5" << std::endl;

		vec x0(nH);
		double tmp;
		int i = 0;
		double err1, err2 = 9999;
		do {
			x0 = x.col(j);
			err1 = err2;
			err2 = 0;
			for (int l = 0; l < nH; l++)
			{
				if (is_masked && mask(l,j) > 0) continue;
				tmp = x(l,j) - mu(l,0) / WtW(l,l);
				if (tmp < 0) tmp = 0;
				if (tmp != x(l,j))
				{
					mu.col(0) += (tmp - x(l,j)) * WtW.col(l);
				}
				x(l,j) = tmp;
				tmp = std::abs(x(l,j) - x0(l));
				if (tmp > err2) err2 = tmp;
			}
		} while(++i < max_iter && std::abs(err1 - err2) / (err1 + 1e-9) > rel_tol);
	}
	return x;
}
mat compute_hessian_theta1_delta_weighted(uint i, mat station_data, uint wdclat1_col, uint wdclon1_col,
    double pointslat1_i, double pointslon1_i, double beta1, double sigma0, colvec xdeltain, 
    uvec st_point_list_uvec, rowvec deltain_row, urowvec mat_st_state_row, 
    NumericVector xv0_vec, uint focal_station_index, uint xtheta1_size,
    double point_density_i, rowvec points_den_covariates) {
  
          rowvec station_data_dis_vIdx = conv_to< rowvec >::from(latlondistance(station_data.col(wdclat1_col), 
            station_data.col(wdclon1_col), pointslat1_i, pointslon1_i));                    
          
          rowvec util = exp(beta1*station_data_dis_vIdx + deltain_row)% (mat_st_state_row==0);
          double den_util = sum(util);
          uint no_t_st = util.size();          
          //rowvec lambda_st_t(no_t_st,fill::zeros);
          mat hessian_beta1_delta_t(1,no_t_st,fill::zeros);
          mat hessian_theta1_delta_t(xtheta1_size,no_t_st,fill::zeros);
          rowvec grad_delta(no_t_st,fill::zeros);

          uvec no_focal_indexes(no_t_st,fill::zeros);
          
          //fill  no_focal_indexes with index sequence
          //find more efficient way to do this
          for(uint m=0; m<no_focal_indexes.size(); ++m) {
            no_focal_indexes(m)=m;
          }
          no_focal_indexes.shed_row(focal_station_index);

          for(int m=0; m<xv0_vec.size(); ++m) {
              double out = exp(-xv0_vec(m)*sigma0);
              double denutil_t = den_util+out;        
              
              rowvec util_prob_t =  util/denutil_t;

              rowvec disP = util_prob_t%station_data_dis_vIdx;
              double disP_sum = sum( disP);
              // rowvec disP_sum_vec(no_t_st);
              // disP_sum_vec.fill(disP_sum);

              vec val1(no_t_st,fill::zeros);
              val1 = station_data_dis_vIdx 
              val1 += station_data_dis_vIdx(focal_station_index) - 2*disP_sum_vec;
              val1 = val1 % util_prob_t;
              val1 *= -util_prob_t(focal_station_index);
              //remove focal_station_index from val1 as it is incorrect.
              val1.shed_row(focal_station_index);

              hessian_beta1_delta_t(0,no_focal_indexes) += val1;
              hessian_beta1_delta_t(0,focal_station_index) += util_prob_t(focal_station_index) * (1-2*util_prob_t(focal_station_index))\
                (station_data_dis_vIdx(focal_station_index)-disP_sum);

              grad_delta -= util_prob_t(focal_station_index)*util_prob_t;
              grad_delta(focal_station_index) += util_prob_t(focal_station_index);
          }
          grad_delta *= (1/xv0_vec.size());
          hessian_beta1_delta_t *= (1/xv0_vec.size())* point_density_i;
          
          mat hessian_thetaden_delta_t = points_den_covariates.t() * grad_delta;
          assert(hessian_thetaden_delta_t.n_rows==points_den_covariates.size());
          assert(hessian_thetaden_delta_t.n_cols==grad_delta.size());

          hessian_theta1_delta_t.row(0)=hessian_beta1_delta_t;
          hessian_theta1_delta_t.rows(span(2,xtheta1_size-1))=hessian_thetaden_delta_t;

          return((hessian_theta1_delta_t));  
}