コード例 #1
0
ファイル: view.c プロジェクト: jpeak5/csc4356
void view_turn(view *V, const double *w)
{
#if 0
    double M[16], T[16], q[4], a[3], b[3], c[3], t[3];

    assert(V);

    /* Transform the mark and drag vectors from eye space into the world     */
    /* space current at the time of the mark.                                */

    state_matrix(M, &V->mark);

    mtranspose(T, M);
    vnormalize(t, V->a);
    vtransform(a, T, t);
    vnormalize(t,    w);
    vtransform(b, T, t);

    /* These determine the axis and angle of rotation.  Find the quaternion. */

    vcrs(t, a, b);
    vnormalize(c, t);
    qrotate(q, c, acos(vdot(a, b)));

    /* Accumulate this quaternion with the view state, rotating the view.    */

    qmultiply(view_curr(V)->q, V->mark.q, q);
#endif
}
コード例 #2
0
ファイル: shaderlib.c プロジェクト: ProjectAsura/lucille
void
diffuse_cn(float4 *ret, float4 N)
{
    float4 L;
    float NdotL;
    float4 rr;

    L = rsl_getL();

    vnormalize(&L);

    NdotL = vdot(N, L);
    if (NdotL < 0.0f) {
        NdotL = 0.0f;
    }

    //printf("diffuse. L = %f, %f, %f\n", L[0], L[1], L[2]);
    //printf("diffuse. N = %f, %f, %f\n", N[0], N[1], N[2]);
    //printf("diffuse. NdotL = %f\n", NdotL);

    rr[0] = NdotL;
    rr[1] = NdotL;
    rr[2] = NdotL;
    rr[3] = NdotL;
    (*ret) = rr;
}
コード例 #3
0
ファイル: view.c プロジェクト: jpeak5/csc4356
void view_mark(view *V, const double *m)
{
    assert(V);
    vnormalize(V->m, m);

    memcpy(&V->mark, view_curr(V), sizeof (state));
}
コード例 #4
0
ファイル: aobench.c プロジェクト: Falken42/aobench-android
void
ray_sphere_intersect(Isect *isect, const Ray *ray, const Sphere *sphere)
{
	vec rs;

	rs.x = ray->org.x - sphere->center.x;
	rs.y = ray->org.y - sphere->center.y;
	rs.z = ray->org.z - sphere->center.z;

	aobfloat B = vdot(rs, ray->dir);
	aobfloat C = vdot(rs, rs) - sphere->radius * sphere->radius;
	aobfloat D = B * B - C;

	if (D > 0.0) {
		aobfloat t = -B - sqrt(D);
		
		if ((t > 0.0) && (t < isect->t)) {
			isect->t = t;
			isect->hit = 1;
			
			isect->p.x = ray->org.x + ray->dir.x * t;
			isect->p.y = ray->org.y + ray->dir.y * t;
			isect->p.z = ray->org.z + ray->dir.z * t;

			isect->n.x = isect->p.x - sphere->center.x;
			isect->n.y = isect->p.y - sphere->center.y;
			isect->n.z = isect->p.z - sphere->center.z;

			vnormalize(&(isect->n));
		}
	}
}
コード例 #5
0
// -------------------------------------------------------------------------- //
//
void Test_Mathutils::testVectorNormalization()
{
    // Setup.
    std::vector<double> vec0(4);
    vec0[0] =  1.1;
    vec0[1] =  2.2;
    vec0[2] =  3.3;
    vec0[3] =  7.7;

    const double norm0 = vec0[0] + vec0[1] + vec0[2] + vec0[3];

    std::vector<double> vec1(4);
    vec1[0] =   2.1;
    vec1[1] =   3.2;
    vec1[2] =   4.3;
    vec1[3] =  11.7;

    const double norm1 = vec1[0] + vec1[1] + vec1[2] + vec1[3];

    // Take a reference.
    const std::vector<double> ref = vec0;
    const std::vector<double> ref1 = vec1;

    // Call.
    vnormalize(vec0, ref1);

    // Check.
    CPPUNIT_ASSERT_EQUAL(static_cast<int>(vec0.size()), static_cast<int>(ref.size()));
    CPPUNIT_ASSERT_DOUBLES_EQUAL( vec0[0], ref[0]*norm1/norm0, EPS );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( vec0[1], ref[1]*norm1/norm0, EPS );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( vec0[2], ref[2]*norm1/norm0, EPS );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( vec0[3], ref[3]*norm1/norm0, EPS );
}
コード例 #6
0
ファイル: aof_gcd.c プロジェクト: Pentan/iaobenchCollection
static void
render_tile(unsigned char *img, int comps, float *fimg, int w, int h, int nsubsamples, int tilex, int tiley, int tilew, int tileh)
{
    int endx = tilex + min_i(tilew, w - tilex);
    int endy = tiley + min_i(tileh, h - tiley);
    
    int x, y;
    int u, v;
    
    for (y = tiley; y < endy; y++) {
        for (x = tilex; x < endx; x++) {
            
            for (v = 0; v < nsubsamples; v++) {
                for (u = 0; u < nsubsamples; u++) {
                    float px = (x + (u / (float)nsubsamples) - (w / 2.0)) / (w / 2.0);
                    float py = -(y + (v / (float)nsubsamples) - (h / 2.0)) / (h / 2.0);

                    Ray ray;

                    ray.org.x = 0.0;
                    ray.org.y = 0.0;
                    ray.org.z = 0.0;

                    ray.dir.x = px;
                    ray.dir.y = py;
                    ray.dir.z = -1.0;
                    vnormalize(&(ray.dir));

                    Isect isect;
                    isect.t   = 1.0e+17;
                    isect.hit = 0;

                    ray_sphere_intersect(&isect, &ray, &spheres[0]);
                    ray_sphere_intersect(&isect, &ray, &spheres[1]);
                    ray_sphere_intersect(&isect, &ray, &spheres[2]);
                    ray_plane_intersect (&isect, &ray, &plane);

                    if (isect.hit) {
                        vec col;
                        ambient_occlusion(&col, &isect);

                        fimg[3 * (y * w + x) + 0] += col.x;
                        fimg[3 * (y * w + x) + 1] += col.y;
                        fimg[3 * (y * w + x) + 2] += col.z;
                    }

                }
            }

            fimg[3 * (y * w + x) + 0] /= (float)(nsubsamples * nsubsamples);
            fimg[3 * (y * w + x) + 1] /= (float)(nsubsamples * nsubsamples);
            fimg[3 * (y * w + x) + 2] /= (float)(nsubsamples * nsubsamples);

            img[comps * (y * w + x) + 0] = clamp(fimg[3 *(y * w + x) + 0]);
            img[comps * (y * w + x) + 1] = clamp(fimg[3 *(y * w + x) + 1]);
            img[comps * (y * w + x) + 2] = clamp(fimg[3 *(y * w + x) + 2]);
        }
    }
}
コード例 #7
0
static void calcTriNormal(const float* v0, const float* v1, const float* v2, float* norm)
{
	float e0[3], e1[3];
	vsub(e0, v1, v0);
	vsub(e1, v2, v0);
	vcross(norm, e0, e1);
	vnormalize(norm);
}
コード例 #8
0
ファイル: ftriangle.c プロジェクト: droVaTar/RT
t_vector	count_triangle_normale(t_vector a[3])
{
    t_vector    ab;
    t_vector    bc;

    ab = vsub(a[0], a[1]);
    bc = vsub(a[1], a[2]);
    return (vnormalize(vmultiple(ab, bc)));
}
コード例 #9
0
ファイル: ao_serial.cpp プロジェクト: danielmundt/ispc
/* Compute the image for the scanlines from [y0,y1), for an overall image
   of width w and height h.
 */
static void ao_scanlines(int y0, int y1, int w, int h, int nsubsamples,
                         float image[]) {
    static Plane plane = { vec(0.0f, -0.5f, 0.0f), vec(0.f, 1.f, 0.f) };
    static Sphere spheres[3] = {
        { vec(-2.0f, 0.0f, -3.5f), 0.5f },
        { vec(-0.5f, 0.0f, -3.0f), 0.5f },
        { vec(1.0f, 0.0f, -2.2f), 0.5f } };

    srand48(y0);

    for (int y = y0; y < y1; ++y) {
        for (int x = 0; x < w; ++x)  {
            int offset = 3 * (y * w + x);
            for (int u = 0; u < nsubsamples; ++u) {
                for (int v = 0; v < nsubsamples; ++v) {
                    float px = (x + (u / (float)nsubsamples) - (w / 2.0f)) / (w / 2.0f);
                    float py = -(y + (v / (float)nsubsamples) - (h / 2.0f)) / (h / 2.0f);

                    // Scale NDC based on width/height ratio, supporting non-square image output
                    px *= (float)w / (float)h;

                    float ret = 0.f;
                    Ray ray;
                    Isect isect;

                    ray.org = vec(0.f, 0.f, 0.f);

                    ray.dir.x = px;
                    ray.dir.y = py;
                    ray.dir.z = -1.0f;
                    vnormalize(ray.dir);

                    isect.t   = 1.0e+17f;
                    isect.hit = 0;

                    for (int snum = 0; snum < 3; ++snum)
                        ray_sphere_intersect(isect, ray, spheres[snum]);
                    ray_plane_intersect(isect, ray, plane);

                    if (isect.hit)
                        ret = ambient_occlusion(isect, plane, spheres);

                    // Update image for AO for this ray
                    image[offset+0] += ret;
                    image[offset+1] += ret;
                    image[offset+2] += ret;
                }
            }
            // Normalize image pixels by number of samples taken per pixel
            image[offset+0] /= nsubsamples * nsubsamples;
            image[offset+1] /= nsubsamples * nsubsamples;
            image[offset+2] /= nsubsamples * nsubsamples;
        }
    }
}
コード例 #10
0
ファイル: DebugDraw.cpp プロジェクト: Denominator13/NeoCore
void appendArrowHead(struct duDebugDraw* dd, const float* p, const float* q,
					 const float s, unsigned int col)
{
	if (!dd) return;
	float ax[3], ay[3] = {0,1,0}, az[3];
	vsub(az, q, p);
	vnormalize(az);
	vcross(ax, ay, az);
	vcross(ay, az, ax);
	vnormalize(ay);

	dd->vertex(p, col);
//	dd->vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col);
	dd->vertex(p[0]+az[0]*s+ax[0]*s/3, p[1]+az[1]*s+ax[1]*s/3, p[2]+az[2]*s+ax[2]*s/3, col);

	dd->vertex(p, col);
//	dd->vertex(p[0]+az[0]*s-ay[0]*s/2, p[1]+az[1]*s-ay[1]*s/2, p[2]+az[2]*s-ay[2]*s/2, col);
	dd->vertex(p[0]+az[0]*s-ax[0]*s/3, p[1]+az[1]*s-ax[1]*s/3, p[2]+az[2]*s-ax[2]*s/3, col);
	
}
コード例 #11
0
ファイル: fcone.c プロジェクト: droVaTar/RT
t_vector		get_cone_normale(t_vector p, t_icone *cone)
{
	double		m;
	t_vector	res;

	m = pow(vlen(vsub(p, cone->vertex)), 2) / vscalar_multiple(vsub(p,
			cone->vertex), cone->vector);
	res = vsum(cone->vertex, vk_multiple(cone->vector, m));
	res = vnormalize(vsub(p, res));
	return (res);
}
コード例 #12
0
ファイル: aobench.c プロジェクト: Falken42/aobench-android
// modified to only render one row (specified by parameter y) per function call
void
aobench_render(unsigned char *img, int w, int h, int nsubsamples, int y)
{
	int x, u, v;

	for (x = 0; x < w; x++) {
		aobfloat r = 0.0, g = 0.0, b = 0.0;
		
		for (v = 0; v < nsubsamples; v++) {
			for (u = 0; u < nsubsamples; u++) {
				aobfloat px =  (x + (u / (aobfloat)nsubsamples) - (w / 2.0)) / (w / 2.0);
				aobfloat py = -(y + (v / (aobfloat)nsubsamples) - (h / 2.0)) / (h / 2.0);

				Ray ray;

				ray.org.x = 0.0;
				ray.org.y = 0.0;
				ray.org.z = 0.0;

				ray.dir.x = px;
				ray.dir.y = py;
				ray.dir.z = -1.0;
				vnormalize(&(ray.dir));

				Isect isect;
				isect.t   = 1.0e+17;
				isect.hit = 0;

				ray_sphere_intersect(&isect, &ray, &spheres[0]);
				ray_sphere_intersect(&isect, &ray, &spheres[1]);
				ray_sphere_intersect(&isect, &ray, &spheres[2]);
				ray_plane_intersect (&isect, &ray, &plane);

				if (isect.hit) {
					vec col;
					ambient_occlusion(&col, &isect);

					r += col.x;
					g += col.y;
					b += col.z;
				}

			}
		}

		r /= (aobfloat)(nsubsamples * nsubsamples);
		g /= (aobfloat)(nsubsamples * nsubsamples);
		b /= (aobfloat)(nsubsamples * nsubsamples);
	
		img[3 * (y * w + x) + 0] = clamp(r);
		img[3 * (y * w + x) + 1] = clamp(g);
		img[3 * (y * w + x) + 2] = clamp(b);
	}
}
コード例 #13
0
void sph_model::zoom(double *w, const double *v)
{
    double d = vdot(v, zoomv);
    
    if (-1 < d && d < 1)
    {
        double b = scale(zoomk, acos(d) / M_PI) * M_PI;
                
        double y[3];
        double x[3];
        
        vcrs(y, v, zoomv);
        vnormalize(y, y);
        vcrs(x, zoomv, y);
        vnormalize(x, x);
        
        vmul(w, zoomv, cos(b));
        vmad(w, w,  x, sin(b));
    }
    else vcpy(w, v);
}
コード例 #14
0
ファイル: ao_serial.cpp プロジェクト: danielmundt/ispc
static inline void
orthoBasis(vec basis[3], const vec &n) {
    basis[2] = n;
    basis[1].x = 0.0; basis[1].y = 0.0; basis[1].z = 0.0;

    if ((n.x < 0.6f) && (n.x > -0.6f)) {
        basis[1].x = 1.0;
    } else if ((n.y < 0.6f) && (n.y > -0.6f)) {
        basis[1].y = 1.0;
    } else if ((n.z < 0.6f) && (n.z > -0.6f)) {
        basis[1].z = 1.0;
    } else {
        basis[1].x = 1.0;
    }

    basis[0] = vcross(basis[1], basis[2]);
    vnormalize(basis[0]);

    basis[1] = vcross(basis[2], basis[0]);
    vnormalize(basis[1]);
}
コード例 #15
0
static void bislerp(double *p, const double *a, const double *b,
                               const double *c, const double *d,
                               double x, double y)
{
    double t[3];
    double u[3];
    
    vslerp(t, a, b, x);
    vslerp(u, c, d, x);
    vslerp(p, t, u, y);

    vnormalize(p, p);
}
コード例 #16
0
ファイル: aof_vbase.c プロジェクト: Pentan/iaobenchCollection
static void
orthoBasis(vec *basis, vec n)
{
    basis[2] = n;
    basis[1].x = 0.0; basis[1].y = 0.0; basis[1].z = 0.0;

    if ((n.x < 0.6) && (n.x > -0.6)) {
        basis[1].x = 1.0;
    } else if ((n.y < 0.6) && (n.y > -0.6)) {
        basis[1].y = 1.0;
    } else if ((n.z < 0.6) && (n.z > -0.6)) {
        basis[1].z = 1.0;
    } else {
        basis[1].x = 1.0;
    }

    vcross(&basis[0], basis[1], basis[2]);
    vnormalize(&basis[0]);

    vcross(&basis[1], basis[2], basis[0]);
    vnormalize(&basis[1]);
}
コード例 #17
0
ファイル: ctr.cpp プロジェクト: anukat2015/ctr
void c_ctr::read_init_information(const char* theta_init_path, 
                                  const char* beta_init_path,
                                  const c_corpus* c,
                                  double alpha_smooth) {
  int num_topics = m_num_factors;
  m_theta = gsl_matrix_alloc(c->m_num_docs, num_topics);
  printf("\nreading theta initialization from %s\n", theta_init_path);
  FILE * f = fopen(theta_init_path, "r");
  mtx_fscanf(f, m_theta);
  fclose(f);

  //smoothing
  gsl_matrix_add_constant(m_theta, alpha_smooth);

  //normalize m_theta, in case it's not
  for (size_t j = 0; j < m_theta->size1; j ++) {
    gsl_vector_view theta_v = gsl_matrix_row(m_theta, j);
    vnormalize(&theta_v.vector);
  }

  m_beta = gsl_matrix_alloc(num_topics, c->m_size_vocab);
  printf("reading beta initialization from %s\n", beta_init_path);
  f = fopen(beta_init_path, "r");
  mtx_fscanf(f, m_beta);
  fclose(f);

  // exponentiate if it's not
  if (mget(m_beta, 0, 0) < 0) {
    mtx_exp(m_beta);
  }
  else {
    gsl_matrix_add_constant(m_beta, beta_smooth);
    for (size_t j = 0; j < m_beta->size1; j ++) {
      gsl_vector_view beta_v = gsl_matrix_row(m_beta, j);
      vnormalize(&beta_v.vector);
    }
  }
}
コード例 #18
0
ファイル: ctr.cpp プロジェクト: anukat2015/ctr
double c_ctr::doc_inference(const c_document* doc, const gsl_vector* theta_v, 
                            const gsl_matrix* log_beta, gsl_matrix* phi,
                            gsl_vector* gamma, gsl_matrix* word_ss, 
                            bool update_word_ss) {

  double pseudo_count = 1.0;
  double likelihood = 0;
  gsl_vector* log_theta_v = gsl_vector_alloc(theta_v->size);
  gsl_vector_memcpy(log_theta_v, theta_v);
  vct_log(log_theta_v);

  int n, k, w;
  double x;
  for (n = 0; n < doc->m_length; n ++) {
    w = doc->m_words[n]; 
    for (k = 0; k < m_num_factors; k ++)
      mset(phi, n, k, vget(theta_v, k) * mget(m_beta, k, w));

    gsl_vector_view row =  gsl_matrix_row(phi, n);
    vnormalize(&row.vector);

    for (k = 0; k < m_num_factors; k ++) {
      x = mget(phi, n, k);
      if (x > 0) 
        likelihood += x*(vget(log_theta_v, k) + mget(log_beta, k, w) - log(x));
    }
  }

  if (pseudo_count > 0) {
    likelihood += pseudo_count * vsum(log_theta_v);
  }

  gsl_vector_set_all(gamma, pseudo_count); // smoothing with small pseudo counts
  for (n = 0; n < doc->m_length; n ++) {
    for (k = 0; k < m_num_factors; k ++) {
      x = doc->m_counts[n] * mget(phi, n, k);
      vinc(gamma, k, x);      
      if (update_word_ss) minc(word_ss, k, doc->m_words[n], x);
    }
  }

  gsl_vector_free(log_theta_v);
  return likelihood;
}
コード例 #19
0
ファイル: ao_serial.cpp プロジェクト: dbabokin/ispc
static inline void ray_sphere_intersect(Isect &isect, Ray &ray, Sphere &sphere) {
    vec rs = ray.org - sphere.center;

    float B = dot(rs, ray.dir);
    float C = dot(rs, rs) - sphere.radius * sphere.radius;
    float D = B * B - C;

    if (D > 0.) {
        float t = -B - sqrtf(D);

        if ((t > 0.0) && (t < isect.t)) {
            isect.t = t;
            isect.hit = 1;
            isect.p = ray.org + t * ray.dir;
            isect.n = isect.p - sphere.center;
            vnormalize(isect.n);
        }
    }
}
コード例 #20
0
ファイル: fcone.c プロジェクト: droVaTar/RT
t_figure		*cone_init(t_ray *axis, double k, int color,
		double reflection)
{
	t_figure	*new_figure;
	t_icone		*cone;

	new_figure = (t_figure*)malloc(sizeof(t_figure));
	new_figure->type = InfiniteCone;
	cone = (t_icone*)malloc(sizeof(t_icone));
	new_figure->figure = cone;
	cone->vertex = axis->o;
	cone->radius = k;
	new_figure->color = color;
	new_figure->reflection = reflection;
	cone->vector = vnormalize(axis->v);
	free(axis);
	new_figure->next = NULL;
	return (new_figure);
}
コード例 #21
0
ファイル: shaderlib.c プロジェクト: ProjectAsura/lucille
void
specularbrdf_cvnvf(float4 *ret, float4 L, float4 N, float4 V, float roughness)
{
    float4 r;

    float4 H = L + V;
    vnormalize(&H);

    float NdotH = vdot(N, H);
    if (NdotH < 0.0f) NdotH = 0.0f;

    float val = powf(NdotH, 1.0f / roughness);

    r.x = val;
    r.y = val;
    r.z = val;

    (*ret) = r;

}
コード例 #22
0
ファイル: shaderlib.c プロジェクト: ProjectAsura/lucille
void
specular_cnvf(float4 *ret, float4 N, float4 V, float roughness)
{
    // TODO: Calculate contribution from lights in the scene.
  
    float4 Cl = rsl_getCl();
    float4 L  = rsl_getL();
    vnormalize(&L);

    float4 r;
    float4 specular_col;

    specularbrdf_cvnvf(&specular_col, L, N, V, roughness);

    r.x = Cl.x * specular_col.x;
    r.y = Cl.y * specular_col.y;
    r.z = Cl.z * specular_col.z;

    (*ret) = r;
}
コード例 #23
0
ファイル: aof_vbase.c プロジェクト: Pentan/iaobenchCollection
static void
ray_sphere_intersect(Isect *isect, const Ray *ray, const Sphere *sphere)
{
    vec rs;

    vsub(&rs, ray->org, sphere->center);
/*
    rs.x = ray->org.x - sphere->center.x;
    rs.y = ray->org.y - sphere->center.y;
    rs.z = ray->org.z - sphere->center.z;
*/

    float B = vdot(rs, ray->dir);
    float C = vdot(rs, rs) - sphere->radius * sphere->radius;
    float D = B * B - C;

    if (D > 0.0) {
        float t = -B - sqrt(D);
        
        if ((t > 0.0) && (t < isect->t)) {
            isect->t = t;
            isect->hit = 1;
            
            vmultsadd(&(isect->p), ray->dir, t, ray->org);

            vsub(&(isect->n), isect->p, sphere->center);
/*
            isect->p.x = ray->org.x + ray->dir.x * t;
            isect->p.y = ray->org.y + ray->dir.y * t;
            isect->p.z = ray->org.z + ray->dir.z * t;

            isect->n.x = isect->p.x - sphere->center.x;
            isect->n.y = isect->p.y - sphere->center.y;
            isect->n.z = isect->p.z - sphere->center.z;
*/
            vnormalize(&(isect->n));
        }
    }
}
コード例 #24
0
ファイル: intersect_disk.c プロジェクト: SN9NV/RT
int		intersect_disk(t_ray *r, t_prim *o, double *t)
{
	t_vector	point;
	double		denominator;
	double		numerator;
	double		t0;

	if ((denominator = vdot(r->dir, o->normal)) == 0)
		return (0);
	numerator = vdot(o->loc, o->normal) - vdot(r->loc, o->normal);
	t0 = numerator / denominator;
	if (t0 > EPSILON)
	{
		point = vadd(r->loc, vmult(r->dir, t0));
		if (vnormalize(vsub(point, o->loc)) <= o->radius)
		{
			*t = t0;
			return (1);
		}
		return (0);
	}
	return (0);
}
コード例 #25
0
ファイル: ctr.cpp プロジェクト: anukat2015/ctr
void c_ctr::learn_map_estimate(const c_data* users, const c_data* items, 
                               const c_corpus* c, const ctr_hyperparameter* param,
                               const char* directory) {
  // init model parameters
  printf("\ninitializing the model ...\n");
  init_model(param->ctr_run);

  // filename
  char name[500];

  // start time
  time_t start, current;
  time(&start);
  int elapsed = 0;

  int iter = 0;
  double likelihood = -exp(50), likelihood_old;
  double converge = 1.0;

  /// create the state log file 
  sprintf(name, "%s/state.log", directory);
  FILE* file = fopen(name, "w");
  fprintf(file, "iter time likelihood converge\n");


  /* alloc auxiliary variables */
  gsl_matrix* XX = gsl_matrix_alloc(m_num_factors, m_num_factors);
  gsl_matrix* A  = gsl_matrix_alloc(m_num_factors, m_num_factors);
  gsl_matrix* B  = gsl_matrix_alloc(m_num_factors, m_num_factors);
  gsl_vector* x  = gsl_vector_alloc(m_num_factors);

  gsl_matrix* phi = NULL;
  gsl_matrix* word_ss = NULL;
  gsl_matrix* log_beta = NULL;
  gsl_vector* gamma = NULL;

  if (param->ctr_run && param->theta_opt) {
    int max_len = c->max_corpus_length();
    phi = gsl_matrix_calloc(max_len, m_num_factors);
    word_ss = gsl_matrix_calloc(m_num_factors, c->m_size_vocab);
    log_beta = gsl_matrix_calloc(m_num_factors, c->m_size_vocab);
    gsl_matrix_memcpy(log_beta, m_beta);
    mtx_log(log_beta);
    gamma = gsl_vector_alloc(m_num_factors);
  }

  /* tmp variables for indexes */
  int i, j, m, n, l, k;
  int* item_ids; 
  int* user_ids;

  double result;

  /// confidence parameters
  double a_minus_b = param->a - param->b;

  while ((iter < param->max_iter and converge > 1e-4 ) or iter < min_iter) {

    likelihood_old = likelihood;
    likelihood = 0.0;

    // update U
    gsl_matrix_set_zero(XX);
    for (j = 0; j < m_num_items; j ++) {
      m = items->m_vec_len[j];
      if (m>0) {
        gsl_vector_const_view v = gsl_matrix_const_row(m_V, j); 
        gsl_blas_dger(1.0, &v.vector, &v.vector, XX);
      }
    }
    gsl_matrix_scale(XX, param->b);
    // this is only for U
    gsl_matrix_add_diagonal(XX, param->lambda_u); 

    for (i = 0; i < m_num_users; i ++) {
      item_ids = users->m_vec_data[i];
      n = users->m_vec_len[i];
      if (n > 0) {
        // this user has rated some articles
        gsl_matrix_memcpy(A, XX);
        gsl_vector_set_zero(x);
        for (l=0; l < n; l ++) {
          j = item_ids[l];
          gsl_vector_const_view v = gsl_matrix_const_row(m_V, j); 
          gsl_blas_dger(a_minus_b, &v.vector, &v.vector, A); 
          gsl_blas_daxpy(param->a, &v.vector, x);
        }

        gsl_vector_view u = gsl_matrix_row(m_U, i);
        matrix_vector_solve(A, x, &(u.vector));

        // update the likelihood
        gsl_blas_ddot(&u.vector, &u.vector, &result);
        likelihood += -0.5 * param->lambda_u * result;
      }
    }
    
    if (param->lda_regression) break; // one iteration is enough for lda-regression

    // update V
    if (param->ctr_run && param->theta_opt) gsl_matrix_set_zero(word_ss);

    gsl_matrix_set_zero(XX);
    for (i = 0; i < m_num_users; i ++) {
      n = users->m_vec_len[i]; 
      if (n>0) {
        gsl_vector_const_view u = gsl_matrix_const_row(m_U, i);
        gsl_blas_dger(1.0, &u.vector, &u.vector, XX);
      }
    }
    gsl_matrix_scale(XX, param->b);

    for (j = 0; j < m_num_items; j ++) {
      gsl_vector_view v = gsl_matrix_row(m_V, j);
      gsl_vector_view theta_v = gsl_matrix_row(m_theta, j);

      user_ids = items->m_vec_data[j];
      m = items->m_vec_len[j];
      if (m>0) {
        // m > 0, some users have rated this article
        gsl_matrix_memcpy(A, XX);
        gsl_vector_set_zero(x);
        for (l = 0; l < m; l ++) {
          i = user_ids[l];
          gsl_vector_const_view u = gsl_matrix_const_row(m_U, i);  
          gsl_blas_dger(a_minus_b, &u.vector, &u.vector, A);
          gsl_blas_daxpy(param->a, &u.vector, x);
        }

        // adding the topic vector
        // even when ctr_run=0, m_theta=0
        gsl_blas_daxpy(param->lambda_v, &theta_v.vector, x);
        
        gsl_matrix_memcpy(B, A); // save for computing likelihood 

        // here different from U update
        gsl_matrix_add_diagonal(A, param->lambda_v);  
        matrix_vector_solve(A, x, &v.vector);

        // update the likelihood for the relevant part
        likelihood += -0.5 * m * param->a;
        for (l = 0; l < m; l ++) {
          i = user_ids[l];
          gsl_vector_const_view u = gsl_matrix_const_row(m_U, i);  
          gsl_blas_ddot(&u.vector, &v.vector, &result);
          likelihood += param->a * result;
        }
        likelihood += -0.5 * mahalanobis_prod(B, &v.vector, &v.vector);
        // likelihood part of theta, even when theta=0, which is a
        // special case
        gsl_vector_memcpy(x, &v.vector);
        gsl_vector_sub(x, &theta_v.vector);
        gsl_blas_ddot(x, x, &result);
        likelihood += -0.5 * param->lambda_v * result;
        
        if (param->ctr_run && param->theta_opt) {
          const c_document* doc =  c->m_docs[j];
          likelihood += doc_inference(doc, &theta_v.vector, log_beta, phi, gamma, word_ss, true); 
          optimize_simplex(gamma, &v.vector, param->lambda_v, &theta_v.vector); 
        }
      }
      else {
      // m=0, this article has never been rated
        if (param->ctr_run && param->theta_opt) {
          const c_document* doc =  c->m_docs[j];
          doc_inference(doc, &theta_v.vector, log_beta, phi, gamma, word_ss, false); 
          vnormalize(gamma);
          gsl_vector_memcpy(&theta_v.vector, gamma);
        }
      }
    }

    // update beta if needed
    if (param->ctr_run && param->theta_opt) {
        gsl_matrix_memcpy(m_beta, word_ss);
        for (k = 0; k < m_num_factors; k ++) {
          gsl_vector_view row = gsl_matrix_row(m_beta, k);
          vnormalize(&row.vector);
        }
        gsl_matrix_memcpy(log_beta, m_beta);
        mtx_log(log_beta);
    }

    time(&current);
    elapsed = (int)difftime(current, start);

    iter++;
    converge = fabs((likelihood-likelihood_old)/likelihood_old);

    if (likelihood < likelihood_old) printf("likelihood is decreasing!\n");

    fprintf(file, "%04d %06d %10.5f %.10f\n", iter, elapsed, likelihood, converge);
    fflush(file);
    printf("iter=%04d, time=%06d, likelihood=%.5f, converge=%.10f\n", iter, elapsed, likelihood, converge);

    // save intermediate results
    if (iter % param->save_lag == 0) {

      sprintf(name, "%s/%04d-U.dat", directory, iter);
      FILE * file_U = fopen(name, "w");
      mtx_fprintf(file_U, m_U);
      fclose(file_U);

      sprintf(name, "%s/%04d-V.dat", directory, iter);
      FILE * file_V = fopen(name, "w");
      mtx_fprintf(file_V, m_V);
      fclose(file_V);

      if (param->ctr_run) { 
        sprintf(name, "%s/%04d-theta.dat", directory, iter);
        FILE * file_theta = fopen(name, "w");
        mtx_fprintf(file_theta, m_theta);
        fclose(file_theta);

        sprintf(name, "%s/%04d-beta.dat", directory, iter);
        FILE * file_beta = fopen(name, "w");
        mtx_fprintf(file_beta, m_beta);
        fclose(file_beta);
      }
    }
  }

  // save final results
  sprintf(name, "%s/final-U.dat", directory);
  FILE * file_U = fopen(name, "w");
  mtx_fprintf(file_U, m_U);
  fclose(file_U);

  sprintf(name, "%s/final-V.dat", directory);
  FILE * file_V = fopen(name, "w");
  mtx_fprintf(file_V, m_V);
  fclose(file_V);

  if (param->ctr_run) { 
    sprintf(name, "%s/final-theta.dat", directory);
    FILE * file_theta = fopen(name, "w");
    mtx_fprintf(file_theta, m_theta);
    fclose(file_theta);

    sprintf(name, "%s/final-beta.dat", directory);
    FILE * file_beta = fopen(name, "w");
    mtx_fprintf(file_beta, m_beta);
    fclose(file_beta);
  }

  // free memory
  gsl_matrix_free(XX);
  gsl_matrix_free(A);
  gsl_matrix_free(B);
  gsl_vector_free(x);

  if (param->ctr_run && param->theta_opt) {
    gsl_matrix_free(phi);
    gsl_matrix_free(log_beta);
    gsl_matrix_free(word_ss);
    gsl_vector_free(gamma);
  }
}
コード例 #26
0
ファイル: thing.hpp プロジェクト: jckarter/BattleMints
 line(vec2 pt_a, vec2 pt_b, int flags)
     : thing((pt_a+pt_b)*0.5f, LINE | flags),
       endpoint_a(pt_a), endpoint_b(pt_b), normal(vperp(vnormalize(endpoint_b - endpoint_a)))
     { }
コード例 #27
0
ファイル: aof_vbase.c プロジェクト: Pentan/iaobenchCollection
static void
render(unsigned char *img, int comps, int w, int h, int nsubsamples)
{
    int x, y;
    int u, v;

    //float *fimg = (float *)malloc(sizeof(float) * w * h * 3);
    vec *fimg = (vec *)malloc(sizeof(vec) * w * h);
    memset((void *)fimg, 0, sizeof(vec) * w * h);

    for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
            
            for (v = 0; v < nsubsamples; v++) {
                for (u = 0; u < nsubsamples; u++) {
                    float px = (x + (u / (float)nsubsamples) - (w / 2.0)) / (w / 2.0);
                    float py = -(y + (v / (float)nsubsamples) - (h / 2.0)) / (h / 2.0);

                    Ray ray;

                    ray.org.x = 0.0;
                    ray.org.y = 0.0;
                    ray.org.z = 0.0;

                    ray.dir.x = px;
                    ray.dir.y = py;
                    ray.dir.z = -1.0;
                    vnormalize(&(ray.dir));

                    Isect isect;
                    isect.t   = 1.0e+17;
                    isect.hit = 0;

                    ray_sphere_intersect(&isect, &ray, &spheres[0]);
                    ray_sphere_intersect(&isect, &ray, &spheres[1]);
                    ray_sphere_intersect(&isect, &ray, &spheres[2]);
                    ray_plane_intersect (&isect, &ray, &plane);

                    if (isect.hit) {
                        vec col;
                        ambient_occlusion(&col, &isect);

                        vadd(&fimg[y * w + x], fimg[y * w + x], col);
/*
                        fimg[y * w + x].x += col.x;
                        fimg[y * w + x].y += col.y;
                        fimg[y * w + x].z += col.z;
*/
                    }

                }
            }

            vdivs(&fimg[y * w + x], fimg[y * w + x], (float)(nsubsamples * nsubsamples));
/*
            fimg[y * w + x].x /= (float)(nsubsamples * nsubsamples);
            fimg[y * w + x].y /= (float)(nsubsamples * nsubsamples);
            fimg[y * w + x].z /= (float)(nsubsamples * nsubsamples);
*/
            img[comps * (y * w + x) + 0] = clamp(fimg[y * w + x].x);
            img[comps * (y * w + x) + 1] = clamp(fimg[y * w + x].y);
            img[comps * (y * w + x) + 2] = clamp(fimg[y * w + x].z);
        }
    }
}
コード例 #28
0
ファイル: thing.hpp プロジェクト: jckarter/BattleMints
 line(int flags, FILE *bin)
     : thing(LINE | flags, bin)
 {
     BATTLEMINTS_READ_SLOTS(*this, endpoint_a, endpoint_b, bin);
     normal = vperp(vnormalize(endpoint_b - endpoint_a));
 }
コード例 #29
0
void sph_model::draw(const double *P, const double *V, const int *fv, int fc,
                                                       const int *pv, int pc, float alpha)
{
    double M[16];
    
    mmultiply(M, P, V);

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixd(P);
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixd(V);
    
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindBuffer(GL_ARRAY_BUFFER, vertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, 0);

    for (int i = 15; i >= 0; --i)
    {
        glActiveTexture(GL_TEXTURE0 + i);
        glBindTexture(GL_TEXTURE_2D, cache.get_fill());
    }

    // This is a hack that ensures that the root pages of all files are touched.

    GLuint o;
    int tock;

    for (int i = 0; i < fc; ++i)
    {
        o = cache.get_page(fv[i], 0, time, tock);
        o = cache.get_page(fv[i], 1, time, tock);
        o = cache.get_page(fv[i], 2, time, tock);
        o = cache.get_page(fv[i], 3, time, tock);
        o = cache.get_page(fv[i], 4, time, tock);
        o = cache.get_page(fv[i], 5, time, tock);
    }
    for (int i = 0; i < pc; ++i)
    {
        o = cache.get_page(pv[i], 0, time, tock);
        o = cache.get_page(pv[i], 1, time, tock);
        o = cache.get_page(pv[i], 2, time, tock);
        o = cache.get_page(pv[i], 3, time, tock);
        o = cache.get_page(pv[i], 4, time, tock);
        o = cache.get_page(pv[i], 5, time, tock);
    }

#if 0
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
#endif

    glUseProgram(program);
    {
        glUniform1f(glGetUniformLocation(program, "zoomk"), zoomk);
	glUniform1f(glGetUniformLocation(program, "globalAlpha"), alpha);
        glUniform3f(glGetUniformLocation(program, "zoomv"),
                    zoomv[0], zoomv[1], zoomv[2]);

        for (int i = 0; i < 6; ++i)
        {
            double a[3], b[3], c[3], d[3];
            
            vnormalize(a, cube_v[cube_i[i][0]]);
            vnormalize(b, cube_v[cube_i[i][1]]);
            vnormalize(c, cube_v[cube_i[i][2]]);
            vnormalize(d, cube_v[cube_i[i][3]]);
            
            glUniform3f(pos_a, GLfloat(a[0]), GLfloat(a[1]), GLfloat(a[2]));
            glUniform3f(pos_b, GLfloat(b[0]), GLfloat(b[1]), GLfloat(b[2]));
            glUniform3f(pos_c, GLfloat(c[0]), GLfloat(c[1]), GLfloat(c[2]));
            glUniform3f(pos_d, GLfloat(d[0]), GLfloat(d[1]), GLfloat(d[2]));

            draw_face(fv, fc, pv, pc, 0, 1, 0, 1, 0, i);
        }
    }
    glUseProgram(0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER,         0);
    glDisableClientState(GL_VERTEX_ARRAY);

    glActiveTexture(GL_TEXTURE0);
}
コード例 #30
0
ファイル: ctr.cpp プロジェクト: anukat2015/ctr
void c_ctr::stochastic_learn_map_estimate(const c_data* users, const c_data* items, 
                               const c_corpus* c, const ctr_hyperparameter* param,
                               const char* directory) {
  // init model parameters
  printf("\nrunning stochastic learning ...\n");
  printf("initializing the model ...\n");
  init_model(param->ctr_run);

  // filename
  char name[500];

  // start time
  time_t start, current;
  time(&start);
  int elapsed = 0;

  int iter = 0;
  double likelihood = -exp(50), likelihood_old;
  double converge = 1.0;
  double learning_rate = param->learning_rate;

  /// create the state log file 
  sprintf(name, "%s/state.log", directory);
  FILE* file = fopen(name, "w");
  fprintf(file, "iter time likelihood converge\n");

  /* alloc auxiliary variables */
  gsl_vector* x  = gsl_vector_alloc(m_num_factors);

  gsl_matrix* phi = NULL;
  gsl_matrix* word_ss = NULL;
  gsl_matrix* log_beta = NULL;
  gsl_vector* gamma = NULL;

  if (param->ctr_run && param->theta_opt) {
    int max_len = c->max_corpus_length();
    phi = gsl_matrix_calloc(max_len, m_num_factors);
    word_ss = gsl_matrix_calloc(m_num_factors, c->m_size_vocab);
    log_beta = gsl_matrix_calloc(m_num_factors, c->m_size_vocab);
    gsl_matrix_memcpy(log_beta, m_beta);
    mtx_log(log_beta);
    gamma = gsl_vector_alloc(m_num_factors);
  }

  /* tmp variables for indexes */
  int i, j, m, n, l, k, ll, jj;
  int* item_ids; 
  bool positive = true;

  double result, inner;
  int active_num_items = 0;
  for (j = 0; j < m_num_items; ++j) {
    if (items->m_vec_len[j] > 0)
      active_num_items++; 
  }

  int* idx_base = new int[active_num_items];
  l = 0;
  for (j = 0; j < m_num_items; ++j) {
    if (items->m_vec_len[j] > 0) {
      idx_base[l] = j;
      ++l;
    }
  }
  int* sel = new int[active_num_items];

  while (iter < param->max_iter) {
    likelihood_old = likelihood;
    likelihood = 0.0;

    for (i = 0; i < m_num_users; ++i) {
      item_ids = users->m_vec_data[i];
      n = users->m_vec_len[i];
      if (n > 0) {
        double lambda_u = param->lambda_u / (2*n);
        gsl_vector_view u = gsl_matrix_row(m_U, i);
        // this user has rated some articles
        // Randomly choose 2*n negative examples
        sample_k_from_n(n, active_num_items, sel, idx_base);
        qsort(sel, n, sizeof(int), compare);
        l = 0; ll = 0;
        while (true) {
          if (l < n) {
            j = item_ids[l]; // positive
          } else {
            j = -1;
          }

          if (ll < n) { 
            jj = sel[ll]; //negative
            while (ll < n-1 && jj == sel[ll+1]) ++ll; // skip same values
          } else {
            jj = -1;
          }

          if (j == -1) {
            if (jj == -1) break;
            else {
              positive = false; // jj is a negative example
              ++ll;
            }
          } else {
            if (j < jj) {
              positive = true; // j is a positive example
              ++l; 
            } else if (j == jj) {
              positive = true; // j is a positive example
              ++l; 
              ++ll;
            } else {  // j > jj
              if (jj == -1) {
                positive = true; // j is a positive example
                ++l; 
              } else { 
                positive = false;
                ++ll;  // jj is a negative example
              }
            }
          }
          gsl_vector_view v;
          gsl_vector_view theta_v;
          double lambda_v = 0.0;
          if (positive) {
            // j is a positive example 
            lambda_v = param->lambda_v / (2 * items->m_vec_len[j]);
            v = gsl_matrix_row(m_V, j);
            theta_v = gsl_matrix_row(m_theta, j);
            // second-order
            // u
            gsl_vector_scale(&u.vector, 1 - learning_rate);
            gsl_blas_ddot(&v.vector, &v.vector, &inner);
            gsl_blas_daxpy(learning_rate / (lambda_u + inner), &v.vector, &u.vector);
            // v
            if (!param->lda_regression) {
              gsl_vector_scale(&v.vector, 1 - learning_rate);
              gsl_blas_daxpy(learning_rate, &theta_v.vector, &v.vector);
              gsl_blas_ddot(&u.vector, &u.vector, &inner);
              gsl_blas_ddot(&u.vector, &theta_v.vector, &result);
              gsl_blas_daxpy(learning_rate * (1.0 - result) / (lambda_v + inner), &u.vector, &v.vector);
            }

            gsl_blas_ddot(&u.vector, &v.vector, &result);
            likelihood += -0.5 * (1 - result) * (1 - result);
            // gsl_blas_ddot(&u.vector, &v.vector, &result);
            // result -= 1.0;
          } else {
            // jj is a negative example 
            lambda_v = param->lambda_v / (2 * items->m_vec_len[jj]);
            v = gsl_matrix_row(m_V, jj);
            theta_v = gsl_matrix_row(m_theta, jj);
            // second order
            // u
            gsl_vector_scale(&u.vector, 1 - learning_rate);

            // v
            if (!param->lda_regression) {
              gsl_vector_scale(&v.vector, 1 - learning_rate);
              gsl_blas_daxpy(learning_rate, &theta_v.vector, &v.vector);
              gsl_blas_ddot(&u.vector, &u.vector, &inner);
              gsl_blas_ddot(&u.vector, &theta_v.vector, &result);
              gsl_blas_daxpy(-learning_rate * result / (lambda_v + inner), &u.vector, &v.vector);
            }

            gsl_blas_ddot(&u.vector, &v.vector, &result);
            likelihood += -0.5 * result *  result;
            // gsl_blas_ddot(&u.vector, &v.vector, &result);
          }
          // update u
          // first-order 
         // gsl_vector_scale(&u.vector, 1 - param->learning_rate * lambda_u);
         // gsl_blas_daxpy(-result * param->learning_rate, &v.vector, &u.vector);
         // second order
          
          // update v
         // gsl_vector_scale(&v.vector, 1 - param->learning_rate * lambda_v);
         // gsl_blas_daxpy(-result * param->learning_rate, &u.vector, &v.vector);
         // gsl_blas_daxpy(param->learning_rate * lambda_v, &theta_v.vector, &v.vector);
        }
        assert(n == l && n == l);
        //printf("n=%d, l=%d, ll=%d,  j=%d,  jj=%d\n", n, l, ll, j, jj);

        // update the likelihood
        gsl_blas_ddot(&u.vector, &u.vector, &result);
        likelihood += -0.5 * param->lambda_u * result;
      }
    }

    for (j = 0; j < m_num_items; ++j) {
      gsl_vector_view v = gsl_matrix_row(m_V, j);
      gsl_vector_view theta_v = gsl_matrix_row(m_theta, j);
      gsl_vector_memcpy(x, &v.vector);
      gsl_vector_sub(x, &theta_v.vector);
      gsl_blas_ddot(x, x, &result);
      likelihood += -0.5 * param->lambda_v * result;
    }

    // update theta
    if (param->ctr_run && param->theta_opt) {
      gsl_matrix_set_zero(word_ss);
      for (j = 0; j < m_num_items; j ++) {
        gsl_vector_view v = gsl_matrix_row(m_V, j);
        gsl_vector_view theta_v = gsl_matrix_row(m_theta, j);
        m = items->m_vec_len[j];
        if (m>0) {
          // m > 0, some users have rated this article
          const c_document* doc =  c->m_docs[j];
          likelihood += doc_inference(doc, &theta_v.vector, log_beta, phi, gamma, word_ss, true); 
          optimize_simplex(gamma, &v.vector, param->lambda_v, &theta_v.vector); 
        }
        else {
        // m=0, this article has never been rated
          const c_document* doc =  c->m_docs[j];
          doc_inference(doc, &theta_v.vector, log_beta, phi, gamma, word_ss, false); 
          vnormalize(gamma);
          gsl_vector_memcpy(&theta_v.vector, gamma);
        }
      }
      gsl_matrix_memcpy(m_beta, word_ss);
      for (k = 0; k < m_num_factors; k ++) {
        gsl_vector_view row = gsl_matrix_row(m_beta, k);
        vnormalize(&row.vector);
      }
      gsl_matrix_memcpy(log_beta, m_beta);
      mtx_log(log_beta);
    }

    time(&current);
    elapsed = (int)difftime(current, start);

    iter++;
    if (iter > 50 && learning_rate > 0.001) learning_rate /= 2.0;
    converge = fabs((likelihood-likelihood_old)/likelihood_old);

    fprintf(file, "%04d %06d %10.5f %.10f\n", iter, elapsed, likelihood, converge);
    fflush(file);
    printf("iter=%04d, time=%06d, likelihood=%.5f, converge=%.10f\n", iter, elapsed, likelihood, converge);

    // save intermediate results
    if (iter % param->save_lag == 0) {

      sprintf(name, "%s/%04d-U.dat", directory, iter);
      FILE * file_U = fopen(name, "w");
      gsl_matrix_fwrite(file_U, m_U);
      fclose(file_U);

      sprintf(name, "%s/%04d-V.dat", directory, iter);
      FILE * file_V = fopen(name, "w");
      gsl_matrix_fwrite(file_V, m_V);
      fclose(file_V);

      if (param->ctr_run && param->theta_opt) { 
        sprintf(name, "%s/%04d-theta.dat", directory, iter);
        FILE * file_theta = fopen(name, "w");
        gsl_matrix_fwrite(file_theta, m_theta);
        fclose(file_theta);

        sprintf(name, "%s/%04d-beta.dat", directory, iter);
        FILE * file_beta = fopen(name, "w");
        gsl_matrix_fwrite(file_beta, m_beta);
        fclose(file_beta);
      }
    }
  }

  // save final results
  sprintf(name, "%s/final-U.dat", directory);
  FILE * file_U = fopen(name, "w");
  gsl_matrix_fwrite(file_U, m_U);
  fclose(file_U);

  sprintf(name, "%s/final-V.dat", directory);
  FILE * file_V = fopen(name, "w");
  gsl_matrix_fwrite(file_V, m_V);
  fclose(file_V);

  if (param->ctr_run && param->theta_opt) { 
    sprintf(name, "%s/final-theta.dat", directory);
    FILE * file_theta = fopen(name, "w");
    gsl_matrix_fwrite(file_theta, m_theta);
    fclose(file_theta);

    sprintf(name, "%s/final-beta.dat", directory);
    FILE * file_beta = fopen(name, "w");
    gsl_matrix_fwrite(file_beta, m_beta);
    fclose(file_beta);
  }

  // free memory
  gsl_vector_free(x);
  delete [] idx_base;
  delete [] sel;

  if (param->ctr_run && param->theta_opt) {
    gsl_matrix_free(phi);
    gsl_matrix_free(log_beta);
    gsl_matrix_free(word_ss);
    gsl_vector_free(gamma);
  }
}