double vec_cos(int dim, double *x, double *y) { double prod, length_x, length_y; /* 内積を計算 */ prod = innerprod(dim, x, y); /* ベクトルのL2ノルムを計算する */ length_x = get_vec_lp_norm(dim, x, 2); length_y = get_vec_lp_norm(dim, y, 2); return prod / (length_x * length_y); }
/* 多変量正規分布 N(Μ,Σ)の X に対する値を計算する。 単変量の正規分布は上の関数を使うこと。 */ double get_multi_norm(double *mean, double **covmat, double *X, int dim) { double *tmp1 = NULL, *tmp2 = NULL; double det, **invmat = NULL; double val; tmp1 = del_vec(X, mean, dim); tmp2 = tmp1; invmat = matinv(dim, covmat, &det); tmp1 = vecxmat(tmp1, dim, invmat, dim, dim); val = dvid(safe_exp(-0.5 * innerprod(dim, tmp1, tmp2)), (pow(2.0 * M_PI, dim / 2.0) * sqrt(det))); free_double_matrix(invmat); free_double_vector(tmp1); free_double_vector(tmp2); return val; }
double norm(const Vector& v) { return sqrt(innerprod(v, v)); }
void P_nominal(vector<double> &P, const vector<double> &par, const NumericMatrix &Theta, const NumericVector &ot, const int &N, const int &nfact, const int &ncat, const int &returnNum, const int &israting) { vector<double> a(nfact), ak(ncat), d(ncat); for(int i = 0; i < nfact; ++i) a[i] = par[i]; for(int i = 0; i < ncat; ++i){ ak[i] = par[i + nfact]; if(israting){ if(i) d[i] = par[i + nfact + ncat] + par[par.size()-1]; } else { d[i] = par[i + nfact + ncat]; } } const int USEOT = ot.size() > 1; NumericMatrix Num(N, ncat); vector<double> z(ncat); vector<double> Den(N, 0.0); vector<double> innerprod(N, 0.0); for(int i = 0; i < N; ++i) for(int j = 0; j < nfact; ++j) innerprod[i] += Theta(i,j) * a[j]; if(USEOT){ for(int i = 0; i < N; ++i){ for(int j = 0; j < ncat; ++j) z[j] = ak[j] * innerprod[i] + d[j] + ot[j]; double maxz = *std::max_element(z.begin(), z.end()); for(int j = 0; j < ncat; ++j){ z[j] = z[j] - maxz; if(z[j] < -ABS_MAX_Z) z[j] = -ABS_MAX_Z; Num(i,j) = exp(z[j]); Den[i] += Num(i,j); } } } else { for(int i = 0; i < N; ++i){ for(int j = 0; j < ncat; ++j) z[j] = ak[j] * innerprod[i] + d[j]; double maxz = *std::max_element(z.begin(), z.end()); for(int j = 0; j < ncat; ++j){ z[j] = z[j] - maxz; if(z[j] < -ABS_MAX_Z) z[j] = -ABS_MAX_Z; Num(i,j) = exp(z[j]); Den[i] += Num(i,j); } } } int which = 0; if(returnNum){ for(int j = 0; j < ncat; ++j){ for(int i = 0; i < N; ++i){ P[which] = Num(i,j); ++which; } } } else { for(int j = 0; j < ncat; ++j){ for(int i = 0; i < N; ++i){ P[which] = Num(i,j) / Den[i]; ++which; } } } }