![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
spea |
|
|||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
С помощью чего и как лучше реализовать эту задачу на языке С?
Попробую кратко описать задачу. Имеются данные в txt файле в следующем виде: 23.020834 56.979168 -9.01 23.062500 56.979168 -10.37 23.104166 56.979168 -11.98 23.145834 56.979168 -13.84 23.187500 56.979168 -15.44 23.229166 56.979168 -17.79 23.312500 56.979168 -18.47 23.354166 56.979168 -19.25 23.395834 56.979168 -20.15 Количество строк заранее не известно, их около 30 000. В каждой строке 3 характеристики (A, B, C) одной точки. Точки можно условно пронумеровать от 1 до k. В общем, для каждой точки нужно рассчитать ещё одно значение (D). Для i-ой точки Di= сумма произведений Ck* (Ak - Ai) * (Bk - Bi). Так например для первой точки D1 = C1 * (A1 - A1) * (B1 - B1) + C2 * (A2 - A1) * (B2 - B1) + ... + Ck * (Ak - A1) * (Bk - B1) для второй точки D2 = C1 * (A1 - A2) * (B1 - B2) + C2 * (A2 - A2) * (B2 - B2) + ... + Ck * (Ak - A2) * (Bk - B2) и т.д. для всех точек k. Основная мысль в том, что сначала исходные данные нужно считать в массив, затем проиндексировать и составить алгоритм расчета D. Но вместо всего столбца удается считать только первое значение. И ещё не понятно как быть, если исходные данные разбиты на 2 файла. Это сообщение отредактировал(а) spea - 23.10.2012, 00:07 |
|||
|
||||
feodorv |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
В принципе, можно открыть файл и посчитать количество строк:
Тогда заранее будет известен размер требуемого массива. Далее запрашивается память нужного размера:
(можно и через calloc). Далее читаем файл данных (с самого начала) построчно:
Далее высчитываем значения массива d. Уже считали, только не в один массив, а в три - a, b, c. При желании, можно структуру использовать вида:
И работать уже с массивом структур, но это не принципиально. Что имеется в виду? Код приведите, пожалуйста))) Добавлено через 8 минут и 47 секунд
Можно объединить два файла в один. А можно сконструировать так программу, чтобы она работала с несколькими файлами. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||
|
|||||||||||
spea |
|
||||||||||||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
Спасибо большое за помощь!
Каким то образом присвоить индексы i и k из форумы. В начале пытался сделать на основе куска этого кода
И вопрос ещё по файлам. В конечном итоге их должно быть около 300. Лучше их объединять, так? P.S. Извиняюсь, что наверно большая половина, написанного мной, похоже на бред) Это сообщение отредактировал(а) spea - 23.10.2012, 00:05 |
||||||||||||||
|
|||||||||||||||
feodorv |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ничего, попробуем разобраться ![]() Вот это в каком смысле? Ясно же сказано:
Эти данные - независимы друг от друга (для каждого файла - свои N и d), или все их нужно объединить в одну общую большую кучу? PS Какая у Вас операционка? Вот это всё есть в файле, или же файл всё-таки такого формата: Тогда откуда там аж 5 значений на строчку??? Нет, всё-таки три... А разделитель строк '\n' Вы запихиваете в файл? Почему тогда не так:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||
|
|||||||||
spea |
|
||||||||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
Сама исходная задача звучит несколько иначе: идет интегрирование по поверхности сферы, и двойной интеграл заменяется суммой. А первые две (А, B) координаты в строке это широта и долгота. Поэтому все данные взаимосвязаны, по примерным подсчетам около 40 млн точек. И D считается несколько сложнее, а здесь попытался отразить только то, что вызвало вопросы. Для меня это вводная задача и в тему исследования и, вообще, в программирование. И ещё кое-что. Предполагаю, что в дальнейшем мне придется выполнять задачи такого типа: решение дифференциальных и интегральных уравнений с краевыми условиями, преобразование Фурье и др. Слышал о подключении библиотек Matlab или Scilab. Можете ли порекомендовать литературу, где описывается как реализовать такое в С? feodorv, ещё раз спасибо, Вы мне невероятно помогли. Это сообщение отредактировал(а) spea - 23.10.2012, 09:44 |
||||||||||
|
|||||||||||
feodorv |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Увы, нет. Лучше всего задать этот вопрос в отдельной теме ![]() Двойной интеграл - двойная сумма. Может, где-то нужен цикл и по i, проверьте, пожалуйста. Но d[i] вычисляется именно так. Это много.... Таких массивов ОС может не создать... ![]() Добавлено через 12 минут и 3 секунды Нет, ничего, создаёт:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
spea |
|
||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
В первом приближении получилось следующее
Появилось несколько вопросов. Первый: для всех массивов нужно выделять память по типу (double *) malloc( N * sizeof(double) ), а для двухмерного (double **) malloc( N * sizeof(double *) ) ? и когда необходимо производить освобождение памяти? Второй: FS[i][k] вычисляется по значению аркосинуса. А для ячеек типа [1][1] или [5][5], т.е когда i равно k, аркосинус равен 0, из-за чего происходит деление на 0. То что у меня записано как if ( i == k ) FS[i][k] == 0; не всегда срабатывает: часть значений обращается в ноль, другие - в минус ноль, третьи - занимают пол экрана. В общем, как можно исключить эти значения? Третий: При обработке большого числа точек (около 500) программа выкидывает ошибку. Понимаю, что вычисление реализованы хуже некуда, а попытками улучшить делаю только хуже. Что именно необходимо исправить в программе, чтобы оптимизировать её работу ? |
||||
|
|||||
feodorv |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Гм. Вы понимаете, что линейные массивы требуют памяти размером N*sizeof(double) байт, а двумерные - уже N*N*sizeof(double), что для 500 элементов увеличивает размер требуемой памяти в 500 раз? Судя по коду, можно обойтись только линейными массивами, вычисляя p[i][k] и FS[i][k] по ходу цикла по переменной i.
Судя по всему, Вы исчерпываете стековую память (по умолчанию ограниченную 1 мегабайтом).
И не только:
В момент, когда память больше не нужна. Но по окончанию процесса память высвобождается автоматически, поэтому если выделенная память нужна до самого конца, то можно её вообще не высвобождать))) Не увидел деления на FS[i][k]... Умножение - да, видел... Если действительно в интегральной формуле знаменатель обращается в 0, значит и числитель тоже, и здесь нужно пользоваться разложением вблизи нуля (типа sin(x)/x ~= 1 - x*x/6 + ...) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
spea |
|
|||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
FS[i][k] = 1/sin(Z/2) - 6*sin(Z/2) + 1 - 5*cos(Z) - 3*cos(Z)*log(sin(Z/2) + pow(sin(Z/2), 2)); так вот когда Z = 0, а Z равен нулю в точках i = k, происходит деление на ноль, а ещё нахождение натурального логарифма нуля, и в память заносится значение 1.#INF00 . Не понятно как заставить программу в этих точках игнорировать это значение или давать значение FS[i][k], при i = k, равное нулю. |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Аааа))) Опять же, FS[i][k] не существует сам по себе, оно потом умножается на что-то близкое к 0.
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
spea |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
Выкладываю вторую версию кода. Просьба посмотреть на наличие ошибок и указать на то, что можно сделать лучше и эффективнее.
Это сообщение отредактировал(а) spea - 25.10.2012, 21:26 |
||||||
|
|||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
И то, и другое))) А этой проверки не сделано. При нехватке памяти (а её и не может хватить на 20000 * 20000 double элементов), malloc возвращает NULL, по которому адресу Вы и пытаетесь обратиться. Алгоритм необходимо переписать под использование только линейных массивов, но никак не двумерных... Это сообщение отредактировал(а) feodorv - 25.10.2012, 20:27 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
spea |
|
||||
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 22.10.2012 Репутация: нет Всего: нет |
Посмотрю, что можно сделать, но боюсь, что это маловероятно. Скорее всего надо преобразовывать исходные данные, чтобы не обрабатывать 40 млн точек. |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Посмотрите хотя бы на массивы FS[ i ][ k ], p[ i ][ k ] и то, как они используется. Их вполне можно заменить на вызовы функций
Вот что здесь маловероятного? А если ещё и массивы lon и lat сделать глобальными, то не нужно будет их передавать в качестве аргументов... Хотя и так хорошо))) Это сообщение отредактировал(а) feodorv - 26.10.2012, 04:29 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |