Как создать вектор с рисунком [1 2 5 6 9 10 13 14 17 18 ....] в MATLAB? - PullRequest
3 голосов
/ 22 апреля 2020

Предположим, что мы хотим создать вектор с шаблоном:

[1   3   5   7   9] 

Мы могли бы легко написать

1:2:10

Но что я должен написать, если мне нужен этот шаблон:

[1 2 5 6 9 10 13 14 17 18 ....]

?

Идея заключается в том, что у меня есть матрица длинных столбцов:

[-0.41416   0.37756  -3.39666  -0.42352   0.83481  -0.66782  -0.75471   0.54008  -0.60284 -1.43141  -1.10128  -0.18244]

И я хочу превратить ее в:

[-0.41416   0.37756 0 0  -3.39666  -0.42352 0 0   0.83481  -0.66782 0 0  -0.75471   0.54008 0 0 -0.60284 -1.43141 0 0 -1.10128  -0.18244 0 0]

Для каждых 2 значений я хочу добавить два нуля.

Вот как я решил это, если я хочу, чтобы между каждым значением было только 0 нулей.

l = length(g);
nu = rows(g);
G = zeros(nu, l*nu);
for i = 1:nu
  G(i, i:nu:l*nu-1+i) = g(i, 1:l);
end
g = G; 

Этот код превратит этот шаблон

   [1.4392e-04   5.6149e-07   1.4572e-04  -1.1104e-05   1.4720e-04  -3.3176e-05   1.4836e-04
   2.4174e-04   6.5988e-06   2.7917e-04   5.3787e-06   3.1924e-04   1.0706e-06   3.6204e-04]

в этот шаблон:

   [0.000221   0.000000  -0.000420   0.000000   0.000570   0.000000  -0.000418   0.000000
   0.000000   0.017647   0.000000  -0.002033   0.000000   0.017248   0.000000  -0.001855]

Ответы [ 5 ]

3 голосов
/ 22 апреля 2020

Вы можете сложить два вектора строки (второй равен одному плюс первый), а затем изменить его:

>> a=[1:4:17];
>> b=reshape(vertcat(a,a+1),1,[])

b =

     1     2     5     6     9    10    13    14    17    18

Та же идея распространяется и на вашу вторую "причину этого примера":

>> c=[-0.41416   0.37756  -3.39666  -0.42352   0.83481  -0.66782  -0.75471   0.54008  -0.60284 -1.43141  -1.10128  -0.18244];
>> d=reshape(c,2,[]);
>> e=reshape(vertcat(d,0*d),1,[])

e =

  Columns 1 through 12

   -0.4142    0.3776         0         0   -3.3967   -0.4235         0         0    0.8348   -0.6678         0         0

  Columns 13 through 24

   -0.7547    0.5401         0         0   -0.6028   -1.4314         0         0   -1.1013   -0.1824         0         0
2 голосов
/ 22 апреля 2020

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

Для выполнения это, мы изменяем форму (это по существу бесплатно, данные не копируются) вектор, чтобы иметь 2xN элементов. Теперь мы добавляем две строки нулей и снова изменяем форму матрицы для вектора столбца:

M = [-0.41416   0.37756  -3.39666  -0.42352   0.83481  -0.66782  -0.75471   0.54008  -0.60284 -1.43141  -1.10128  -0.18244].';

M = reshape(M,2,[]);
M = [M;zeros(size(M))];
M = reshape(M,[],1);
M = M(1:end-2);      % remove the last two zeros, which we don't want

Конечно, это работает только для массивов четного размера. Для массива нечетного размера мы сначала добавляем ноль, а затем удаляем его после:

M = [-0.41416   0.37756  -3.39666  -0.42352   0.83481  -0.66782  -0.75471   0.54008  -0.60284 -1.43141  -1.10128].';

M = reshape([M;0],2,[]); % note we add a zero here
M = [M;zeros(size(M))];
M = reshape(M,[],1);
M = M(1:end-3);          % remove the last three zeros, which we don't want
2 голосов
/ 22 апреля 2020

Вам не нужна математика для этого; вы действительно можете воспользоваться MAT частью MATLAB следующим образом:

  • сгенерировать массив элементов с нечетным индексом нужного массива,
  • добавить 1 к нему, чтобы получить массив элементов с четным индексом,
  • объединить две строки по вертикали, получив таким образом матрицу из двух строк,
  • векторизовать матрицу по столбцу
  • транспонировать его, если вам действительно нужна строка.
n = 100;
x = 1:4:n;
x = [x; x + 1];
x = x(:)';

Это создает четное количество элементов в исходном векторе. Если вам нужен нечетный номер, используйте тот же код с соответствующим n и измените последнюю строку следующим образом:

x = x(1:end-1)';
1 голос
/ 22 апреля 2020

Ответ, пытающийся решить эту проблему для произвольной длины, не полагаясь на длину, делимую на 2 или 4.

При приближении к таким задачам мне нравится описывать шаблон в короткий текстовый или математический способ, который обычно приводит к тому, что я могу реализовать. Здесь «все числа от 1 до n, которые имеют остаток 1 или 2 при делении на 4»

>> n=9;
>> find(ismember(mod(1:n,4),[1,2]))

ans =

     1     2     5     6     9

, что позволяет установить самое высокое значение n. Если вы вместо этого хотите установить m количество элементов в вашем списке, я бы использовал следующий код:

>> m = 7;

>> [1:m]*2-(mod([1:m],2)==0)-1

ans =

    1     2     5     6     9    10    13

Идея, лежащая в основе этого, заключается в том, что ваш шаблон имеет вид 2 4 6 8, уменьшенный на 1, а затем снова каждая нечетная позиция уменьшается на 1. Это, вероятно, больше подходит для вашей операции индексации:

x=rand(7,1);
m=numel(x);
pattern=[1:m]*2-(mod([1:m],2)==0)-1;
y(pattern)=x;

, которая возвращает:

y =

    0.9572    0.4854         0         0    0.8003    0.1419         0         0    0.4218    0.9157         0         0    0.7922
1 голос
/ 22 апреля 2020

Вы можете просмотреть

[1 2 5 6 9 10 13 14 17 18 ....]

как следующую сумму:

  [0 1 0 1 0 1 0 1 ...] + [1 1 5 5 9 9 13 13 ...]
= [0 1 0 1 0 1 0 1 ...] + [0 0 4 4 8 8 12 12 ...] + [1 1 1 1 1 1 1 1 ...]
= [0 1 0 1 0 1 0 1 ...] + 4*[0 0 1 1 2 2 3 3 ...] + [1 1 1 1 1 1 1 1 ...]

Каждый из этих кусков должен быть проще для создания:

[0 1 0 1 0 1 0 1 ...] = mod(0:1:9, 2)
[0 0 1 1 2 2 3 3 ...] = floor(0.5 * (0:1:9))
[1 1 1 1 1 1 1 1 ...] = ones(1, 10)

Помещение вместе:

>> mod(0:1:9, 2) + 4*floor(0.5*(0:1:9)) + ones(1,10)
ans =
    1    2    5    6    9   10   13   14   17   18

Но, перейдя ко второй части вашего вопроса, есть более простой способ решить его, если ваша цель - вставить два ноля после каждых двух элементов. Начните с изменения формы вашего длинного массива в виде матрицы размером 2 на (n / 2):

>> y = reshape(x, 2, 6)
y =
  -0.41416  -3.39666   0.83481  -0.75471  -0.60284  -1.10128
   0.37756  -0.42352  -0.66782   0.54008  -1.43141  -0.18244

Теперь вставьте две строки нулей:

>> z = [y; zeros(2, 6)]
z 
  -0.41416  -3.39666   0.83481  -0.75471  -0.60284  -1.10128
   0.37756  -0.42352  -0.66782   0.54008  -1.43141  -0.18244
   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000

Затем измените форму обратно на 1-мерный массив:

>> w = reshape(z, 1, 24)
w =
 Columns 1 through 7:
  -0.41416   0.37756   0.00000   0.00000  -3.39666  -0.42352   0.00000
 Columns 8 through 14:
   0.00000   0.83481  -0.66782   0.00000   0.00000  -0.75471   0.54008
 Columns 15 through 21:
   0.00000   0.00000  -0.60284  -1.43141   0.00000   0.00000  -1.10128
 Columns 22 through 24:
  -0.18244   0.00000   0.00000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...