예제 #1
0
pcover expand(pset_family F, pset_family R, int nonsparse)
               
            
                                /* expand non-sparse variables only */
{
    register pcube last, p;
    pcube RAISE, FREESET, INIT_LOWER, SUPER_CUBE, OVEREXPANDED_CUBE;
    int var, num_covered;
    bool change;

    /* Order the cubes according to "chewing-away from the edges" of mini */
    if (use_random_order)
	F = random_order(F);
    else
	F = mini_sort(F, (qsort_compare_func) ascend);

    /* Allocate memory for variables needed by expand1() */
    RAISE = new_cube();
    FREESET = new_cube();
    INIT_LOWER = new_cube();
    SUPER_CUBE = new_cube();
    OVEREXPANDED_CUBE = new_cube();

    /* Setup the initial lowering set (differs only for nonsparse) */
    if (nonsparse)
	for(var = 0; var < cube.num_vars; var++)
	    if (cube.sparse[var])
		(void) set_or(INIT_LOWER, INIT_LOWER, cube.var_mask[var]);

    /* Mark all cubes as not covered, and maybe essential */
    foreach_set(F, last, p) {
	RESET(p, COVERED);
	RESET(p, NONESSEN);
    }
예제 #2
0
/* else return FALSE.                                 */
bool
Is_Any_Connect(pcover WSS, pcover P)
{
	register int i, ind;
	register pset q, x=new_cube(), r=new_cube();
	int pos_p;
	
	foreachi_set(P, i, q){
		ind = Get_Var_Ind(q, 0);
		set_copy(x, GETSET(WSS, ind));
		set_diff(r, x, q);
		if (!setp_empty(r))
			return TRUE;
	}
예제 #3
0
/* Update the P to newP and they have the same cube sequence */
void
Update_Partition(pcover newP, pcover P, pset x, pset q, int pos_q)
{
	register pset r, tt=set_save(x), tmp=new_cube();
	register int i, first_pos;
	
	/* The merge cube */
	set_insert(tt, pos_q);
	
	/* Let the first variable of the merge cube is positive */
	first_pos = Get_Var_Pos(tt, 0);
	if ((first_pos % 2) == 0)
		sf_addset(newP, set_save(tt));
	else
		sf_addset(newP, Var_Phase_Inv(tt));
	free_cube(tt);
	
	
	/* Add the other inputs sequently */
	foreachi_set(P, i, r){
		if (set_andp(tmp, r, x)) continue;
		if (set_andp(tmp, r, q)) continue;
		
		sf_addset(newP, r);
	}
	
	free_cube(tmp);
}
예제 #4
0
void 
menger( voxelmap_t* V, glm::ivec3 size, glm::ivec3 cube, glm::ivec3 offset ) {
    uint32_t step = cube.x / 3;
    if( step < 1 )
        return;
    for( size_t x =0; x < 3; x++ )
        for( size_t y =0; y < 3; y++ )
            for( size_t z =0; z < 3; z++ ) {
                if( size.x == cube.x )
                    printf( "[%zu]\n", x*y*z );
                glm::ivec3 offs = offset + glm::ivec3( x * step, y * step, z * step );
                glm::ivec3 new_cube( step, step, step );
                // middle element
                if( ( z == 1 && ( y == 1 || x == 1 ) )
                    || ( x == 1 && y == 1 ) ) {
                   // #pragma omp parallel for
                    for( size_t i = offs.x; i < offs.x + step; i++ )
                        for( size_t j = offs.y; j < offs.y + step; j++ )
                            for( size_t k = offs.z; k < offs.z + step; k++ ) {
                                //glm::vec4 color =voxelmapUnpack( V, ivec3_32(i,j,k ) );
                                //color.a =0.f;
                                //voxelmapPack(  V, ivec3_32( i, j, k ), color );
                                voxelmapPack(  V, ivec3_32( i, j, k ), glm::vec4(0) );
                                //((uint32_t*)V->data)[size.x * size.y * k + size.x * j + i] &= ~(uint32_t)0xff;
                            }
                }
                // corner element, expand recursively
                else
                    menger( V, size, new_cube, offs );
            }
}
예제 #5
0
파일: cofactor.c 프로젝트: spl/ivy
/* cofactor -- compute the cofactor of a cover with respect to a cube */
pcube *cofactor(pset *T, register pset c)
{
    pcube temp = cube.temp[0], *Tc_save, *Tc, *T1;
    register pcube p;
    int listlen;

    listlen = CUBELISTSIZE(T) + 5;

    /* Allocate a new list of cube pointers (max size is previous size) */
    Tc_save = Tc = ALLOC(pcube, listlen);

    /* pass on which variables have been cofactored against */
    *Tc++ = set_or(new_cube(), T[0], set_diff(temp, cube.fullset, c));
    Tc++;

    /* Loop for each cube in the list, determine suitability, and save */
    for(T1 = T+2; (p = *T1++) != NULL; ) {
	if (p != c) {

#ifdef NO_INLINE
	if (! cdist0(p, c)) goto false;
#else
    {register int w,last;register unsigned int x;if((last=cube.inword)!=-1)
    {x=p[last]&c[last];if(~(x|x>>1)&cube.inmask)goto false;for(w=1;w<last;w++)
    {x=p[w]&c[w];if(~(x|x>>1)&DISJOINT)goto false;}}}{register int w,var,last;
    register pcube mask;for(var=cube.num_binary_vars;var<cube.num_vars;var++){
    mask=cube.var_mask[var];last=cube.last_word[var];for(w=cube.first_word[var
    ];w<=last;w++)if(p[w]&c[w]&mask[w])goto nextvar;goto false;nextvar:;}}
#endif

	    *Tc++ = p;
	false: ;
	}
    }
예제 #6
0
 void update(int frame) {
     if( frame % 3 == 1 ) new_cube();
     for( int i = 0; i < MAX_SIZE; ++i ) {
         if( cubes[i] ) {
             cubes[i]->update(i);
         }
     }
 }
예제 #7
0
cube_list* negate_cube(cube* c, int var) {
  cube_list* result = new_cube_list(var);

  for (int i = 1; i <= var; i++) {
    val value = c->values[i];

    if (value == t) {
      cube* cn = new_cube(var);
      set_false(cn, i);
      add_cube(result, cn);
    } else if (value == f) {
      cube* cn = new_cube(var);
      set_true(cn, i);
      add_cube(result, cn);
    }
  }

  return result;
}
예제 #8
0
파일: compl.c 프로젝트: spl/ivy
/* complement -- compute the complement of T */
pcover complement(pset *T)
         			/* T will be disposed of */
{
    register pcube cl, cr;
    register int best;
    pcover Tbar, Tl, Tr;
    int lifting;
    static int compl_level = 0;

    if (debug & COMPL)
	debug_print(T, "COMPLEMENT", compl_level++);

    T = compl_special_cases(T, &Tbar);
    if (T != NULL){

	/* Allocate space for the partition cubes */
	cl = new_cube();
	cr = new_cube();
	best = binate_split_select(T, cl, cr, COMPL);

	/* Complement the left and right halves */
	Tl = complement(scofactor(T, cl, best));
	Tr = complement(scofactor(T, cr, best));

	if (Tr->count*Tl->count > (Tr->count+Tl->count)*CUBELISTSIZE(T)) {
	    lifting = USE_COMPL_LIFT_ONSET;
	} else {
	    lifting = USE_COMPL_LIFT;
	}
	Tbar = compl_merge(T, Tl, Tr, cl, cr, best, lifting);

	free_cube(cl);
	free_cube(cr);
	free_cubelist(T);
    }

    if (debug & COMPL)
	debug1_print(Tbar, "exit COMPLEMENT", --compl_level);
        
    return Tbar;
}
예제 #9
0
/*
    cube_setup -- assume that the fields "num_vars", "num_binary_vars", and
    part_size[num_binary_vars .. num_vars-1] are setup, and initialize the
    rest of cube and cdata.

    If a part_size is < 0, then the field size is abs(part_size) and the
    field read from the input is symbolic.
*/
void cube_setup()
{
    register int i, var;
    register pcube p;

    if (cube.num_binary_vars < 0 || cube.num_vars < cube.num_binary_vars)
	fatal("cube size is silly, error in .i/.o or .mv");

    cube.num_mv_vars = cube.num_vars - cube.num_binary_vars;
    cube.output = cube.num_mv_vars > 0 ? cube.num_vars - 1 : -1;

    cube.size = 0;
    cube.first_part = ALLOC(int, cube.num_vars);
    cube.last_part = ALLOC(int, cube.num_vars);
    cube.first_word = ALLOC(int, cube.num_vars);
    cube.last_word = ALLOC(int, cube.num_vars);
    for(var = 0; var < cube.num_vars; var++) {
	if (var < cube.num_binary_vars)
	    cube.part_size[var] = 2;
	cube.first_part[var] = cube.size;
	cube.first_word[var] = WHICH_WORD(cube.size);
	cube.size += ABS(cube.part_size[var]);
	cube.last_part[var] = cube.size - 1;
	cube.last_word[var] = WHICH_WORD(cube.size - 1);
    }

    cube.var_mask = ALLOC(pset, cube.num_vars);
    cube.sparse = ALLOC(int, cube.num_vars);
    cube.binary_mask = new_cube();
    cube.mv_mask = new_cube();
    for(var = 0; var < cube.num_vars; var++) {
	p = cube.var_mask[var] = new_cube();
	for(i = cube.first_part[var]; i <= cube.last_part[var]; i++)
	    set_insert(p, i);
	if (var < cube.num_binary_vars) {
	    INLINEset_or(cube.binary_mask, cube.binary_mask, p);
	    cube.sparse[var] = 0;
	} else {
	    INLINEset_or(cube.mv_mask, cube.mv_mask, p);
	    cube.sparse[var] = 1;
	}
    }
    if (cube.num_binary_vars == 0)
	cube.inword = -1;
    else {
	cube.inword = cube.last_word[cube.num_binary_vars - 1];
	cube.inmask = cube.binary_mask[cube.inword] & DISJOINT;
    }

    cube.temp = ALLOC(pset, CUBE_TEMP);
    for(i = 0; i < CUBE_TEMP; i++)
	cube.temp[i] = new_cube();
    cube.fullset = set_fill(new_cube(), cube.size);
    cube.emptyset = new_cube();

    cdata.part_zeros = ALLOC(int, cube.size);
    cdata.var_zeros = ALLOC(int, cube.num_vars);
    cdata.parts_active = ALLOC(int, cube.num_vars);
    cdata.is_unate = ALLOC(int, cube.num_vars);
}
예제 #10
0
bool
Is_Group_Connect(pcover WSS, pset group, pset inp, int *inp_ind)
{
	register pset r=new_cube(), mask=new_cube();
	register int ind;
	register bool result;
	
	ind = Get_Var_Ind(group, 0);
	Generate_Mask(mask, inp);
	
	if (set_andp(r, mask, GETSET(WSS, ind)))
		result = TRUE;
	else
		result = FALSE;
	
	*inp_ind = Get_Var_Pos(r, 0);
	
	free_cube(r);
	free_cube(mask);
	
	return result;
}
예제 #11
0
/* primes_consensus -- generate primes using consensus */
pcover primes_consensus(pset *T)
  /* T will be disposed of */
{
  register pcube cl, cr;
  register int best;
  pcover Tnew, Tl, Tr;

  if (primes_consensus_special_cases(T, &Tnew) == MAYBE) {
    cl = new_cube();
    cr = new_cube();
    best = binate_split_select(T, cl, cr, COMPL);

    Tl = primes_consensus(scofactor(T, cl, best));
    Tr = primes_consensus(scofactor(T, cr, best));
    Tnew = primes_consensus_merge(Tl, Tr, cl, cr);

    free_cube(cl);
    free_cube(cr);
    free_cubelist(T);
  }

  return Tnew;
}
예제 #12
0
bfun* try_simplify(bfun* b) {
  bfun* result = NULL;

  if (b->cube_count == 0) { // empty cubelist is never true -> change to true bfun
    result = new_cube_list(b->var_count);
    add_cube(result, new_cube(b->var_count));
  } else if (has_all_dc(b)) { // always true -> change to empty (false) bfun
    result = new_cube_list(b->var_count); 
  } else if (b->cube_count == 1) { // just one cube -> negate manually
    result = negate_cube(b->begin, b->var_count);
  }

  if (result == NULL) return b;
  return result;
}
예제 #13
0
static bool
primes_consensus_special_cases(pset *T, pset_family *Tnew)
  /* will be disposed if answer is determined */
  /* returned only if answer determined */
{
  register pcube *T1, p, ceil, cof=T[0];
  pcube last;
  pcover A;

  /* Check for no cubes in the cover */
  if (T[2] == NULL) {
    *Tnew = new_cover(0);
    free_cubelist(T);
    return TRUE;
  }

  /* Check for only a single cube in the cover */
  if (T[3] == NULL) {
    *Tnew = sf_addset(new_cover(1), set_or(cof, cof, T[2]));
    free_cubelist(T);
    return TRUE;
  }

  /* Check for a row of all 1's (implies function is a tautology) */
  for(T1 = T+2; (p = *T1++) != NULL; ) {
    if (full_row(p, cof)) {
      *Tnew = sf_addset(new_cover(1), cube.fullset);
      free_cubelist(T);
      return TRUE;
    }
  }

  /* Check for a column of all 0's which can be factored out */
  ceil = set_save(cof);
  for(T1 = T+2; (p = *T1++) != NULL; ) {
    INLINEset_or(ceil, ceil, p);
  }
  if (! setp_equal(ceil, cube.fullset)) {
    p = new_cube();
    (void) set_diff(p, cube.fullset, ceil);
    (void) set_or(cof, cof, p);
    free_cube(p);

    A = primes_consensus(T);
    foreach_set(A, last, p) {
      INLINEset_and(p, p, ceil);
    }
예제 #14
0
파일: moncube.c 프로젝트: jpmeirsman/42
void		print_my_cube(t_data *data)
{
	float			center_x;
	float			center_y;
	t_meshes		*my_meshes;

//printf("zzz\n");
	center_x = (float) data->canvas_width / 2;
	center_y = (float) data->canvas_height / 2;
//	my_meshes = malloc(sizeof(t_meshes));
	my_meshes = new_meshes(1);
	data->my_meshes = my_meshes;
	my_meshes->m[0] = new_cube("Mon Cube");
	data->cam = set_cam(zero_vector3(), zero_vector3());
	data->cam->position = set_vector3(0, 0 ,10);
	data->cam->target = set_vector3(0, 0 ,0);
	my_meshes->m[0]->rotation.x += 0.01;
	my_meshes->m[0]->rotation.y += 0.01;

	data->anime = 1;
//printf("\n");
//	render(data, arr_mesh);
//	drawing_loop(data, my_meshes);
}
예제 #15
0
ABC_NAMESPACE_IMPL_START


/*
    cube_setup -- assume that the fields "num_vars", "num_binary_vars", and
    part_size[num_binary_vars .. num_vars-1] are setup, and initialize the
    rest of cube and cdata.

    If a part_size is < 0, then the field size is abs(part_size) and the
    field read from the input is symbolic.
*/
void cube_setup()
{
    register int i, var;
    register pcube p;

    if (cube.num_binary_vars < 0 || cube.num_vars < cube.num_binary_vars)
	fatal("cube size is silly, error in .i/.o or .mv");

    cube.num_mv_vars = cube.num_vars - cube.num_binary_vars;
    cube.output = cube.num_mv_vars > 0 ? cube.num_vars - 1 : -1;

    cube.size = 0;
    cube.first_part = ALLOC(int, cube.num_vars);
    cube.last_part = ALLOC(int, cube.num_vars);
    cube.first_word = ALLOC(int, cube.num_vars);
    cube.last_word = ALLOC(int, cube.num_vars);
    for(var = 0; var < cube.num_vars; var++) {
	if (var < cube.num_binary_vars)
	    cube.part_size[var] = 2;
	cube.first_part[var] = cube.size;
	cube.first_word[var] = WHICH_WORD(cube.size);
	cube.size += ABS(cube.part_size[var]);
	cube.last_part[var] = cube.size - 1;
	cube.last_word[var] = WHICH_WORD(cube.size - 1);
    }

    cube.var_mask = ALLOC(pset, cube.num_vars);
    cube.sparse = ALLOC(int, cube.num_vars);
    cube.binary_mask = new_cube();
    cube.mv_mask = new_cube();
    for(var = 0; var < cube.num_vars; var++) {
	p = cube.var_mask[var] = new_cube();
	for(i = cube.first_part[var]; i <= cube.last_part[var]; i++)
	    set_insert(p, i);
	if (var < cube.num_binary_vars) {
	    INLINEset_or(cube.binary_mask, cube.binary_mask, p);
	    cube.sparse[var] = 0;
	} else {
	    INLINEset_or(cube.mv_mask, cube.mv_mask, p);
	    cube.sparse[var] = 1;
	}
    }
    if (cube.num_binary_vars == 0)
	cube.inword = -1;
    else {
	cube.inword = cube.last_word[cube.num_binary_vars - 1];
	cube.inmask = cube.binary_mask[cube.inword] & DISJOINT;
    }

    cube.temp = ALLOC(pset, CUBE_TEMP);
    for(i = 0; i < CUBE_TEMP; i++)
	cube.temp[i] = new_cube();
    cube.fullset = set_fill(new_cube(), cube.size);
    cube.emptyset = new_cube();

    cdata.part_zeros = ALLOC(int, cube.size);
    cdata.var_zeros = ALLOC(int, cube.num_vars);
    cdata.parts_active = ALLOC(int, cube.num_vars);
    cdata.is_unate = ALLOC(int, cube.num_vars);
}
예제 #16
0
/* Init the models */
void init(void){

    /* Create the robot base */
    Model* base = new_cube(ROBOT_X_ORIGIN, ROBOT_Y_ORIGIN, ROBOT_Z_ORIGIN, update_base);
    models.push_back(base);

    /* Create the lower arm */
    Model* lower_arm = new_cube(ROBOT_X_ORIGIN, ROBOT_Y_ORIGIN, ROBOT_Z_ORIGIN, update_lower_arm);
    models.push_back(lower_arm);  

    /* Create the upper arm */
    Model* upper_arm = new_cube(ROBOT_X_ORIGIN, ROBOT_Y_ORIGIN, ROBOT_Z_ORIGIN, update_upper_arm);
    models.push_back(upper_arm);    

    /* Create the first shapes */
    for(int i=0;i<SHAPE_SIZE;i++){
        Model* m = new_shape(i);
        models.push_back(m); 

        shape_t s;
        s.model = m;        
        shapes[i].push_back(s);
    } 

    /* Create the second shapes */
    for(int i=0;i<SHAPE_SIZE;i++){
        Model* m = new_shape(i);
        models.push_back(m); 

        shape_t s;
        s.model = m;        
        shapes[i].push_back(s);
    }     

    /* Update colors as random */
    update_colors();

    /* Select the hold and true shape */
    hold_shape = shapes[0][0].model;
    hold_shape->update = update_holded;
    true_shape = shapes[0][1].model;

    /* Init the all models */
    for(list<Model*>::iterator i = models.begin();i != models.end();i++){
        (*i)->point_init();
        (*i)->apply_material(diffuse, ambient, specular, shininess);
        (*i)->lightp = light_p;
    }

    /* Init the view matrix */
    view = LookAt(eye_point, look_at_point, vec3(0.0,1.0,0.0));
    view *= RotateX(ROTATE_X);
    view *= RotateY(ROTATE_Y);
    projection = Perspective(fovy, aspect, z_near, z_far);
    
    /* Enable some features */
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glClearDepth(1.0);
    glEnable(GL_MULTISAMPLE);
    glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0, 0, 0, 0);   

    /* Init the clock */
    past = clock();
}
예제 #17
0
//@builds the world of objects and background color,
//    lights, and camera with depth of reflections
//@post objects and lights now exist in the world with camera and associated viewplane assigned
//@usage world_ptr -> build();
void
World::build(void)
{
    background_color = black;
    depth = 4;  // levels of reflection. 0 for no reflections.

    camera_ptr = new Camera();
    camera_ptr -> loc = Vector3D(3,15,6);
    camera_ptr -> v = Vector3D(0,1,-5);
    camera_ptr -> n = Vector3D(0,.3,1);
    camera_ptr -> calculateUVN(camera_ptr -> n, camera_ptr -> v);
    camera_ptr -> u = Vector3D(1,0,-10);
    camera_ptr -> calculateUVN(camera_ptr -> n, camera_ptr -> u);


    Sphere* sphere_ptr = new Sphere;
    sphere_ptr -> set_center(-3, 1, -45);
    sphere_ptr -> set_radius(2.0);
    Material* mat_ptr = new Material();
    mat_ptr -> kr = .8;
    mat_ptr -> setAllColor(1,0,0);       // red
    sphere_ptr -> set_material(mat_ptr);
    add_object(sphere_ptr);

    sphere_ptr = new Sphere(Vector3D(6, 3, -45), 2);
    sphere_ptr -> set_radius(1.0);
    mat_ptr = new Material();
    mat_ptr -> kr = .6;
    mat_ptr -> setAllColor(0,1,1);          // teal
    sphere_ptr -> set_material(mat_ptr);
    add_object(sphere_ptr);

    sphere_ptr = new Sphere(Vector3D(2, -1, -35), 2);
    mat_ptr = new Material();
    mat_ptr -> kr = 0;
    mat_ptr -> setAllColor(0,1,0);          // green
    sphere_ptr -> set_material(mat_ptr);
    add_object(sphere_ptr);

    Cube new_cube(5, .5, -60);
    Square* array_of_squares[6];
    new_cube.populate_squares(array_of_squares);
    for (int i = 0; i < 6; i++)
    {
        add_object(array_of_squares[i]);
    }

    Plane* plane_ptr = new Plane(Vector3D(0, -2, 0), Vector3D(0, 1, 0));
    mat_ptr = new Material();
    mat_ptr -> kr = .8;
    mat_ptr -> setAllColor(1, 1, 1);          // green
    plane_ptr -> set_material(mat_ptr);
    add_object(plane_ptr);

    CheckeredPlane* pattern_pointer = new CheckeredPlane(Vector3D(0, -1.9999, 0), Vector3D(0, 1, 0));
    mat_ptr = new Material();
    mat_ptr -> kr = .4;
    mat_ptr -> setAllColor(1, 0, 1);          // green
    pattern_pointer -> set_material(mat_ptr);
    add_object(pattern_pointer);

    PointLight* light_ptr = new PointLight();
    light_ptr -> set_color(1,1,1);
    light_ptr -> set_intensity(1);
    light_ptr -> set_location(100,40,10);
    add_light(light_ptr);

}
예제 #18
0
파일: main.cpp 프로젝트: fulmineo/hpc-oc
int main(int argc, char *argv[])
{
	int myid, numprocs, i;
	int namelen;
	char processor_name[MPI_MAX_PROCESSOR_NAME];

	// Инициализация подсистемы MPI
	MPI_Init(&argc, &argv);

	// Получить размер коммуникатора MPI_COMM_WORLD
	// (общее число процессов в рамках задачи)
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
	// Получить номер текущего процесса в рамках 
	// коммуникатора MPI_COMM_WORLD
	MPI_Comm_rank(MPI_COMM_WORLD,&myid);
	MPI_Get_processor_name(processor_name,&namelen);

	if (myid==0)
	{
		//create X0
	}

	//TODO: считать настройки из файла
	ReadSettings("config.cfg");

	FILE *fp;
	fp = fopen("U.raw","r");
	assert(fp!=NULL);

	int npts;
	int dim_u;
	fscanf(fp,"%d",&npts);
	fscanf(fp,"%d",&dim_u);

	//добавляем шаги по времени
	assert(t0<t1);

	//unsigned long start_pos=ftell(fp);
	fpos_t start_pos;
	fgetpos(fp,&start_pos);

	float t=t0;

	//выделили память
	float *u = new float[dim_u];
	float *curr_corner = new float[dim_x];
	float *next_p = new float[dim_x];

	FILE *log=fopen("log.txt","w");

	while (t<=t1)
	{
		

		//fseek(fp,start_pos,SEEK_SET);
		//fsetpos(fp,&start_pos);
		rewind(fp);
		fscanf(fp,"%d",&npts);
		fscanf(fp,"%d",&dim_u);

		if (myid==0)
		{
			std::ifstream ifs("X.prev", std::ios::binary);
			std::ofstream ofs("X.next", std::ios::binary);
			ofs << ifs.rdbuf();
		}

		MPI_Barrier(MPI_COMM_WORLD);

		//файл с прошлым шагом
		FILE *prevX;
		prevX = fopen("X.prev","rb");
		assert(prevX!=NULL);
		//printf("%d: Opened X.prev\n",myid);

		//со следующим
		FILE *nextX;
		nextX = fopen("X.next","rb+");
		assert(nextX!=NULL);

		//теперь философия такая. у меня есть N точек и K процессов
		//если N>K (а это часто так), то каждый процесс берёт точки последовательно:
		// myid, myid+K, myid+2*K итд
		//пропускаем myid строк

		for (int i=0; i<myid; i++){
			while((feof(fp)==0) && (fgetc(fp)!='\n')); //skip strings!
		}

		while( !feof(fp)){	
			//считали точку u
			for (int i=0; i<dim_u; i++)
			{
				fscanf(fp,"%f",u+i);
			}

			//printf("%d: took next u: ",myid);
			for (int i=0; i<dim_u; i++)
			{
				//printf("%f ",u[i]);
			}
			//printf("\n");

			//словарь с кубиками
			std::map<long,Cube> newCubes;
		

			Cube curr_cube(dim_x);
			long space_idx=0;

			rewind(prevX);
			rewind(nextX);

			while(curr_cube.ReadCube(prevX))//читаем следующий кубик из файла
			{
				//printf("%d: Reading next cube at %d\n",myid,space_idx);

				// вычислим точки в текущем кубе
				SpaceIdxToCorner(space_idx,curr_corner);
				//printf("%d: Calculating points inside...",myid);
				curr_cube.CalculatePoints(curr_corner,delta);
				//printf("OK (%d points in cube) \n",curr_cube.points.size());
				
				// переберём их
				for (int p_idx=0; p_idx<curr_cube.points.size(); p_idx++)	
				{
					float *p = curr_cube.points[p_idx];
					
					//формула Эйлера FTW!!
					//printf("%d: Calculating next point\n",myid);
					
					for (int i=0;i<dim_x;i++)
					{
						fprintf(log,"%f ",p[i]);
					}
					fprintf(log,"-> ");
					f(t,p,u,next_p);
					for (int i=0; i<dim_x; i++) next_p[i]=p[i]+h*next_p[i];
					for (int i=0;i<dim_x;i++)
					{
						fprintf(log,"%f ",next_p[i]);
					}
					fprintf(log,"\n");

					//printf("%d: Point OK, indexing\n",myid);

					//ищем индекс её кубика
					long space_index=GetSpaceIndex(next_p);
					std::map<long,Cube>::iterator cube_idx=newCubes.find(space_index);
					
					if (cube_idx!=newCubes.end())
					{
						//printf("%d: Indexed in ready cube\n",myid);
						//если нужный кубик у нас уже есть, пихаем туда новую точку
						cube_idx->second.Add(GetCubeIndex(next_p,space_index));

						//newCubes[space_index].Add(GetCubeIndex(next_p,space_index));
					} else {
						//кубика нет, пробуем завести
						//printf("%d: Indexed in new cube\n",myid);
						try 
						{
							//printf("%d: Creating a cube\n",myid);
							Cube new_cube(dim_x);
							new_cube.Add(GetCubeIndex(next_p,space_index));
							newCubes.insert(std::pair<long,Cube>(space_index,new_cube));
							//printf("%d: Insertion OK\n",myid);
						}
						catch (std::bad_alloc& nomem)
						{
							//printf("%d: SHIT!\n",myid);

							//не хватило памяти при создании кубика
							rewind(nextX);
							//записываем все посчитанные кубики в файл
							for (std::map<long,Cube>::iterator it = newCubes.begin(); it!=newCubes.end(); it++)
							{
								(*it).second.WriteCube(nextX,it->first,SEEK_SET);
							}
							//очищаем память
							newCubes.clear();

							//пробуем ещё разок
							Cube new_cube(dim_x);
							new_cube.Add(GetCubeIndex(next_p,space_index));
							newCubes.insert(std::pair<long,Cube>(space_index,new_cube));
						}
					}
				}
				space_idx++;
			}
			
			//printf("%d: Calculated some points, writing X.next...",myid);
			//пишем посчитанные кубики в файл		
			rewind(nextX);
			for (std::map<long,Cube>::iterator it = newCubes.begin(); it!=newCubes.end(); it++)
			{
				it->second.WriteCube(nextX,it->first,SEEK_SET);
			}
			//printf("OK\n");

			//printf("%d: Done for u ",myid);
			for (int i=0; i<dim_u; i++)
			{
				//printf("%f ",u[i]);
			}
			//printf("\n");


			//пропускаем numprocs строк
			for (int i=0; i<numprocs; i++){
				while((feof(fp)==0) && (fgetc(fp)!='\n')); //skip strings!
			}
		}

		fclose(nextX);
		fclose(prevX);

		fprintf(log,"%d: Time step done, switching\n",myid);

		//барьер!

		MPI_Barrier(MPI_COMM_WORLD);

		if (myid==0)
		{
			//меняем местами X.next и X.prev
			assert(rename("X.next","_X.next")==0);
			assert(rename("X.prev","X.next")==0);
			assert(rename("_X.next","X.prev")==0);
			//copy contents of X.prev to X.next			
			//printf("Current t: %f of %f\n",t,t1);
		}

		//добавляем время
		t+=h;

		fflush(stdout);	
	}

	//освободили память
	delete[] next_p;
	delete[] curr_corner;
	delete[] u;
	fclose(fp);
	fclose(log);

	// Освобождение подсистемы MPI
	MPI_Finalize();

	delete[] root_corner;
	return 0;
}