int mat_rank(int dim, double **mat) { int i, j; int count = 0; double *dr = NULL, *di = NULL; double **tmp; dr = new_double_vector(dim); di = new_double_vector(dim); tmp = new_double_matrix(dim, dim); /* 計算途中で値が上書きされるから元の行列のコピーを使う */ for(i = 0; i < dim; i++) for(j = 0; j < dim; j++) tmp[i][j] = mat[i][j]; /* 固有値の計算 */ hes(tmp, dim); hqr(tmp, dr, di, dim); /* 固有値を調べる */ /* drが実数成分、diが虚数成分 */ for(i = 0; i < dim; i++) if(dr[i] > 0.0 && (!(di[i] > 0.0 || di[i] < 0.0))) count++; /* 配列を解放 */ free_double_vector(dr); free_double_vector(di); free_double_matrix(tmp); return count; }
/* 多変量正規分布 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; }
/* * free rfprof structure */ void rfprof_free(double ** obj) { int i, N; N = rfprof_len(obj); for (i=1; i<=N; i++) { free_double_vector(obj[i]); } free(obj[0]); free(obj); }
void Test_approximate_block_solver(CuTest *tc) { double_vector *p = alloc_double_vector(2); p->values[0] = 0.5; p->values[1] = 1.0; double_matrix *A = alloc_double_matrix(3, 2); A->values[0 * 2 + 0] = 1.0; A->values[1 * 2 + 0] = 2.0; A->values[2 * 2 + 0] = 3.0; A->values[0 * 2 + 1] = 2.0; A->values[1 * 2 + 1] = 2.0; A->values[2 * 2 + 1] = 3.0; double_vector *opt = approximate_block_solver(A, p, 5, 0.001); CuAssertDblEquals(tc, 0.0, opt->values[0], 0.01); CuAssertDblEquals(tc, 0.0, opt->values[1], 0.01); CuAssertDblEquals(tc, 5.0, opt->values[2], 0.01); free_double_vector(p); free_double_matrix(A); free_double_vector(opt); }
void free_param(Spec *spc, Data *dat, KNN *knn) { /* 配列の解放 */ free_int_vector(spc->tr_sample); free_int_vector(spc->te_sample); free_double_matrix(dat->x_tr); free_double_matrix(dat->x_te); free_int_vector(dat->label_tr); free_int_vector(dat->label_te); free_double_vector(knn->dist_queue); free_int_vector(knn->index); free_int_matrix(knn->count); }
int main(int argc, char **argv) { int i; int dim, line; int dflag = 0; double extract; int *index, *fi; double *item, max; FILE *fp; if(argc != 4){ fprintf(stderr, "\n[使用法] : detect_fi <file> [-d (num) / -r (ratio)]\n"); exit(1); } /* 取り出す要素数の方法を引数から確認 */ if(is_opt(argc, argv, "-d")){ dflag = 1; extract = get_double_arg(argc, argv, "-d"); } else if(is_opt(argc, argv, "-r")) extract = get_double_arg(argc, argv, "-r"); else{ fprintf(stderr, "\n[エラー] : 不明な引数が含まれています\n"); exit(1); } /* データの大きさを調べる */ get_size(argv[1], &dim, &line); /* 準備 */ index = new_int_vector(line); item = new_double_vector(line); /* データを読み込む */ if((fp = fopen(argv[1], "r")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル %s が開けません\n", argv[1]); exit(1); } for(i = 0; i < line; i++) fscanf(fp, "%d %lf", &index[i], &item[i]); fclose(fp); /* 要素数を決定し、結果を出力 */ if(dflag){ dim = (int)extract; fi = new_int_vector(dim); for(i = 0; i < dim; i++) fi[i] = index[i]; if(dim > 1) quicksort(fi, 0, dim - 1); if((fp = fopen("Subset.dat", "w")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル Subset.dat が開けません\n"); exit(1); } for(i = 0; i < dim; i++){ fprintf(fp, "%d", fi[i]); if(i < dim - 1) fprintf(fp, " "); } fprintf(fp, "\n"); fclose(fp); } else{ /* 評価関数の最大値を判定する */ max = item[line - 1]; extract = max * (1.0 - extract / 100.0); for(i = 0; i < line; i++){ if(item[i] - extract > 0.0){ dim = i; break; } } dim++; /* 特徴の番号を合わせる. C言語では0番から始まるけど、特徴は1 番からカウントするのでfor文を抜けた後のdimは特徴数が1だけ 小さい。 */ fi = new_int_vector(dim); for(i = 0; i < dim; i++) fi[i] = index[i]; if(dim > 1) quicksort(fi, 0, dim - 1); if((fp = fopen("Subset.dat", "w")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル Subset.dat が開けません\n"); exit(1); } for(i = 0; i < dim; i++){ fprintf(fp, "%d", fi[i]); if(i < dim - 1) fprintf(fp, " "); } fprintf(fp, "\n"); fclose(fp); } /* 終了処理 */ free_int_vector(index); free_double_vector(item); free_int_vector(fi); exit(0); }
int main(int argc, char **argv) { int i, j; int flag = 0; int num_1, num_2; int dim_1, dim_2; double *vec_1, *vec_2; FILE *fp_1, *fp_2; if(argc < 3){ fprintf(stderr, "\n[エラー] : 引数が足りません\n"); fprintf(stderr, "[使用法] : vecarg <file1> <file2> (-rad)\n"); exit(1); } /* ファイルから次元数とサンプル数を調べる。二つのファイルで一致しなけ れば計算を行わない */ get_size(argv[1], &dim_1, &num_1); get_size(argv[2], &dim_2, &num_2); if(is_opt(argc, argv, "-rad")) flag = 1; if((dim_1 != dim_2) || (num_1 != num_2)){ fprintf(stderr, "\n[エラー] : 次元数、またはサンプル数が一致しません\n"); exit(1); } /* ファイルからデータを一つ読み角度を計算する */ if((fp_1 = fopen(argv[1], "r")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル %s が開けません\n", argv[1]); exit(1); } if((fp_2 = fopen(argv[2], "r")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル %s が開けません\n", argv[2]); exit(2); } vec_1 = new_double_vector(dim_1); vec_2 = new_double_vector(dim_2); for(i = 0; i < num_1; i++){ for(j = 0; j < dim_1; j++) fscanf(fp_1, "%lf", &vec_1[j]); for(j = 0; j < dim_2; j++) fscanf(fp_2, "%lf", &vec_2[j]); /* 角度を計算して値を表示する */ if(flag) fprintf(stdout, "%f\n", vec_arg(dim_1, vec_1, vec_2)); else fprintf(stdout, "%f\n", vec_cos(dim_1, vec_1, vec_2)); } free_double_vector(vec_1); free_double_vector(vec_2); fclose(fp_1); fclose(fp_2); exit(0); }
int main(int argc, char **argv) { int i, j; int flag = 0; int dim, size; double **data; double *mean; double **sigma; double **corr; FILE *fp; if(argc < 2){ fprintf(stderr, "\n[使用法] : corrmat <file> (-s)\n"); exit(1); } /* 出力フラグを調べる */ if(is_opt(argc, argv, "-s")) flag = 1; /* 次元数とサンプル数を調べる */ get_size(argv[1], &dim, &size); data = new_double_matrix(size, dim); /* データを読み込む */ if((fp = fopen(argv[1], "r")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル %s が開けません\n", argv[1]); exit(1); } for(i = 0; i < size; i++) for(j = 0; j < dim; j++) fscanf(fp, "%lf", &data[i][j]); fclose(fp); /* 平均を計算する */ mean = calc_mean(data, size, dim); /* 共分散行列を計算する */ sigma = calc_cov_mat(data, mean, size, dim); /* 相関係数行列を計算する */ corr = calc_corr_mat(sigma, dim); /* 結果を出力 */ if(!flag) printf("Correlation Matrix:\n"); for(i = 0; i < dim; i++){ for(j = 0; j < dim; j++){ printf("%#+.2f", corr[i][j]); if(j < dim - 1) printf(" "); } printf("\n"); fflush(stdout); } /* 終了処理 */ free_double_matrix(data); free_double_vector(mean); free_double_matrix(sigma); free_double_matrix(corr); exit(0); }
void run_viterbi(ModelParams *model_params, Observation *observations, int *state_indices, double *state_probabilities, double *log_prob) { double **log_delta; int **psi; double *log_pi; double **log_a; int i, j; long t; double max_logprob, this_logprob; int max_index, index; double **bprob, **eprob, **alpha, **beta, **gamma, mll; /* Find probabilities by solving for gammas: */ fprintf(stderr, "Starting viterbi\n"); bprob = alloc_double_matrix(model_params->T, model_params->N); eprob = alloc_double_matrix(model_params->T, model_params->N); alpha = alloc_double_matrix(model_params->T, model_params->N); beta = alloc_double_matrix(model_params->T, model_params->N); gamma = alloc_double_matrix(model_params->T, model_params->N); calc_bprobs(model_params, observations, bprob); calc_eprobs(model_params, observations, eprob); calc_alphas(model_params, observations, alpha, bprob, eprob, &mll); calc_betas(model_params, observations, beta, bprob, eprob); calc_gammas(model_params, alpha, beta, gamma); /* Calculate logs of parameters for easier manipulation. */ log_pi = alloc_double_vector(model_params->N); for (i = 0; i < model_params->N; i++) { log_pi[i] = log((model_params->pi)[i]); } log_a = alloc_double_matrix(model_params->N, model_params->N); for (i = 0; i < model_params->N; i++) { for (j = 0; j < model_params->N; j++) { log_a[i][j] = log(model_params->a[i][j]); } } log_delta = alloc_double_matrix(model_params->T, model_params->N); psi = alloc_int_matrix(model_params->T, model_params->N); /* Initialization */ for (i = 0; i < model_params->N; i++) { log_delta[0][i] = log_pi[i] + log(bprob[0][i]) + log(eprob[0][i]); psi[0][i] = 0; } /* Recursion */ for (t = 1; t < model_params->T; t++) { for (i = 0; i < model_params->N; i++) { max_logprob = -99999999.0; for (j = 0; j < model_params->N; j++) { this_logprob = log_delta[t-1][j] + log_a[j][i]; if (this_logprob > max_logprob) { max_logprob = this_logprob; max_index = j; } } log_delta[t][i] = max_logprob + log(bprob[t][i]) + log(eprob[t][i]); psi[t][i] = max_index; } } /* Termination */ *log_prob = -99999999.0; state_indices[model_params->T - 1] = 1; for (i = 0; i < model_params->N; i++) { if (log_delta[model_params->T - 1][i] > *log_prob) { *log_prob = log_delta[model_params->T - 1][i]; state_indices[model_params->T - 1] = i; } } /* Traceback */ for (t = model_params->T - 2; t >= 0; t--) { state_indices[t] = psi[t + 1][state_indices[t + 1]]; } /* free memory */ free_double_vector(log_pi); free_double_matrix(log_a, model_params->N); free_double_matrix(log_delta, model_params->T); free_int_matrix(psi, model_params->N); fprintf(stderr, "Done with viterbi\n"); for (t = 0; t < model_params->T; t++) { index = state_indices[t]; state_probabilities[t] = gamma[t][index]; /* fprintf(stderr, "time %ld probability %lf for state %d\n", t, state_probabilities[t], index); */ } free_double_matrix(eprob, model_params->T); free_double_matrix(alpha, model_params->T); free_double_matrix(beta, model_params->T); free_double_matrix(gamma, model_params->T); }
int main(int argc, char **argv) { int i, j; int flag = 0; int dim, size; double **data; double *mean; double **sigma; FILE *fp; if(argc < 2){ fprintf(stderr, "\n[使用法] : meancov <file> (-s)\n"); exit(1); } /* 出力フラグを調べる */ if(is_opt(argc, argv, "-s")) flag = 1; /* 次元数とサンプル数を調べる */ get_size(argv[1], &dim, &size); data = new_double_matrix(size, dim); /* データを読み込む */ if((fp = fopen(argv[1], "r")) == NULL){ fprintf(stderr, "\n[エラー] : ファイル %s が開けません\n", argv[1]); exit(1); } for(i = 0; i < size; i++) for(j = 0; j < dim; j++) fscanf(fp, "%lf", &data[i][j]); fclose(fp); /* 平均を計算する */ mean = calc_mean(data, size, dim); /* 共分散行列を計算する */ sigma = calc_cov_mat(data, mean, size, dim); /* 結果を出力 */ if(!flag) fprintf(stdout, "Mean :\n"); for(i = 0; i < dim; i++){ fprintf(stdout, "%#+.6g", mean[i]); if(i != dim - 1) fprintf(stdout, " "); } if(!flag) fprintf(stdout, "\n\n"); else fprintf(stdout, "\n"); if(!flag) fprintf(stdout, "Covariance :\n"); for(i = 0; i < dim; i++){ for(j = 0; j < dim; j++){ fprintf(stdout, "%#+.6g", sigma[i][j]); if(j != dim - 1) fprintf(stdout, " "); } fprintf(stdout, "\n"); } /* 終了処理 */ free_double_matrix(data); free_double_vector(mean); free_double_matrix(sigma); exit(0); }
void hqr(double **mat, double *dr, double *di, int n) // 行列の中身は書き換えられるので注意 { int i, j, k, kaisuu, m; double d, e, p, q, r, sint, cost, beta, gamma, dd; double *c, *s; c = new_double_vector(n); s = new_double_vector(n); m = n; while(m >= 1) { if(m == 1) { dr[0] = mat[0][0]; di[0] = 0.0; break; } for(kaisuu = 1; kaisuu < MAX_TIME; ++kaisuu) { /* 収束判定 */ if(fabs(mat[m - 1][m - 2]) < STOP_THRESHOLD) { dr[m - 1] = mat[m - 1][m - 1]; di[m - 1] = 0.0; m -= 1; break; } if(fabs(mat[m - 2][m - 3]) < STOP_THRESHOLD) { beta = (-mat[m - 2][m - 2] - mat[m - 1][m - 1]); gamma = mat[m - 2][m - 2] * mat[m - 1][m - 1] - mat[m - 2][m - 1] * mat[m - 1][m - 2]; dd = beta * beta - 4.0 * gamma; d = sqrt(fabs(beta * beta - 4.0 * gamma)); if(dd > 0.0) { if(beta > 0.0) d = (-d); dr[m - 2] = (-beta + d) / 2.0; dr[m - 1] = gamma / dr[m - 2]; di[m - 1] = di[m - 2] = 0.0; } else { dr[m - 1] = dr[m - 2] = (-beta) / 2.0; di[m - 1] = d / 2.0; di[m - 2] = (-d / 2.0); } m -= 2; break; } /* QR分解 */ for(k = 0; k < m-1; ++k) { d = mat[k][k]; e = mat[k + 1][k]; r = sqrt(d * d + e * e); c[k] = cost = d / r; s[k] = sint = e / r; for(j = k; j < m; ++j) { p = mat[k][j]; q = mat[k + 1][j]; mat[k][j] = cost * p + sint * q; mat[k + 1][j] = (-sint * p + cost * q); } } /* 逆順乗算 */ for(k = 0; k < m-1; ++k) { cost = c[k]; sint = s[k]; for(i = 0; i <= k + 1; ++i) { p = mat[i][k]; q = mat[i][k + 1]; mat[i][k] = cost * p + sint * q; mat[i][k + 1] = (-sint * p + cost * q); } } } // end of for(kaisuu = 1; kaisuu < MAX_ITER; ++kaisuu) } //end of while(m >= 1) { /* 終了処理 */ free_double_vector(c); free_double_vector(s); }
void hes(double **mat, int n) // 行列の中身は書き換えられるので注意 { int i, j, k; double aik, alpha, s, ss, uu; double *u, *v, *w, *vv, *ww; u = new_double_vector(n); v = new_double_vector(n); w = new_double_vector(n); vv = new_double_vector(n); ww = new_double_vector(n); for(k = 0; k < n - 2; ++k) { ss = 0.0; for(i = k + 1; i < n; ++i) { aik = mat[i][k]; u[i] = aik; ss += aik * aik; } s = sqrt(ss); if(u[k + 1] > 0.0) s = (-s); u[k] = 0.0; u[k + 1] -= s; uu = sqrt(2.0 * (ss - mat[k + 1][k] * s)); for(i = k; i < n; ++i) u[i] /= uu; for(i = k; i < n; ++i) { s = 0.0; ss = 0.0; for(j = k; j < n; ++j) { s += mat[i][j] * u[j]; ss += mat[j][i] * u[j]; } v[i] = s; vv[i] = ss; } s = 0.0; for(i = k; i < n; ++i) s += u[i] * v[i]; alpha = s; for(i = k; i < n; ++i) { w[i] = (v[i] - alpha * u[i]) * 2.0; ww[i] = (vv[i] - alpha * u[i]) * 2.0; } for(i = k; i < n; ++i) { for(j = k; j < n; ++j) { mat[i][j] -= u[i] * ww[j] + w[i] * u[j]; } } } free_double_vector(u); free_double_vector(v); free_double_vector(w); free_double_vector(vv); free_double_vector(ww); }