static ERL_NIF_TERM divide(ErlNifEnv *env, int32_t argc, const ERL_NIF_TERM *argv) { ErlNifBinary first, second; ERL_NIF_TERM result; float *first_data, *second_data, *result_data; int32_t data_size; size_t result_size; (void)(argc); if (!enif_inspect_binary(env, argv[0], &first )) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &second)) return enif_make_badarg(env); first_data = (float *) first.data; second_data = (float *) second.data; data_size = (int32_t) (first_data[0] * first_data[1] + 2); result_size = sizeof(float) * data_size; result_data = (float *) enif_make_new_binary(env, result_size, &result); matrix_divide(first_data, second_data, result_data); return result; }
void factorize(double *v, int row, int col, int features, unsigned int count, MatrixFactor *mf) { // 重みの行列と特徴の行列をランダムな値で初期化. double * h = new double[features * col]; double * hn = new double[features * col]; double * hd = new double[features * col]; double * hd_t = new double[features * features]; double * w = new double[row * features]; double * wn = new double[row * features]; double * wd = new double[row * features]; double * wd_t = new double[row * col]; // 重みと特徴の乗算結果用行列. double * wh = new double[row * col]; matrix_init_zero((double*)wh, row, col); matrix_init(h, features, col); matrix_init_zero(hn, features, col); matrix_init_zero(hd, features, col); matrix_init_zero(hd_t, features, features); matrix_init(w, row, features); matrix_init_zero(wn, row, features); matrix_init_zero(wd, row, features); matrix_init_zero(wd_t, row, col); //matrix_print((double*)h, features, col); //matrix_print((double*)w, raw, features); unsigned int i = 0; for (i = 0; i < count; i++){ // 特徴の重みの行列の積から、元データとの差を計算する. matrix_x(wh, w, h, row, features, col); int cost = matrix_diff(v, wh, row, col); // 差が完全にゼロになったらループを抜ける. if (cost == 0){ break; } //------------------------------------------------------------------------------------------- // 特徴の行列を更新する. //------------------------------------------------------------------------------------------- // hn 転置した重みの行列にデータ行列を掛け合わせたもの matrix_tx_left(hn, w, v, features, row, col); // hd 転置した重みの行列に重みの行列を掛け合わせたものに特徴の行列を掛け合わせたもの matrix_tx_left(hd_t, w, w, features, row, features); matrix_x(hd, hd_t, h, features, features, col); matrix_x(h, h, hn, features, col); matrix_divide(h, h, hd, features, col); //------------------------------------------------------------------------------------------- // 重みの行列を更新する. //------------------------------------------------------------------------------------------- // wn データ行列に転置した特長の行列を掛け合わせたもの. matrix_tx_right(wn, v, h, row, col, features); // wd 重みの行列に、特徴の行列を掛け合わせたものに転置した特長の行列を掛け合わせたもの. matrix_x(wd_t, w, h, row, features, col); matrix_tx_right(wd, wd_t, h, row, col, features); matrix_x(w, w, wn, row, features); matrix_divide(w, w, wd, row, features); } mf->h = h; mf->w = w; //matrix_x(wh, w, h, ROW, FEATURES, COL); //matrix_print(wh, ROW, COL); //matrix_print(w, ROW, FEATURES); //matrix_print(h, FEATURES, COL); delete[] hn; delete[] hd; delete[] hd_t; delete[] wn; delete[] wd; delete[] wd_t; delete[] wh; }