Example #1
0
 inline
 float
 compute_quadratic_cubic_approximate_error(fastuidraw::c_array<const fastuidraw::vec2> p)
 {
   /* This is derivied fromt the article at
    *     http://caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html
    *
    * The derivation for the error comes from the following:
    *
    * Let p(t) = (1-t)^3 p0 + 3t(1-t)^2 p1 + 3t^2(1-t) p2 + t^3 p3
    *
    * Set A = 3p1 - p0, B = 3p2 - p1
    * q0 = p0, q1 = (A + B) / 4 and q2 = p2
    *
    * then, after lots of algebra,
    *
    * p(t) - q(t) = (A - B) (t^3 - 1.5t^2 + 0.5t)
    *
    * then the maximum error in each coordinate occurs when
    * the polynomial Z(t) =  t^3 - 1.5t^2 + 0.5t has maixmal
    * absolute value the critical points; thus we need to only
    * check the critical points which are when Z'(t) = 0 which
    * are t1 = 0.5 * (1 - sqrt(3)) and t2 = 0.5 * (1 + sqrt(3)).
    * Z(t1) = sqrt(3) / 36 and Z(t2) = -sqrt(3) / 36. Hence,
    * the maximal error of max ||p(t) - q(t) || over 0 <= t < 1
    * is ||A - B|| * sqrt(3) / 36
    */
   const float error_coeff(0.04811252243f);
   fastuidraw::vec2 error_vec(p[3] - 3.0f * p[2] + 3.0f * p[1] - p[0]);
   float error(error_coeff * error_vec.magnitude());
   return error;
 }
Example #2
0
void line_trainer_path::train_path(int mode, int *node_lst, real alpha, real *_error_vec, real *_error_p, real *_error_q, double (*func_rand_num)(), unsigned long long &rand_index, int model)
{
    int target, label, u, v, vector_size, trans_id;
    real f, g;
    std::string path_type = std::string();
    int step_bg = 0, step_ed = 0, pst_bg = 0, pst_ed = 0;
    line_node *node_u = phin->node_u, *node_v = phin->node_v;
    
    vector_size = node_u->vector_size;
    Eigen::Map<BLPVector> error_vec(_error_vec, vector_size);
    Eigen::Map<BLPVector> error_p(_error_p, vector_size);
    Eigen::Map<BLPVector> error_q(_error_q, vector_size);
    error_vec.setZero();
    error_p.setZero();
    error_q.setZero();
    
    sample_path(node_lst, func_rand_num);
    
    if (model == 0)
    {
        step_bg = path_size - 1; step_ed = path_size;
        pst_bg = 0; pst_ed = 1;
    }
    else if (model == 1)
    {
        step_bg = 1; step_ed = 2;
        pst_bg = 0; pst_ed = path_size - 1;
    }
    else if (model == 2)
    {
        step_bg = 1; step_ed = path_size;
        pst_bg = 0; pst_ed = path_size - 1;
    }
    
    for (int step = step_bg; step != step_ed; step++) for (int pst = pst_bg; pst != pst_ed; pst++)
    {
        if (pst + step >= path_size) continue;
        
        path_type = path.substr(pst * 2, step * 2 + 1);
        trans_id = map_trans[path_type];
        if (trans_id == 0)
        {
            printf("ERROR: trans id error!\n");
            exit(1);
        }
        trans_id--;
        
        u = node_lst[pst];
        v = node_lst[pst + step];
        
        error_vec.setZero();
        error_p.setZero();
        error_q.setZero();
        
        for (int d = 0; d < neg_samples + 1; d++)
        {
            if (d == 0)
            {
                target = v;
                label = 1;
            }
            else
            {
                rand_index = rand_index * (unsigned long long)25214903917 + 11;
                target = neg_table[pst + step][(rand_index >> 16) % neg_table_size];
                if (target == v) continue;
                label = 0;
            }
            f = 0;
            f += node_u->vec.row(u) * node_v->vec.row(target).transpose();
            if (mode == 1 || mode == 2 || mode == 3)
            {
                f += (node_u->vec.row(u)) * (vec_trans[trans_id]->P.transpose());
                f += (node_v->vec.row(target)) * (vec_trans[trans_id]->Q.transpose());
                f += vec_trans[trans_id]->bias;
            }
            if (f > MAX_EXP) g = (label - 1) * alpha;
            else if (f < -MAX_EXP) g = (label - 0) * alpha;
            else g = (label - expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))]) * alpha;
            if (mode == 2 || mode == 3)
            {
                error_p += g * (node_u->vec.row(u));
                error_q += g * (node_v->vec.row(target));
            }
            if (mode == 1 || mode == 3)
            {
                error_vec += g * ((node_v->vec.row(target)));
                error_vec += g * (vec_trans[trans_id]->P);
                
                node_v->vec.row(target) += g * ((node_u->vec.row(u)));
                node_v->vec.row(target) += g * (vec_trans[trans_id]->Q);
            }
            if (mode == 0)
            {
                error_vec += g * node_v->vec.row(target);
                node_v->vec.row(target) += g * node_u->vec.row(u);
            }
        }
        if (mode == 0 || mode == 1 || mode == 3) node_u->vec.row(u) += error_vec;
        if (mode == 2 || mode == 3)
        {
            vec_trans[trans_id]->P += error_p;
            vec_trans[trans_id]->Q += error_q;
        }
    }
    new (&error_vec) Eigen::Map<BLPMatrix>(NULL, 0, 0);
    new (&error_p) Eigen::Map<BLPMatrix>(NULL, 0, 0);
    new (&error_q) Eigen::Map<BLPMatrix>(NULL, 0, 0);
}
Example #3
0
void line_trainer_edge::train_sample_randwalk(int mode, real alpha, real restart, real *_error_vec, real *_error_p, real *_error_q, double (*func_rand_num)(), unsigned long long &rand_index)
{
    int target, label, u, v, node, index, vector_size, trans_id;
    real f, g;
    std::string edge_type = std::string();
    line_node *node_u = phin->node_u, *node_v = phin->node_v;
    std::vector<int> node_lst;
    int node_cnt = 0;
    
    vector_size = node_u->vector_size;
    Eigen::Map<BLPVector> error_vec(_error_vec, vector_size);
    Eigen::Map<BLPVector> error_p(_error_p, vector_size);
    Eigen::Map<BLPVector> error_q(_error_q, vector_size);
    error_vec.setZero();
    error_p.setZero();
    error_q.setZero();
    
    edge_type += edge_tp;
    trans_id = map_trans[edge_type];
    if (trans_id == 0)
    {
        printf("ERROR: trans id error!\n");
        exit(1);
    }
    trans_id--;
    
    node_lst.clear();
    
    node = (int)(ransampl_draw(smp_u, func_rand_num(), func_rand_num()));
    node_lst.push_back(node);
    node_cnt = 0;
    while(1)
    {
        if (func_rand_num() < restart) break;
        if (u_nb_cnt[node_lst[node_cnt]] == 0) break;
        index = (int)(ransampl_draw(smp_u_nb[node_lst[node_cnt]], func_rand_num(), func_rand_num()));
        node = u_nb_id[node_lst[node_cnt]][index];
        node_lst.push_back(node);
        node_cnt++;
    }
    
    for (int k = 1; k <= node_cnt; k++)
    {
        u = node_lst[0];
        v = node_lst[k];
        
        error_vec.setZero();
        error_p.setZero();
        error_q.setZero();
        
        for (int d = 0; d < neg_samples + 1; d++)
        {
            if (d == 0)
            {
                target = v;
                label = 1;
            }
            else
            {
                rand_index = rand_index * (unsigned long long)25214903917 + 11;
                target = neg_table[(rand_index >> 16) % neg_table_size];
                if (target == v) continue;
                label = 0;
            }
            f = 0;
            f += node_u->vec.row(u) * node_v->vec.row(target).transpose();
            if (mode == 1 || mode == 2 || mode == 3)
            {
                f += (node_u->vec.row(u)) * (vec_trans[trans_id]->P.transpose());
                f += (node_v->vec.row(target)) * (vec_trans[trans_id]->Q.transpose());
                f += vec_trans[trans_id]->bias;
            }
            if (f > MAX_EXP) g = (label - 1) * alpha;
            else if (f < -MAX_EXP) g = (label - 0) * alpha;
            else g = (label - expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))]) * alpha;
            if (mode == 2 || mode == 3)
            {
                error_p += g * (node_u->vec.row(u));
                error_q += g * (node_v->vec.row(target));
            }
            if (mode == 1 || mode == 3)
            {
                error_vec += g * ((node_v->vec.row(target)));
                error_vec += g * (vec_trans[trans_id]->P);
                
                node_v->vec.row(target) += g * ((node_u->vec.row(u)));
                node_v->vec.row(target) += g * (vec_trans[trans_id]->Q);
            }
            if (mode == 0)
            {
                error_vec += g * node_v->vec.row(target);
                node_v->vec.row(target) += g * node_u->vec.row(u);
            }
        }
        if (mode == 0 || mode == 1 || mode == 3) node_u->vec.row(u) += error_vec;
        if (mode == 2 || mode == 3)
        {
            vec_trans[trans_id]->P += error_p;
            vec_trans[trans_id]->Q += error_q;
        }
    }
    new (&error_vec) Eigen::Map<BLPMatrix>(NULL, 0, 0);
    new (&error_p) Eigen::Map<BLPMatrix>(NULL, 0, 0);
    new (&error_q) Eigen::Map<BLPMatrix>(NULL, 0, 0);
}