コード例 #1
0
ファイル: special.c プロジェクト: VitaliyRakitin/ChM
// обновление шага
double new_h(double EPS, double h, double k[K_NUM][VAL_NUM], double x, double y, double u, double v){
    double var = Variation(h,k,x,y,u,v);
    double p = 1.0/(POW + 1.0);

    while (var > EPS){
        h = h*min(max(FAC * pow(EPS/var,p))); 
        new_k(h,k,x,y,u,v); 
        var = Variation(h,k,x,y,u,v); 
        if (h<H_DEFAULT) break;
    }
    h =  h*min(max(FAC * pow(EPS/var,p)));
    return h;
}
コード例 #2
0
WrfGridValueMap* StoryLineWidget::GetOperationResult(OperationType op_type){
	last_operation_elements_.clear();

	std::vector< WrfGridValueMap* > elements;
	for ( int i = 0; i < stamp_items_.size(); ++i )
		if ( stamp_items_[i]->is_selected() ){
			elements.push_back(WrfDataManager::GetInstance()->GetStoryStamp(stamp_items_[i]->id()));
			last_operation_elements_.push_back(stamp_items_[i]->id());
		}
	switch (op_type){
	case SUM_OP:
	case MINUS_OP:
		if ( elements.size() != 2) return NULL;
		break;
	case VAR_OP:
		if ( elements.size() < 2 ) return NULL;
		break;
	default:
		return NULL;
		break;
	}

	if ( result_value_map_ == NULL ){
		result_value_map_ = new WrfGridValueMap;
		result_value_map_->start_latitude = elements[0]->start_latitude;
		result_value_map_->end_latitude = elements[0]->end_latitude;
		result_value_map_->start_longitude = elements[0]->start_longitude;
		result_value_map_->end_longitude = elements[0]->end_longitude;
		result_value_map_->latitude_grid_number = elements[0]->latitude_grid_number;
		result_value_map_->longitude_grid_number = elements[0]->longitude_grid_number;
		result_value_map_->latitude_grid_space = elements[0]->latitude_grid_space;
		result_value_map_->longitude_grid_space = elements[0]->longitude_grid_space;
		result_value_map_->max_value = elements[0]->max_value;
		result_value_map_->min_value = elements[0]->min_value;
		result_value_map_->values.resize(elements[0]->longitude_grid_number * elements[0]->latitude_grid_number);
	}

	switch (op_type){
	case SUM_OP:
		SumMap(elements);
		break;
	case MINUS_OP:
		Minius(elements);
		break;
	case VAR_OP:
		Variation(elements);
		break;
	default:
		return NULL;
		break;
	}
	
	int temp_level = -1;
	for ( int i = 0; i < elements.size(); ++i ) if ( elements[i]->level > temp_level ) temp_level = elements[i]->level;
	result_value_map_->level = temp_level + 1;

	return result_value_map_;
}
コード例 #3
0
ファイル: special.c プロジェクト: VitaliyRakitin/ChM
// Основная функция. На вход: EPS --- порядок погрешности
// filename --- файл для вывода, local --- значения локальной погрешности в точках
int runge(double *global_error, double EPS, const char*filename, double local[CHECK_POSITIONS * VAL_NUM ])
{
    double x,y,u,v; // x y a b
    double h=0;

    double k[K_NUM][VAL_NUM]; // числа рунге
    int errflag = 0;
    int check_time = CHECK_POSITIONS; // количество оставшихся точек на временной шкале для проверки лок погрешности
    int flag = 0;
    double h_next = 0; // механическая переменная для хранения следующего шага

    *global_error = 0;

    FILE *file = fopen(filename, "w");

    if (file == NULL) errflag = -1;
    else{
        fprintf(file, "t,  x,  y\n");

        //вводим начальные условия
        x = x0;    y = y0;    u = u0;   v = v0;   h = EPS/h0;
        new_k(h,k,x,y,u,v); // начальные числа Рунге
        h = new_h(EPS,h,k,x,y,u,v); // обновляем шаг
        new_k(h,k,x,y,u,v); // ежели он изменился -- обновим числа Рунге

        for (double t = 0;t<=WORK_TIME+h;t+=h){
            // если мы в нужной точке T, 3T/4, T/2, T/4, то flag == 1 

            if (flag == 0)
                if (check_time > 0) // если меньше, то точек не осталось, увы
                        if ((nearest(t) - t <= h)&&(nearest(t) - t >= 0)){
                            // если мы сюда попали, то расстояние до нужной точки меньше h
                            // объявим следующий шаг этим расстоянием
                            h_next = nearest(t) - t;
                        }


            //подсчет глобальной погрешности
            (*global_error) = Variation(h,k,x,y,u,v) + (*global_error) * exp_int(h,x,y);

        // обновляем координаты
            x = new_parametr(h,x,k,x,y,u,v,0);
            y = new_parametr(h,y,k,x,y,u,v,1);
            u = new_parametr(h,u,k,x,y,u,v,2);
            v = new_parametr(h,v,k,x,y,u,v,3);
            fprintf(file, "%e,  %e,  %e\n", t,x,y);
            // если мы в нужной точке T, 3T/4, T/2, T/4, то flag == 1 
            if (flag == 1) {
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time)] = x;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 1] = y;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 2] = u;
                local[CHECK_POSITIONS*(CHECK_POSITIONS - check_time) + 3] = v;
                h = h_next; // возвращаем исходное значение шага 
                h_next = 0; 
                flag = 0;
                check_time--; // мы же уже дошли до этой точке, осталось на одну меньше
            }

            h = new_h(EPS,h,k,x,y,u,v); //обновляем шаг

            if (h_next != 0){
                double p;
                p = h;
                h = h_next;
                h_next = p;//сохраняем предыдуший шаг на случай, если новый слишком маленький
                flag = 1; // для того, чтобы мы видели вывод
            }
            
            new_k(h,k,x,y,u,v); //обновляем числа Рунге
           
            if (h<H_DEFAULT) {errflag = -2; break;} // на случай особых точек
        }
    }
    printf("final step = %e;\n", h);
    fclose(file);
    return errflag;
}