Автоматизация процесса построения сетки
Здравствуйте, уважаемые члены сообщества exponenta! Третий день бьюсь над решением проблемы, и никак не получается ее решить.
Суть такова: необходимо построить сетку, и провести процесс коррекции (но это сейчас не столь принцпиально). Проблема заключатеся в следующем: кривые, которые образуют сетку задаются с помощью вызова функции CoordTransform, она работает таким образом, что на выходе возвращает 6 параметров, каждый вызов этой функции дает при каждом фиксированной координате, кривую, например, вызов функции Tr1_0(i,:)=CoordTransform(q1,0); позволяет строить кривую изменяющейся с определнным шагом по координате q1, но для постоянной q2 = const (нулю в данном случае). Аналогично и с функцией Tr2_0(i,:)=CoordTransform(0,q2).
Одна кривая горизонтальная, вторая - вертикальная, если говорить наиболее просто. В результате необходимо построить, получить сетку.
Если проводить вызов вручную, т.е прописывать каждый раз вызов CoordTransform и передавать в нее значения самому прописывать, 0,1..5, то в приницпе это нормально, но когда надо строить сетку от 0 до 10 с шагом например 0,01, то вручную это деалть уже тяжело.
Если раскоментировать содрежимое файла coord_curves3.m то эту сетку можно построить, в этом случае, для каждой траектории Tr1_(:,1),Tr1_(:,2) выводить первый и второй столбец, аналогично и для Tr2_(:,1),Tr2_(:,2), тогда получаем такую картинку:
Мне нужно автоматизировать процесс построения такой сетки, чтобы не вручную вызывать и передавать параметр для построения трека (кривой), а просто некоторым циклом, чтобы в одном массиве были треки Tr1_i а в другом Tr2_i, и т.е каждый вызов функции пострения кривой, можно было вызывать несколько раз и в зависимости от переданной из диапазона q=const, т.е передаем в качестве константы q2 = 0 : .05 :10, и соответсвенно каждый раз происходит вызов Tr1[i](i,:)=CoordTransform(q1,q2); т.е надо организовать вызов функций таким образом, чтобы все эти Tr1_i и Tr2_i не приходилось прописывать вручную, как это в файле скрипте...
Для это я написал automate_Tr1() и automate_Tr2(), в них передаю значения q=const для каждой кривой, т.е сначала кривая Tr1(q1,q2 = const), где const последовательно при каждом вызове пробегает значения 0 : .05 :10 к примеру. И пытаюсь организовать вызов для записи в массив каждого трека, чтобы потом с помощью цикла построить такую сетку:
for i=2:Nc
plot(Tr1(i,:,1),Tr1(i,:,2),Tr2(i,:,1),Tr2(i,:,2))
end
Однако, при вызове
for qq2 = 0:.05:10
Ts = automate_Tr1(qq2);
end
просто все время получаю только значение для кривой, когда в нее передан последний элемент диапазона переменной qq2.
Уже почти 3 дня я пытаюсь это сделать и никак не могу понять,что я делаю не так, какой строчки кода не хватает, может я неправильно организу. индексацию, в чем может быть проблема??
Я просто уже не знаю, что делать... Буду благодрен, за оказанную помощь! Все файлы в архиве!
Ответы
Не совсем понятно. Вроде вы сами пишите про цикл, н опри этом вроде как говорите что цикл вам не нужен. Можете пояснить?
Прошу прощения, не совсем корректно написал, мне нужно вызывать циклом и записывай каждый трек в массив, а затем с помощью plot(Ts1(i,:,1),Ts1(i,:,2),Ts2(i,:,1),Ts2(i,:,2)) уже просто вывести эту сетку, где Ts_i как раз тот массив кривых Tr_i...
Но можно строить и циклом график, т.е в цикле реализовать вывод plot(Tr1(i,:,1),Tr1(i,:,2),Tr2(i,:,1),Tr2(i,:,2)) , правда в этом случае, передавая при вызове Tr1_qq2(i,:)=CoordTransform(q1,qq2);, т.е массив координат констант, потом размерности не совпадают, так что вариант с циклом конечно, не рабоатет, сколько я его ни пробовал, но и варинат без цикла plot также пока не сработал...
Для определенности: т.е. массивы ваших "дуг" имеют разные размерности?
Дуга1 = M1(x,y) - массив (первый) координат точек сетки, размерности (2 х m1)
Дуга1 = M2(x,y) - массив (второй) координат точек сетки, размерности (2 х m2)
. . . . .
где m1 != m2 != m3 != . . . . .
и вы пытаетесь нарисовать массивы?
Ну почти так, сейчас постарюсь объяснить более понятно. Сетка строится с помощью координатных кривых. Строим первые треки (кривые), это делается следующим образом:
Хм. не до конца понятно. Возьмем одну вашу дугу. Она допустим состоит из 100 точек. Т.е. у вас 100 иксов, и 100 игреков. Строим plot (x,y). Все. Затем следующую. думаю увас как-то не совсем рациоданоьно данные хранятся.
итого будет у вас
И в этом случае даже если от цикла к циклу кол-во точек будет разное , оно все равно должно построиться.
Не, у меня вызов каждой функции нужно автоматизировать, в зависимости от передаваемой координаты, а затем вытащить из нее значения 1 и 2 столбцов, как выше описанными командами, только не вручную, каждая перменная Tr_ i (i,:) = CoordTransform(q1,q2), когда для одной надо вызывать эту функциюи последовательно передавать сначала значения для q2 (получаем Tr1) и для q1 (получаем Tr2). и потом записать их в массив таким образом, чтобы просто вызвать функцию plot() и построить эту сетку.
Каждая такая функция, должна вызываться один раз, но при каждом значении q1 или q2, передаваемом в CoordTransform.
Я иначе не могу организовать массивы, чтобы строить тракетории, только так, потому что эта функция должна мне возвращать те значения, которые она возвраащет для дальнейшей работы.
Я поэтому в отдельный файл вывел функции для вызова Tr_i, и потом их вызываю, и получаю разную размерность массивов, и не могу построить сетку...
И сетка получается корявой:
Похоже?
Да, это вот то что нужно, не хватает кривой при q1=5, но если можно будет делать3 густую сетку, а так в целом, именно это надо получить (в плане картинки)
Сделал ровно то, что написал выше. Да и размерности вроде у вас нормальные.
Хорошо, но в цикл то Вы что тогда загнали под массивы x и y? У меня ведь две кривые, куда я должен передавать q...
Уточнить могу я кое-какой момент?
Если у меня шаг координаты, q1= cosnt или q2 = const, должен быть 0.1, то какой параметр менять, просто как я понял есть переменная PPSQR, она влияет на шаг изменяющейстя координаты, когда одна постоянная, но мне понадобится, чтобы интервалы координат констант был напримем 0.1, и кривые образовывали бы густую сетку, но на диапазоне от нуля до 5...
PPSQR - это количество точек в линии приходящееся на 1 вашу клетку.
Count - кол-во клеток
Count2 - кол-во точек всего в каждлой линии сетки.
Просто переменная jj может начинаться только с 1, и вдобаввок целый шаг иметь (1,2,3...)
заведите kk = f(jj) которая будет иметь дробный шаг
Отдельно переменную получается...
да
Прошу прощения, что я не сразу ответил, переменную чтобы задать, индексы массива он все равно пишет должны быть целыми, как их... Просто раз я по идее их умножаю на число (шаг), то они их спокойно он должен воспринимать?
И еще один вопросик, как думаете, вот когда я хочу получить значения из сетки, и на каждом шаге изменения координат вычислять ближайшую точку к каждому из 4 узлов сетки, почему при записи стандартной функции
griddedInterpolant(Gr(i,j,1),Gr(i,j,2), вместо просто поиска ближайшей точки как расстояния между координатами (FindNearest1) он может выдавать такую ошибку:
Interpolation requires at least two sample points for each grid dimension.
Вызываю функию из coordcurves3
Код для самой CorrMove:
Просто беру значения из одной сетки, а почему такая ошибка возникает не понимаю, а то писать интерполяцию вручную, когда есть готовые функции не имеет смысла, но понять почему такая ошибка, не могу...
Не. Цикл конечно д.б. по целочисленной jj, а float-шаг уже используете как вам нужно.
Не совсем понятно как вы используете ф-цию. Вы туда передаете 2 значения, и между ними ищите что-то. И это в цикле. А реально ф-ция создает объект которому нужно иметь на входе сетку, отличную от исходной, и он вернет вам массив новых значений. А передавать ей в цикле по 2 значения как-то совсем не рационально. В хелпе на ф-цию есть примеры.
Да, просто я туплю, и получаю картинку вот такую, менняя шаг в цикле....
Исходя из смысла переменных, введеным Вами, на диапазоне от нуля до 5 как менять PPSQR.... Вот почему я спросил...
Да, я видел пример в хелпе, но мне надо по каждому из узлов сетки брать, и искать например ближайшую к узлу точку, которая на самом деле должна соответствовать истинному положению, а сетка кривых как раз моделирует погрешность перемещения, она искривлена, вот и надо передав параметры в CorrMove определить это истинное положение в результате коррекции, а вот FindNearest в простом случае определяла близость точки с помощью расстояния, и в итоге, бралась та точка, которая к точке на сетке имела минимальное расстояние, а лучше, если всмето поиска по наименьшему расстоянию, будет использована интерполяция...
А раз с циклом она не работает, и ей нужна готовая сетка, придется как-то писать руками... пользовательский скриптик
Я возможно понял, что не так с вызовом для функции gridInterpolant, но вот с шагом не могу ничего сделать...
Все равно не могу понять, как при целой индесации jj сделать дробный шаг, чтобы при тех же пределах от 0 до 5 для q1 и q2, чтобы чаще строил кривые сетки, а не просто уменьшал ее масштаб...
jj = 1,2,3,...,N
h = (jj-1)/100
следовательно
h = 0, 0.01, 0.02, 0.03, ... , (N-1)/100
Да, уважаемый aBoomest, так и передаю потом в цикл переменную h:
Аналогично просто в уменьшенном масштабе сетка, jj менять я не могу для cells, иначе не построит их потом в цикле...
В coord_curves3 меняю только Count, PPSQR.
Шаг у вас получается qh = 1/PPSQR
Count = 10
PPSQR = 100
qh = 1/PPSQR = 0.01 (шаг)
Нет, Вы не поняли, шаг qh это одно, я говрою о кривых,образущих сетку: вот возьмем вертикальные кривые, они идут при фиксированной каждый раз q1 (x1) = 1:2:3...10... Т.е jj шаг, а проблема в том, что эти кривые должны быть построены с более мелким шагом, пусть 0,5, но на том же диапазоне значений q1 0 до 5 к примеру, но не с шагом 1, а с шагом 0,5 допустим...
Я поэтому и пишу, так то я понял, что шаг qh можно менять...
Т.е чтобы кривые по фиксированной координате изменялись чаще ( за что jj отвечает), и более мелкие узлы сетки были, но без роста значений диапазона q1 и q2
Тогда вам нужно завести набор аналогичных переменных отдельно для вертикальных дуг и отдельно для горизонтальных и программу скрипта слегка модифицировать.
Два отдельных qh, чтобы и дял вертикальной и горизонтальной дуг были... Ну попробую, попытаюсь
Хотя нет, зачем мне два qh... Глупость какую-то сказал
Это завист от того каких линий и сколько надо нарисовать. В общем случае задача стоит так: нарисовать сетку с преобразованием таким то. Диапазон по 1й координате такой-то, по 2й координате такой-то. Шаг сетки, . . . . тоже самое. Ну и в частных случаях какие-то из величин у вас м.б. одинаковыми.
А можно уточнить: группа данных cells в MATLAB в принципе не может принимать дробный индекс, или все же это возможно? Вектор же может принимать шаг, отличный от нуля... А ячейка нет? Для ячеек возможно например преобразование индексов из логических элементов в числовые, как это есть для векторов?
Нет.
Не знаю что вы подразумеваете под
но любая индексация целочисленная.
Простыми словами если говорить, вектор, терминами обычного программиста не в матлаб, это массив данных. Однотипные.
Cell - это в некоторой стемени массив ячеек в которых могут быть разнотипные данные.
не от нуля, а от целого числа, я описку совершил. Ну это понятно, что индексация целочисленная, для вектора шаг можно дробный сделать спокойно, даже в цикле, и он допустим, пример взять, напечатать 10 чисел с шагом 0.1, так он их и выдаст с шагом 0,1. А здесь видимо так нельзя делать...
Нет. Вы все таки не совсем четко рассуждаете. Математика вешь точная не только с т.з. чисел, но и с т.з. формулировок :)
Вектор V от 0 до 1 с шагом 0,1 - это массив имеющи N = 11 элементов. Индексация м.б. разная. Обычно это 0,1,...,10, но в матлаб принято 1,2,...,11.
Вектор не может принимать дробный индекс. То, что вы описали - это просто способ генерации масива чисел с заданным шагом.
Что под этим подразумевается?
По идее преобразования вы можете сделать какие вам угодно, хоть с трёхэтажными формулами, это дело ваше. Факт - чтобы результат был целый.
Ну я к тому спрашиваю, что если никаких проблем записать дробный шаг для вектора нет, то для cells "угустить" такую сетку, построенных из кривых тяжело.
Да, Вы правы, я не так выразился, мой косяк терминологический...
абстрактно
да это не так оптимально, как A = (0:0.01:1) и будет работать на много медленнее, но результат один.
Не, ну это я понимаю)
Ну и вызов соотвественно с параметром (jj-1)/D
А сколько по времени у Вас занимал вызов функции? Просто ПК не слабый, вроде бы, но я с трудом могу остановить просто выполнение программы (конечно, мб у меня проблемы с самим ПО)... В свете последних событий мне пришло переписать функции CoordTransform, ибо заставили, но по смыслу, они возвращают те же кривые...
1. Да, долго выполнялось.
2. Это хорошо, ибо там все не оптимально, даже на беглый взгляд.
Просто даже 5 минут, и всё равно не строится, я потому спросил... Мб и правда с ПО проблемы
Видимо я неправильно вызов организую, но у меня ничего не происходит. Для сетки, которая на последнем рисунке, у Вас какой шаг? Тот что написан?
Да. Изначально у вас шаг был 1.
Параметр D - это делитель шага, т.е. шаг 1/6 на рисунке. НУ и даже если линии просто посчитать, то видно, что от 0 до 2 имеет место 12 линий сетки.
Понял Вас...
Вот в чем дело, ну не строит и все, очень странно, да может и надо ждать, но не 15 минут же с прерыванием...
Те же MoveQ работают по тому же принципу, я ведь и вызываю Вашим кодом... Какой-то бред, с сеткой, честное слово (причем Ваш то код, написан грамотно, должен работать)
Вопрос-то последнего поста в чем, не до конца ясно?
В том, уважаемый aBoomest, что может я неправильно цикл организую,потому что он конечно, как Вы сказали долго выполняется, но не настолько же, чтобы и через 15 не построить сетку?
Оценить время сложно, но . . .
1. В идеале все должно работать одним циклом, а у вас куча циклов.
2. В идеале^2 циклы должны быть реорганизованы в векторную математику (в матлабовском смысле). Но по ощущениям для данной задачи это полноценено сделать не удастся.
3. Отрисовка графики - это очень медленная вещь. И при работе с графикой вопрос оптимизации стоит остро.
Так что вполне себе возможно 15 сек.
PS: Встречался код большого количества вычислений. Без оптимизации расчет длился 10-11 часов. После оптимизации - до 3 минут.
15 минут, у меня...(и то, потом вылет)
Сильно, да уж, как важна оптимизация, хотя спорить не приходится, это действительно так.
Если раскоментировать все закоментированное после комментария Ver 2.0.............
И передавть соотвественно все параметры как в коде, что я в послденем посте привел, то почему-то практически не работает.
Уважаемый, aBoomest, как думаете, в чем может быть проблема? Мне пришлось все же вернуться к старой функции coordtransform, ибо для moveQ получать сетку, извлекать из кривых построенных само значение координат для сетки, тяжеловато, но такой вот вопрос, при вызове, вместо той сетки, которая изображена у Вас, у меня получается непонятно что, теперь все снова вызвается для coordtransform:
Вот я думаю, где же ошибся, поскольку на выходе:
Что конечно, не является сеткой... Хотя как раз вызов происходит аналогично, что и я для случая, когда шаг единичный... Просто с дургими параметрами...
Вы не могли бы прикрепить файл или код вызова данных циклов, а то я не понимаю, почему спирали, прохожу отладчиком, и вижу, что переменные забиты странными значениями...?
Я не понимаю, уважаемый aBoomest, я вроде так же вызываю... Не получается абсолютно...
Где-то лишнего прибавляется в индексах. Что-то такое получалось, когда ваш код смотрел. Проверьте внимательно и все получится.
К сожалению кода нет, ибо в командировке. :)