Beispiel #1
0
/* Computes ambiant occlusion */
static void ga_shade_ao(vec_t *color, const ga_scene_t *s, const ga_material_t *mat, const vec_t *pos, const vec_t *norm, float importance){
	int sample = mat->ao_sample;
	float rlen,fact;
	vec_t ao_color = vec_new(0,0,0,1);
	vec_t dsample,d1,d2;
	vec_fperp(norm,&d1,&d2);
	while(sample--){
		dsample = vec_new(0,0,0,1);
		vec_ffadd(&dsample,random()*RAND_NORM,norm);
		vec_ffadd(&dsample,(2.0f*random()*RAND_NORM) -1.0f,&d1);
		vec_ffadd(&dsample,(2.0f*random()*RAND_NORM) -1.0f,&d2);
		vec_fnorm(&dsample);
		rlen = ga_ray_length(s,*pos,dsample);
		if (rlen <= mat->ao_min_dist){
			ao_color = vec_add(ao_color,mat->ao_min_color);
		}else if (rlen >= mat->ao_max_dist){
			ao_color = vec_add(ao_color,mat->ao_max_color);
		}else{
			fact = (rlen - mat->ao_min_dist) / (mat->ao_max_dist - mat->ao_min_dist) ;
			ao_color = vec_add(ao_color,
					vec_add(vec_scale(fact,mat->ao_max_color),
						vec_scale(1.0f-fact,mat->ao_min_color)));
		}
	}
	*color = vec_add(*color,
			vec_scale(1.0f/mat->ao_sample*mat->ao_factor,ao_color));
}
Beispiel #2
0
folgen_vektor_p
folgen_vektor_new(vec_p grad) {
	folgen_vektor_p  back;
	folge_p  *vektor;
	int  k, size, dim;
	vec_p  r, s;

	/*Testen auf Konsistenz*/
	dim = grad->dim;
	size = 1;
	for(k=0;k<dim;k++) {
		ASSERT( grad->array[k] >= 0 );
		size = size * (grad->array[k] + 1);
	}



	back = (folgen_vektor_p) malloc(sizeof(folgen_vektor_t));
	ASSERT(back != NULL);


	vektor = (folge_p*) malloc(sizeof(folge_p) * size);
	ASSERT(vektor != NULL);

	for(k=0;k<size;k++) {
		r = vec_new(dim);
		s = vec_new(dim);
		vektor[k] = folge_new( r, s);
	}
	back->vektor = vektor;
	back->grad = grad;

	return back;
}
Beispiel #3
0
//Brief: QR decomposition 
void qrdec(mat *A, mat* R){
    double proj = 0;
    double norm = 0;
    
    // Allocates pointers of type *vec 
    //vec *coli = (vec*)malloc(sizeof(vec));
    //vec *colj = (vec*)malloc(sizeof(vec));
    vec* coli = vec_new(A->row);
    vec* colj = vec_new(A->row);

    for(int i=0; i<A->col; i++){
	mat_get_col(coli, A, i);	
	norm = vec_norm(coli);
	mat_set(R, i, i, norm);
	vec_scale(coli, 1.0/norm);
	mat_set_col(A, coli, i);
	for(int j=i+1; j<A->col; j++){
	    mat_get_col(colj, A, j);
	    proj = vec_dot(coli,colj);
	    vec_add(colj,coli,-proj);
	    mat_set_col(A, colj, j);
	    mat_set(R, i, j, proj);
	}	
    }
    // Free pointers
    vec_free(coli);
    vec_free(colj);
}
Beispiel #4
0
int main()
{
  printf("%s\n", "testing sl_cons");
  sphere *s1 = sphere_new(vec_new(0.0, 0.0, 0.0), 10.0, rgb_new(0.5, 0.5, 0.5));
  sphere *s2 = sphere_new(vec_new(1.0, 1.0, 1.0), 5.0, rgb_new(0.1, 0.1, 0.1));
  sphere *s3 = sphere_new(vec_new(100.0, 100.0, 100.0), 100.0, rgb_new(0, 0, 0));

  sphere_list *sl = sl_cons(s1, sl_cons(s2, sl_cons(s3, NULL)));
  sl_print(sl);
  printf("%s\n", "testing sl_singleton");
  sphere_list *sl2 = sl_singleton(sphere_dup(s1));
  sl_print(sl2);
  sphere_list *sl3 = sl_cons(sphere_dup(s2), sl_singleton(sphere_dup(s1)));
  sl_print(sl3);

  printf("%s\n", "testing sl_dup");
  sphere_list *sl4 = sl_dup(sl);
  sl_print(sl4);


  printf("%s\n", "FOR VALGRIND TESTING");
  sl_free(sl);
  sl_free(sl2);
  sl_free(sl3);
  sl_free(sl4);
}
Beispiel #5
0
folge_p
folge_build(int dim, int a, int n, int mod, bool_t random) {
	vec_p  start, lang;
	int  k, size;
	fepc_real_t *glied;
	folge_p back;

	ASSERT(a>=0);
	ASSERT(n>0);
	start = vec_new(dim);
	lang = vec_new(dim);

	for(k=0;k<dim;k++) {
		if( random == true ) {
			start->array[k] = rand()%(2*a +1 ) - a;
			lang->array[k] = rand()%(n) +1;
		}
		else {
			start->array[k] = a;
			lang->array[k] = n;
		}
	}
	back = folge_new(start,lang);

	size = vec_size( lang );
	glied = back->glied;
	for (k=0;k<size;k++) {
		glied[k] = rand()%(2*mod+1) - mod;
	}

	return back;
}
Beispiel #6
0
/*-----------------------*\
 * BOX
\*-----------------------*/
box_t box_new(vec_t p, float width, float height){ 
	box_t b;
	b.pos = p;
	b.size = vec_abs(vec_new(width/2.0,height/2.0));
	b.axis0 = vec_new(1,0);
	b.axis1 = vec_new(0,1);
	return b;
}
Beispiel #7
0
static void init_env(void)
{
    opts.cpp_options = vec_new();
    opts.ld_options = vec_new();
#ifdef CONFIG_DARWIN
    opts.fleading_underscore = true;
#endif
    inputs = vec_new();
}
Beispiel #8
0
box_t box_bounds(box_t b) {
  vec_t corner = vec_add(vec_abs(vec_scale(b.axis0, b.size.x)), vec_abs(vec_scale(b.axis1, b.size.y)));
  box_t r;
  r.pos = b.pos;
  r.size = corner;
  r.axis0 = vec_new(corner.x, 0);
  r.axis1 = vec_new(0, corner.y);
  return r;
}
Beispiel #9
0
vec_t vec_project(vec_t a,vec_t b){
	float d = vec_dot(a,b);
	float l = b.x*b.x + b.y*b.y;
	if(l == 0.0){
		return vec_new(0,0);
	}else{
		d /= l;
		return vec_new(d*b.x, d*b.y);
	}
}
Beispiel #10
0
mat_t *mat_set_view(vec_t eye, vec_t u, vec_t v, vec_t w, mat_t *a){
	mat_t *b = mat_set_trans(vec_neg(eye),mat_new_zero());
	mat_set_row(0,u,a);
	mat_set_row(1,v,a);
	mat_set_row(2,w,a);
	mat_set_row(3,vec_new(0,0,0,1),a);
	mat_set_col(3,vec_new(0,0,0,1),a);
	mat_mult(a,b);
	mat_free(b);
	return a;
}
Beispiel #11
0
folgen_vektor_p
folgen_vektor_faltung(folgen_vektor_p f, folgen_matrix_p Gamma) {
	folgen_vektor_p  back;
	vec_p  vec_1, n_1, n_2, grad_1, grad_2, r, s;
	int  k, j, a, b;
	int  size_1, size_2, dim;
	folge_p  temp, temp1, sum;

	ASSERT( f->grad->dim == Gamma->grad1->dim );
	dim = f->grad->dim;
	vec_1 = vec_one(dim);

	grad_2 = vec_min( f->grad, Gamma->grad2 );
	n_2 = vec_add( grad_2, vec_1 );
	size_2 = vec_size( n_2 );

	grad_1 = vec_copy( Gamma->grad1 );
	n_1 = vec_add( grad_1, vec_1 );
	size_1 = vec_size( n_1 );

	back = folgen_vektor_new( grad_1 );
	for(k=0;k<size_1;k++) {
		sum = folge_new( vec_new(dim), vec_new(dim) );
		for(j=0;j<size_2;j++) {
			r = entry_one2d( j, n_2 );

			s = vec_add( f->grad, vec_1 );
			a = entry_d2one( r, s );
			vec_del( s );

			s = vec_add( Gamma->grad2, vec_1 );
			b = entry_d2one( r, s );
			vec_del( s );
			vec_del( r );

			temp = folge_faltung( f->vektor[a], Gamma->matrix[k][b] );
			temp1 = folge_add( sum, temp );
			folge_del( temp );
			folge_del( sum );

			sum = temp1;
		}
		folge_del( back->vektor[k] );
		back->vektor[k] = sum;
	}

	vec_del( n_1 );
	vec_del( n_2 );
	vec_del( grad_2 );
	vec_del( vec_1 );

	return back;
}
Beispiel #12
0
int startup_display(void)
{
    /* Initialize the host and tile config structures. */

    tile = vec_new(4, sizeof (struct tile));
    host = vec_new(4, sizeof (struct host));

    /* Initialize the default tile config. */

    default_tile.flags = 0;

    default_tile.o[0]  = DEFAULT_OX;
    default_tile.o[1]  = DEFAULT_OY;
    default_tile.o[2]  = DEFAULT_OZ;

    default_tile.r[0]  = DEFAULT_RX;
    default_tile.r[1]  = DEFAULT_RY;
    default_tile.r[2]  = DEFAULT_RZ;

    default_tile.u[0]  = DEFAULT_UX;
    default_tile.u[1]  = DEFAULT_UY;
    default_tile.u[2]  = DEFAULT_UZ;

    default_tile.win_x = default_tile.pix_x = DEFAULT_X;
    default_tile.win_y = default_tile.pix_y = DEFAULT_Y;
    default_tile.win_w = default_tile.pix_w = DEFAULT_W;
    default_tile.win_h = default_tile.pix_h = DEFAULT_H;

    default_tile.varrier_pitch = DEFAULT_VARRIER_PITCH;
    default_tile.varrier_angle = DEFAULT_VARRIER_ANGLE;
    default_tile.varrier_thick = DEFAULT_VARRIER_THICK;
    default_tile.varrier_shift = DEFAULT_VARRIER_SHIFT;
    default_tile.varrier_cycle = DEFAULT_VARRIER_CYCLE;

    default_tile.quality[0] = 1.0f;
    default_tile.quality[1] = 1.0f;

    /* Initialize the default host config. */

    current_host.flags = HOST_FRAMED;
    current_host.n     = 0;

    current_host.win_x = current_host.tot_x = DEFAULT_X;
    current_host.win_y = current_host.tot_y = DEFAULT_Y;
    current_host.win_w = current_host.tot_w = DEFAULT_W;
    current_host.win_h = current_host.tot_h = DEFAULT_H;

    if (tile && host)
        return 1;
    else
        return 0;
}
Beispiel #13
0
static void register_ship(void){
	particle_t*p;
	model_t *mod;
	material_t *mat;

	mod = model_load("data/ship.obj");
	
	mat = material_new();
	material_set_diffuse(mat,1,0,0,1.0);
	material_set_spec(mat,1,0.5,0.2,1.0);
	material_set_edge(mat,0.5,0,0,0.1);
	material_set_shininess(mat,50);
	material_enable(mat, DRAW_FACE | DRAW_EDGE);
	model_set_material(mod,1,mat);

	mat = material_new();
	material_set_diffuse(mat,0.8,0.8,0.8,1);
	material_set_spec(mat,0.8,0.8,0.8,1);
	material_set_shininess(mat,50);
	material_set_edge(mat,0,0,0,0.1);
	material_enable(mat, DRAW_FACE | DRAW_EDGE);
	model_set_material(mod,0,mat);

	mat = material_new();
	material_set_diffuse(mat,0,0,0,1);
	material_set_edge(mat,1,1,1,0.1);
	material_enable(mat, DRAW_FACE | DRAW_EDGE );
	model_set_material(mod,2,mat);


	p = particle_new(box_new(vec_new(0,0),40,32),0);
	p->draw = ship_draw;	
	p->move = particle_simple_move;
	p->action = ship_action;
	p->collide = ship_collide;
	p->vector[MISSILE] = vec_new(100,0);
	p->model[0] = mod;
	particle_set_color(p,1,0.3,0,0.1);
	particle_set_alt_color(p,1,0.5,0,0.5);
	particle_set_collides(p,1);
	particle_set_camera(p,1);
	particle_set_solid(p,1);
	particle_set_group(p,P_SHIP);
	particle_toggle_collide_group(p,P_SHIP);
	particle_toggle_collide_group(p,P_MISSILE);
	particle_set_nprop(p,SHIP_HSPEED,nprop_new(0,SHIP_ACCEL));
	particle_set_nprop(p,SHIP_VSPEED,nprop_new(0,SHIP_ACCEL));
	factory_register(p,P_SHIP);	
}
Beispiel #14
0
mat_t *mat_new(	float xx, float yx, float zx, float wx,
		float xy, float yy, float zy, float wy,
		float xz, float yz, float zz, float wz,
		float xw, float yw, float zw, float ww){
	mat_t *m = (mat_t*)malloc(sizeof(mat_t));
	if(m){
		m->x = vec_new(xx,yx,zx,wx);
		m->y = vec_new(xy,yy,zy,wy);
		m->z = vec_new(xz,yz,zz,wz); 
		m->w = vec_new(xw,yw,zw,ww);
	}else{
		error_at_line(1,0,__FILE__,__LINE__,"not enough memory\n");
	}
	return m;
}
Beispiel #15
0
void SMat<CoeffRing>::vec_set_entry(sparsevec *&v,
                                    size_t r,
                                    const elem &a) const
{
  sparsevec *p;
  bool iszero = ring().is_zero(a);
  sparsevec head;
  head.next = v;
  for (p = &head; p->next != 0; p = p->next)
    if (p->next->row <= r) break;

  if (p->next == 0 || p->next->row < r)
    {
      if (iszero) return;
      sparsevec *w = vec_new();
      w->next = p->next;
      w->row = r;
      ring().init_set(w->coeff, a);
      p->next = w;
    }
  else if (p->next->row == r)
    {
      if (iszero)
        {
          // delete node
          sparsevec *tmp = p->next;
          p->next = tmp->next;
          vec_remove_node(tmp);
        }
      else
        ring().set(p->next->coeff, a);
    }
  v = head.next;
}
Beispiel #16
0
folgen_vektor_p
folgen_vektor_build(vec_p p, int a, int n, int mod, bool_t random) {
	vec_p  grad;
	int  dim, k, size;
	folgen_vektor_p  back;

	
	dim = p->dim;
	for(k=0;k<dim;k++) {
		ASSERT( p->array[k] >= 0 );
	}

	grad = vec_new(dim);
	for(k=0;k<dim;k++) {
		if(random == true) {
			grad->array[k] = rand()%(p->array[k] + 1);
		}
		else {
			grad->array[k] = p->array[k];
		}
	}

	back = folgen_vektor_new(grad);
	size = 1;
	for(k=0;k<dim;k++){
		size = size * (grad->array[k] + 1);
	}

	for(k=0;k<size;k++) {
		folge_del(back->vektor[k]);
		back->vektor[k] = folge_build( dim, a, n, mod, random );
	}

	return back;
}
Beispiel #17
0
struct pnode *
PP_mknnode(double number)
{
    struct pnode *p;
    struct dvec *v;

    /* We don't use printnum because it screws up PP_mkfnode above. We have
     * to be careful to deal properly with node numbers that are quite
     * large...
     */
    v = dvec_alloc(number < MAXPOSINT
                   ? tprintf("%d", (int) number)
                   : tprintf("%G", number),
                   SV_NOTYPE,
                   VF_REAL,
                   1, NULL);

    v->v_realdata[0] = number;

    vec_new(v);

    p = alloc_pnode();
    p->pn_value = v;
    return (p);
}
Beispiel #18
0
struct entity_func *startup_terrain(void)
{
    if ((terrain = vec_new(MIN_TERRAINS, sizeof (struct terrain))))
        return &terrain_func;
    else
        return NULL;
}
Beispiel #19
0
Vector *mat_get_row(Matrix *m, int row) {
  int j;
  Vector *v = vec_new(m->ncols);
  for (j = 0; j < m->ncols; j++)
    v->data[j] = m->data[row][j];
  return v;
}
Beispiel #20
0
Vector *mat_get_col(Matrix *m, int col) {
  int i;
  Vector *v = vec_new(m->nrows);
  for (i = 0; i < m->nrows; i++)
    v->data[i] = m->data[i][col];
  return v;
}
Beispiel #21
0
static int translate(const char *ifile, const char *ofile)
{
    struct vector *v = vec_new();
    vec_push(v, (char *)ifile);
    vec_push_safe(v, (char *)ofile);
    return runproc(program, v);
}
Beispiel #22
0
void
lincopy(struct dvec *ov, double *newscale, int newlen, struct dvec *oldscale)
{
    struct dvec *v;
    double *nd;

    if (!isreal(ov)) {
        fprintf(cp_err, "Warning: %s is not real\n", ov->v_name);
        return;
    }
    if (ov->v_length < oldscale->v_length) {
        fprintf(cp_err, "Warning: %s is too short\n", ov->v_name);
        return;
    }
    v = alloc(struct dvec);
    v->v_name = copy(ov->v_name);
    v->v_type = ov->v_type;
    v->v_flags = ov->v_flags;
    v->v_flags |= VF_PERMANENT;
    v->v_length = newlen;

    nd = (double *) tmalloc(newlen * sizeof (double));
    if (!ft_interpolate(ov->v_realdata, nd, oldscale->v_realdata,
            oldscale->v_length, newscale, newlen, 1)) {
        fprintf(cp_err, "Error: can't interpolate %s\n", ov->v_name);
        return;
    }
    v->v_realdata = nd;
    vec_new(v);
    return;
}
Beispiel #23
0
vec_t vec_rotate(vec_t a, float angle){
	float sina = sinf(RADIAN(angle));
	float cosa = cosf(RADIAN(angle));
	return vec_new(	a.x*cosa - a.y*sina ,
			a.x*sina + a.y*cosa  );

}
Beispiel #24
0
vec_t box_intersect_vector(box_t a, box_t b){
	vec_t d = vec_diff(a.pos, b.pos);
	vec_t r = vec_new(0,0);
	if (d.x >= 0){
		r.x = (b.pos.x - b.size.x) - (a.pos.x + a.size.x);
		if ( r.x > 0)
			r.x = 0;
	}else{
		r.x =  (b.pos.x + b.size.x) - (a.pos.x - a.size.x);
		if (r.x < 0)
			r.x = 0;
	}
	if (d.y >= 0){
		r.y = (b.pos.y - b.size.y) - (a.pos.y + a.size.y);
		if ( r.y > 0)
			r.y = 0;
	}else{
		r.y =  (b.pos.y + b.size.y) - (a.pos.y - a.size.y);
		if (r.y < 0)
			r.y = 0;
	}
	d = vec_abs(r);
	if(d.x > d.y){
		r.x = 0;
	}else{
		r.y = 0;
	}
	return r;
}
Beispiel #25
0
/* estimate free parameters */
double bd_estimate_transitions(BDPhyloHmm *bdphmm, MSA *msa) {
  int i, nparams = 0;
  Vector *params, *lb, *ub;
  double retval;

  if (bdphmm->phmm->forward == NULL) {
    bdphmm->phmm->forward = smalloc(bdphmm->phmm->hmm->nstates * 
                                    sizeof(double*));
    for (i = 0; i < bdphmm->phmm->hmm->nstates; i++)
      bdphmm->phmm->forward[i] = smalloc(bdphmm->phmm->alloc_len * 
                                         sizeof(double));
  }

  if (bdphmm->estim_omega) nparams++;
  if (bdphmm->estim_gamma) nparams++;
  if (bdphmm->estim_phi) nparams++;

  params = vec_new(nparams);
  lb = vec_new(nparams);
  ub = vec_new(nparams);
  vec_set_all(lb, 1e-6);

  nparams = 0;
  if (bdphmm->estim_omega) {
    vec_set(params, nparams, 1/bdphmm->mu);
    vec_set(ub, nparams++, INFTY);
  }
  if (bdphmm->estim_gamma) {
    vec_set(params, nparams, bdphmm->nu / (bdphmm->mu + bdphmm->nu));
    vec_set(ub, nparams++, 0.5 /* 1-1e-6 */);
  }
  if (bdphmm->estim_phi) {
    vec_set(params, nparams, bdphmm->phi);
    vec_set(ub, nparams++, 0.7 /* 1-1e-6 */);
  }

  opt_bfgs(lnl_wrapper, params, bdphmm, &retval, lb, ub, stderr, NULL, 
           OPT_HIGH_PREC, NULL, NULL);

  unpack_params(params, bdphmm);

  vec_free(params);
  vec_free(lb);
  vec_free(ub);

  return retval;
}
Beispiel #26
0
vec_t vec_norm(vec_t a){
	float len = vec_len(a);
	if(len == 0.0f){
		return vec_new(1.0f,0.0f,0.0f,0.0f);
	}else{
		return vec_scale(1.0f/len,a);
	}
}
Beispiel #27
0
static void fields(node_t * sym)
{
    int follow[] = {INT, CONST, '}', IF, 0};
    node_t *sty = SYM_TYPE(sym);

    if (!first_decl(token)) {
        error("expect type name or qualifiers");
        return;
    }

    struct vector *v = vec_new();
    do {
        node_t *basety = specifiers(NULL, NULL);

        for (;;) {
            node_t *field = new_field();
            if (token->id == ':') {
                bitfield(field);
                FIELD_TYPE(field) = basety;
            } else {
                node_t *ty = NULL;
                struct token *id = NULL;
                declarator(&ty, &id, NULL);
                attach_type(&ty, basety);
                if (token->id == ':')
                    bitfield(field);
                FIELD_TYPE(field) = ty;
                if (id) {
                    for (int i = 0; i < vec_len(v); i++) {
                        node_t *f = vec_at(v, i);
                        if (FIELD_NAME(f) &&
                                !strcmp(FIELD_NAME(f), id->name)) {
                            errorf(id->src,
                                   "redefinition of '%s'",
                                   id->name);
                            break;
                        }
                    }
                    FIELD_NAME(field) = id->name;
                    AST_SRC(field) = id->src;
                }
            }

            vec_push(v, field);
            if (token->id != ',')
                break;
            expect(',');
            ensure_field(field, vec_len(v), false);
        }

        match(';', follow);
        ensure_field(vec_tail(v), vec_len(v),
                     isstruct(sty) && !first_decl(token));
    } while (first_decl(token));

    TYPE_FIELDS(sty) = (node_t **) vtoa(v);
    set_typesize(sty);
}
Beispiel #28
0
folgen_matrix_p
folgen_matrix_new(vec_p grad1, vec_p grad2) {
	folgen_matrix_p  back;
	folge_p  **matrix;
	int  i, j, size1, size2, dim;
	vec_p  r, s;

	/*Testen auf Konsistenz*/
	ASSERT(grad1->dim == grad2->dim);
	dim = grad1->dim;
	size1 = 1;
	for(i=0;i<dim;i++) {
		ASSERT( grad1->array[i] >= 0 );
		size1 = size1 * (grad1->array[i] + 1);
	}
	size2 = 1;
	for(i=0;i<dim;i++) {
		ASSERT( grad2->array[i] >= 0 );
		size2 = size2 * (grad2->array[i] + 1);
	}


	back = (folgen_matrix_p) malloc(sizeof(folgen_matrix_t));
	ASSERT(back != NULL);
	matrix = (folge_p**) malloc(sizeof(folge_p*) * size1);
	ASSERT(matrix != NULL);

	matrix[0] = (folge_p*) malloc(sizeof(folge_p) * size1 * size2);
	for(i=0;i<size1;i++) {
		matrix[i] = matrix[0] + i * size2;
	}

	for(i=0;i<size1;i++) {
		for(j=0;j<size2;j++) {
			r = vec_new(dim);
			s = vec_new(dim);
			matrix[i][j] = folge_new( r, s);
		}
	}
	back->matrix = matrix;
	back->grad1 = grad1;
	back->grad2 = grad2;

	return back;
}
Beispiel #29
0
vec_t vec_new_set(int d, double val) {
    vec_t v = vec_new(d);
    int i;

    for (i = 0; i < d; i++)
        Vn(v, i) = val;
    
    return v;
}
Beispiel #30
0
int main(int argc, char *argv[]) {
  char c;
  int opt_idx;
  Vector *newfreqs = vec_new(4);
  TreeModel *mod;

  struct option long_opts[] = {
    {"help", 0, 0, 'h'},
    {0, 0, 0, 0}
  };

  while ((c = getopt_long(argc, argv, "h", long_opts, &opt_idx)) != -1) {
    switch (c) {
    case 'h':
      printf("%s", HELP);
      exit(0);
    case '?':
      die("Bad argument.  Try 'modFreqs -h'.\n");
    }
  }

  if (optind != argc - 2 && optind != argc - 5) 
    die("ERROR: Wrong number of arguments.  Try 'modFreqs -h'.\n");

  set_seed(-1);

  mod = tm_new_from_file(phast_fopen(argv[optind], "r"), 1);

  if (!tm_is_reversible(mod)) 
    die("ERROR: reversible input model required.\n");
  if (mod->order != 0)
    die("ERROR: single nucleotide model required.\n");
  if (strcmp(mod->rate_matrix->states, DEFAULT_ALPHABET) != 0)
    die("ERROR: default nucleotide alphabet required.\n");

  if (optind == argc - 2) {
    double gc = get_arg_dbl_bounds(argv[optind+1], 0, 1);
    vec_set(newfreqs, 0, (1-gc)/2);
    vec_set(newfreqs, 1, gc/2);
    vec_set(newfreqs, 2, gc/2);
    vec_set(newfreqs, 3, (1-gc)/2);
  }
  else {
    vec_set(newfreqs, 0, get_arg_dbl_bounds(argv[optind+1], 0, 1));
    vec_set(newfreqs, 1, get_arg_dbl_bounds(argv[optind+2], 0, 1));
    vec_set(newfreqs, 2, get_arg_dbl_bounds(argv[optind+3], 0, 1));
    vec_set(newfreqs, 3, get_arg_dbl_bounds(argv[optind+4], 0, 1));
    pv_normalize(newfreqs);
  }

  tm_mod_freqs(mod, newfreqs);

  tm_print(stdout, mod);

  return 0;
}