• Регистрация
Н/Д
Н/Д 0.00
н/д

Автоматизация процесса построения сетки

04.05.2021

Здравствуйте, уважаемые члены сообщества 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 дня я пытаюсь это сделать и никак не могу понять,что я делаю не так, какой строчки кода не хватает, может я неправильно организу. индексацию, в чем может быть проблема??  

Я просто уже не знаю, что делать... Буду благодрен, за оказанную помощь! Все файлы в архиве!

Теги

    04.05.2021

    Ответы

    • aBoomest
      aBoomest+942.89
      5.05.2021 05:04

      надо организовать вызов функций таким образом, чтобы все эти Tr1_i и Tr2_i не приходилось прописывать вручную, как это в файле скрипте...

      Не совсем понятно. Вроде вы сами пишите про цикл, н опри этом вроде как говорите что цикл вам не нужен. Можете пояснить?

      • Прошу прощения, не совсем корректно написал, мне нужно вызывать циклом и записывай каждый трек в массив, а затем с помощью 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 также пока не сработал...

        • aBoomest
          aBoomest+942.89
          5.05.2021 08:06

          Для определенности: т.е. массивы ваших "дуг" имеют разные размерности?
          Дуга1 = M1(x,y) - массив (первый) координат точек сетки, размерности (2 х m1)
          Дуга1 = M2(x,y) - массив (второй) координат точек сетки, размерности (2 х m2)
          . . . . .

          где m1 != m2 != m3 != . . . . .

          и вы пытаетесь нарисовать массивы?

      • aBoomest
        aBoomest+942.89
        5.05.2021 13:56

        Хм. не до конца понятно. Возьмем одну вашу дугу. Она допустим состоит из 100 точек. Т.е. у вас 100 иксов, и 100 игреков. Строим plot (x,y). Все. Затем следующую. думаю увас как-то не совсем рациоданоьно данные хранятся.

        итого будет у вас 

        for i := 1 to count do
        plot(текущий массив x, текущий массив y);
        end;

        И в этом случае даже если от цикла к циклу кол-во точек будет разное , оно все равно должно построиться.

        • Не, у меня вызов каждой функции нужно автоматизировать, в зависимости от передаваемой координаты, а затем вытащить из нее значения  1 и 2 столбцов, как выше описанными командами, только не вручную, каждая перменная Tr_ i (i,:) = CoordTransform(q1,q2), когда для одной надо вызывать эту функциюи последовательно передавать сначала значения для q2 (получаем Tr1) и для q1 (получаем Tr2). и потом записать их в массив таким образом, чтобы просто вызвать функцию plot() и построить эту сетку.

          Каждая такая функция, должна вызываться один раз, но при каждом значении q1 или q2, передаваемом в CoordTransform.

          Я иначе  не могу  организовать массивы, чтобы строить тракетории, только так, потому что эта функция должна мне возвращать те значения, которые она возвраащет для дальнейшей работы.

          Я поэтому в отдельный файл вывел функции для вызова Tr_i, и потом их вызываю, и получаю разную размерность массивов, и не могу построить сетку...

           

             

          И сетка получается корявой:

                             

          • aBoomest
            aBoomest+942.89
            6.05.2021 05:17

            Похоже?

            • Да, это вот то что нужно, не хватает кривой при q1=5, но если можно будет делать3 густую сетку, а так в целом, именно это надо получить (в плане картинки)

              • aBoomest
                aBoomest+942.89
                6.05.2021 06:31

                Сделал ровно то, что написал выше. Да и размерности вроде у вас нормальные.

                • Хорошо, но в цикл то Вы что тогда загнали под массивы x и y? У меня ведь две кривые, куда я должен передавать q...

                   

                  clear
                  clc
                  
                  
                  R2=15; R1=15;
                  
                  qq2 = 0:1:5;
                  Ts1 = automate_Tr1(qq2);
                  
                  qq1 = 0:1:5;
                  Ts2 = automate_Tr2(qq1);
                  
                  for i = 1:100
                      plot(Ts1(i,1),Ts1(i,2),Ts2(i,1),Ts2(i,2))
                  end
                  
                  • aBoomest
                    aBoomest+942.89
                    6.05.2021 07:06

                    • Если у меня шаг координаты, q1= cosnt или q2 = const, должен быть 0.1, то какой параметр менять, просто как я понял есть переменная PPSQR, она влияет на шаг изменяющейстя координаты, когда одна постоянная, но мне понадобится, чтобы интервалы координат констант был напримем 0.1, и кривые образовывали бы густую сетку, но на диапазоне от нуля до 5...

                      • aBoomest
                        aBoomest+942.89
                        6.05.2021 07:21

                        PPSQR - это количество точек в линии приходящееся на 1 вашу клетку.

                        Count - кол-во клеток

                        Count2 - кол-во точек всего в каждлой линии сетки.

                      • Просто переменная jj может начинаться только с 1, и вдобаввок целый шаг иметь (1,2,3...)

                        • aBoomest
                          aBoomest+942.89
                          6.05.2021 07:22

                          заведите kk = f(jj) которая будет иметь дробный шаг

                          • Отдельно переменную получается...

                            • aBoomest
                              aBoomest+942.89
                              6.05.2021 07:54

                              да

        • aBoomest
          aBoomest+942.89
          7.05.2021 05:03

          Прошу прощения, что я не сразу ответил,  переменную чтобы задать, индексы массива он все равно пишет должны быть целыми, как их... Просто раз я по идее их умножаю на число (шаг), то они их спокойно он должен воспринимать?

          Не. Цикл конечно д.б. по целочисленной jj, а float-шаг уже используете как вам нужно.

          Просто беру значения из одной сетки, а почему такая ошибка возникает не понимаю, а то писать интерполяцию вручную, когда есть готовые функции не имеет смысла, но понять почему такая ошибка, не могу...

          Не совсем понятно как вы используете ф-цию. Вы туда передаете 2 значения, и между ними ищите что-то. И это в цикле. А реально ф-ция создает объект которому нужно иметь на входе сетку, отличную от исходной, и он вернет вам массив новых значений. А передавать ей в цикле по 2 значения как-то совсем не рационально. В хелпе на ф-цию есть примеры.

          • Не. Цикл конечно д.б. по целочисленной jj, а float-шаг уже используете как вам нужно.

            Все равно не могу понять, как при целой индесации jj сделать дробный шаг, чтобы при тех же пределах от 0 до 5 для q1 и q2, чтобы чаще строил кривые сетки, а не просто уменьшал ее масштаб...

            • aBoomest
              aBoomest+942.89
              10.05.2021 09:28

              jj = 1,2,3,...,N

              h = (jj-1)/100

              следовательно

              h = 0, 0.01, 0.02, 0.03, ... , (N-1)/100

        • aBoomest
          aBoomest+942.89
          11.05.2021 05:17

          В 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

            • aBoomest
              aBoomest+942.89
              11.05.2021 08:15

              Тогда вам нужно завести набор аналогичных переменных отдельно для вертикальных дуг и отдельно для горизонтальных и программу скрипта слегка модифицировать.

              • Хотя нет, зачем мне два qh... Глупость какую-то сказал

                • aBoomest
                  aBoomest+942.89
                  11.05.2021 10:55

                  Это завист от того каких линий и сколько надо нарисовать. В общем случае задача стоит так: нарисовать сетку с преобразованием таким то. Диапазон по 1й координате такой-то, по 2й координате такой-то. Шаг сетки, . . . . тоже самое. Ну и в частных случаях какие-то из величин у вас м.б. одинаковыми.

                • А можно уточнить: группа данных cells в MATLAB  в принципе не может принимать дробный индекс, или все же это возможно? Вектор же может принимать шаг, отличный от нуля... А ячейка нет? Для ячеек возможно например преобразование индексов из логических элементов в числовые, как это есть для векторов?

                  • aBoomest
                    aBoomest+942.89
                    11.05.2021 11:10

                    Нет.

                    Не знаю что вы подразумеваете под 

                    Вектор же может принимать шаг, отличный от нуля...

                    но любая индексация целочисленная.

                    Простыми словами если говорить, вектор, терминами обычного программиста не в матлаб, это массив данных. Однотипные.
                    Cell - это в некоторой стемени массив ячеек в которых могут быть разнотипные данные.

                    • не от нуля, а от целого числа, я описку совершил. Ну это понятно, что индексация целочисленная, для вектора шаг можно дробный сделать спокойно, даже  в цикле, и он допустим, пример взять, напечатать 10 чисел с шагом 0.1, так он их и выдаст с шагом 0,1. А здесь видимо так нельзя делать...

                      • aBoomest
                        aBoomest+942.89
                        11.05.2021 11:20

                        Нет. Вы все таки не совсем четко рассуждаете. Математика вешь точная не только с т.з. чисел, но и с т.з. формулировок :)

                        Вектор V от 0 до 1 с шагом 0,1 - это массив имеющи N = 11 элементов. Индексация м.б. разная. Обычно это 0,1,...,10, но в матлаб принято 1,2,...,11.

                        А можно уточнить: группа данных cells в MATLAB  в принципе не может принимать дробный индекс, или все же это возможно? Вектор же может принимать шаг, отличный от нуля... А ячейка нет? 

                        Вектор не может принимать дробный индекс. То, что вы описали - это просто способ генерации масива чисел с заданным шагом.

                        Для ячеек возможно например преобразование индексов из логических элементов в числовые, как это есть для векторов?

                        Что под этим подразумевается?
                        По идее преобразования вы можете сделать какие вам угодно, хоть с трёхэтажными формулами, это дело ваше. Факт - чтобы результат был целый.

                        • Ну я к тому спрашиваю, что если никаких проблем записать дробный шаг для вектора нет, то для cells "угустить" такую сетку, построенных из кривых тяжело.

                          • aBoomest
                            aBoomest+942.89
                            11.05.2021 12:19

                            абстрактно

                            A = cell(Count,1); 
                            h = 0;
                            dh = 0.01;
                            for ii = 1:Count
                              A{ii} = f(h);
                              h = h + dh;
                            end

                            да это не так оптимально, как A = (0:0.01:1) и будет работать на много медленнее, но результат один.

            • aBoomest
              aBoomest+942.89
              11.05.2021 12:23

              D=6; % делитель сетки, его можно тоже разделить на два разных
              Count_1 = 10*D;  
              Count_2 = 10*D;  
              
              PPSQR1 = 4;
              PPSQR2 = 4;
              qh1 = 1/PPSQR1/D;
              qh2 = 1/PPSQR2/D;
              Count1 = Count_1*PPSQR1;
              Count2 = Count_2*PPSQR2;

              Ну и вызов соотвественно с параметром (jj-1)/D

               

              • А сколько по времени у Вас занимал  вызов функции? Просто ПК не слабый, вроде бы, но я с трудом могу остановить просто выполнение программы (конечно, мб у меня проблемы с самим ПО)... В свете последних событий мне пришло переписать функции CoordTransform, ибо заставили, но по смыслу, они возвращают те же кривые... 

                • aBoomest
                  aBoomest+942.89
                  11.05.2021 13:33

                  1. Да, долго выполнялось.
                  2. Это хорошо, ибо там все не оптимально, даже на беглый взгляд.

                  • Видимо я неправильно вызов организую, но у меня ничего не происходит. Для сетки, которая на последнем рисунке, у Вас какой шаг? Тот что написан?

                     

                    %-------------------------------------------------------------------------------------------------------------------------------------
                    %                                                   Ver 2.0 MoveQ1, MoveQ2
                    %-------------------------------------------------------------------------------------------------------------------------------------
                    
                    clear;
                    clc;
                    close all;
                    
                    R1 = 15;
                    R2 = 15;
                    L1 = 5;
                    L2 = 5;
                    R0 = 15;
                    
                    D=5; 
                    Count_1 = 15*D;  
                    Count_2 = 15*D;  
                    
                    PPSQR1 = 4;
                    PPSQR2 = 4;
                    qh1 = 1/PPSQR1/D;
                    qh2 = 1/PPSQR2/D;
                    Count1 = Count_1*PPSQR1;
                    Count2 = Count_2*PPSQR2;
                    
                    q2 = 0;
                    for jj = 1:Count1
                            Tr1{jj} = MoveQ1(q2,R1,L1,R2,L2,qh1);
                            q2 = q2 + (jj-1)/D;
                    end
                    
                    q1 = 0;
                    for jj = 1:Count2
                            Tr2{jj} = MoveQ2(q1,R1,L1,R2,L2,qh2); 
                            q1 = q1 + (jj-1)/D;
                    end
                    
                    % Grd=CoordGrid(Count3,Count4,Tr1,Tr2);
                    
                    figure;
                    subplot(1,1,1);
                    clf;
                    hold on;
                    for ii = 1:Count1
                        line(Tr1{ii}(:,1),Tr1{ii}(:,2));
                        line(Tr2{ii}(:,1),Tr2{ii}(:,2));
                    end
                    

                     

                    • aBoomest
                      aBoomest+942.89
                      12.05.2021 09:47

                      Да. Изначально у вас шаг был 1. 
                      Параметр D - это делитель шага, т.е. шаг 1/6 на рисунке. НУ и даже если линии просто посчитать, то видно, что от 0 до 2 имеет место 12 линий сетки.

                      • Вот в чем дело, ну не строит и все, очень странно, да может и надо ждать, но не 15 минут же с прерыванием...

                        Те же MoveQ работают по тому же принципу, я ведь и вызываю Вашим кодом... Какой-то бред, с сеткой, честное слово (причем Ваш то код, написан грамотно, должен работать)

                        • aBoomest
                          aBoomest+942.89
                          13.05.2021 05:11

                          Вопрос-то последнего поста в чем, не до конца ясно?

                          • В том, уважаемый aBoomest, что может я неправильно цикл организую,потому что он конечно, как Вы сказали долго выполняется, но не настолько же, чтобы и через 15 не построить сетку?

                            • aBoomest
                              aBoomest+942.89
                              13.05.2021 09:32

                              Оценить время сложно, но  . . .

                              1. В идеале все должно работать одним циклом, а у вас куча циклов.
                              2. В идеале^2 циклы должны быть реорганизованы в векторную математику (в матлабовском смысле). Но по ощущениям для данной задачи это полноценено сделать не удастся.
                              3. Отрисовка графики - это очень медленная вещь. И при работе с графикой вопрос оптимизации стоит остро.

                              Так что вполне себе возможно 15 сек.

                              PS: Встречался код большого количества вычислений. Без оптимизации расчет длился 10-11 часов. После оптимизации - до 3 минут.

              • Вы не могли бы прикрепить файл или код вызова данных циклов, а то я не понимаю, почему спирали, прохожу отладчиком, и вижу, что переменные забиты странными значениями...?

              • Я не понимаю, уважаемый aBoomest, я вроде так же вызываю... Не получается абсолютно...

                • aBoomest
                  aBoomest+942.89
                  20.05.2021 20:45

                  Где-то лишнего прибавляется в индексах. Что-то такое получалось, когда ваш код смотрел. Проверьте внимательно и все получится.

                  К сожалению кода нет, ибо в командировке. :)