Ejemplo n.º 1
0
Archivo: layout.c Proyecto: ekg/mars
mat mars(Agraph_t* g, struct marsopts opts)
{
    int i, j, n = agnnodes(g), k = MIN(n, MAX(opts.k, 2)), iter = 0;
    mat dij, u, u_trans, q, r, q_t, tmp, tmp2, z;
    double* s = (double*) malloc(sizeof(double)*k);
    double* ones = (double*) malloc(sizeof(double)*n);
    double* d;
    int* anchors = (int*) malloc(sizeof(int)*k);
    int* clusters = NULL;
    double change = 1, old_stress = -1;
    dij = mat_new(k, n);
    u = mat_new(n,k);
    tmp = mat_new(n,k);
    darrset(ones,n,-1);
    
    select_anchors(g, dij, anchors, k);
    if(opts.color) {
        for(i = 0; i < k; i++) {
            Agnode_t* anchor = get_node(anchors[i]);
            agset(anchor, "color", "red");
        }
    }
    if(opts.power != 1) {
        clusters = graph_cluster(g,dij,anchors);
    }

    singular_vectors(g, dij, opts.power, u, s);
    vec_scalar_mult(s, k, -1);
    u_trans = mat_trans(u);
    d = mat_mult_for_d(u, s, u_trans, ones);
    for(i = 0; i < u->c; i++) {
        double* col = mat_col(u,i);
        double* b = inv_mul_ax(d,col,u->r);
        for(j = 0; j < u->r; j++) {
            tmp->m[mindex(j,i,tmp)] = b[j];     
        }
        free(b);
        free(col);
    }
    tmp2 = mat_mult(u_trans,tmp);
    for(i = 0; i < k; i++) {
        tmp2->m[mindex(i,i,tmp2)] += (1.0/s[i]);
    }
    q = mat_new(tmp2->r, tmp2->c);
    r = mat_new(tmp2->c, tmp2->c);
    qr_factorize(tmp2,q,r);
    q_t = mat_trans(q);

    if(opts.given) {
        z = get_positions(g, opts.dim);
    } else {
        z = mat_rand(n, opts.dim);
    }
    translate_by_centroid(z);
   
    if(opts.viewer) {
        init_viewer(g, opts.max_iter);
        append_layout(z);
    }
     
    old_stress = stress(z, dij, anchors, opts.power);
    while(change > EPSILON && iter < opts.max_iter) {
        mat right_side;
        double new_stress;
        
        if(opts.power == 1) {
            right_side = barnes_hut(z);
        } else {
            right_side = barnes_hut_cluster(z, dij, clusters, opts.power);
        }
        for(i = 0; i < opts.dim; i++) {
            double sum = 0;         
            double* x;
            double* b = mat_col(right_side,i);
            for(j = 0; j < right_side->r; j++) {
                sum += b[j];
            }
            x = inv_mul_full(d, b, right_side->r, u, u_trans, q_t, r);
            for(j = 0; j < z->r; j++) {
                z->m[mindex(j,i,z)] = x[j] - sum/right_side->r;
            }
            free(x);
            free(b);
        }
        
        adjust_anchors(g, anchors, k, z);
        update_anchors(z, dij, anchors, opts.power);
        translate_by_centroid(z);
   
        if(opts.viewer) {
            append_layout(z);
        }
         
        new_stress = stress(z, dij, anchors, opts.power);
        change = fabs(new_stress-old_stress)/old_stress;
        old_stress = new_stress;
        
        mat_free(right_side);
        iter++;
    }
    
    mat_free(dij);
    mat_free(u);
    mat_free(u_trans);
    mat_free(q);
    mat_free(r);
    mat_free(q_t);
    mat_free(tmp);
    mat_free(tmp2);
    free(s);
    free(ones);
    free(d);
    free(anchors);
    free(clusters);
    
    return z;
}
Ejemplo n.º 2
0
void run_dla(params p) {
	time_t start, now;
	FILE *fp;

	fp = fopen(p.output_filename, "w");
	if (fp == NULL) {
		fprintf(stderr,"ERROR: could not open output file '%s'\n",
			p.output_filename);
		exit(EXIT_FAILURE);
	}

	if(KDT_DIM == 2) {
		fprintf(fp,"n x y\n");
	}
	else if(KDT_DIM == 3) {
		fprintf(fp,"n x y z\n");
	}
	else {
		fprintf(stderr, "DLA not defined for KDT_DIM=%d\n", KDT_DIM);
		exit(1);
	}

	setuprandom(p.seed);

	// setup initial world conditions
	point_list *buffer = kdt_new_point_list(p.n);
	tree_node *root = kdt_new_tree();
	point *zero = (point *)malloc(sizeof(point));
	vec_zero(zero);
	kdt_add_point(root, zero);
	double curr_max_radius = 0.0f;	
	double starting_rad = starting_radius(p.min_inner_radius, curr_max_radius, p.inner_mult, p.step_size);
	double death_rad = death_radius(p.min_inner_radius, curr_max_radius, p.inner_mult, p.step_size, p.outer_mult);

	time(&start);
	time(&now);
	int i;
	for(i=0; i < p.n && (now - start) < p.max_secs; i++) {
		if(i % (p.n / 10) == 0 && p.log_progress == 1) {
			log_progress((double)i / (double)p.n * 100.0f, curr_max_radius, starting_rad, kdt_max_depth(root));
		}
		point dir, end, col;
		point *pt = (point *)malloc(sizeof(point));
		vec_rand_unit(pt);
		vec_scalar_mult(pt, pt, starting_rad);
		int walking = 1;
		while(walking) {
			vec_rand_unit(&dir);
			vec_scalar_mult(&dir, &dir, p.step_size);
			vec_add(&end, pt, &dir);
			if(kdt_collision_detect(root, pt, &end, &col, p.epsilon, buffer) && sticks(p.stickiness)) {
				vec_copy(pt, &col);
				kdt_add_point(root, pt);
				double pt_radius = vec_length(pt);
				if(pt_radius > curr_max_radius) {
					curr_max_radius = pt_radius;
					starting_rad = starting_radius(p.min_inner_radius, curr_max_radius, p.inner_mult, p.step_size);
					death_rad = death_radius(p.min_inner_radius, curr_max_radius, p.inner_mult, p.step_size, p.outer_mult);
				}
				walking = 0;
			} 
			else {
				vec_copy(pt, &end);
				if(vec_length(pt) >= death_rad) {
					// if we have moved outside the max radius, start over
					vec_rand_unit(pt);
					vec_scalar_mult(pt, pt, starting_rad);
				}
			}
		}
		print_point(fp, i, pt);
		time(&now);
	}
	if (p.log_progress == 1) {
		log_progress((double)i / (double)p.n * 100.0f, curr_max_radius, 
			starting_rad, kdt_max_depth(root));
	}
	fclose(fp);
}