Matlab/Octave - macierz z dwóch wektorów

Mam wektory:

x = linspace(-10, 10, 100);

y = linspace(-20, 20, 100);

Chciałbym wygenerować sobie taką macierz, w której element m(i,j) to będzie pierwiastek z sumy kwadratów x(i), oraz y(j).

Poszukuję najprostszego rozwiązania.

to chyba podstawy operacji na macierzach w matlabie (octave nie znam w ogóle).

\potrzeba napisac prosta funkcje iteracyjna operujaca na elementach tych dwoch macierzy

Właśnie nie chciałbym tego robić w pętli w stylu:

x = linspace(-10, 10, 100);

y = linspace(-20, 20, 100);

for i = 1:100

  for j = 1:100

    r(i,j) = sqrt( x(i)*x(i) + y(j)*y(j) );

  end;

end;

bo pętle w takich programach są dosyć powolne i przy większych rozmiarach wektorów długo trwa obliczanie.

Natomiast operacje na wektorach i macierzach są szybkie i takie chciałbym użyć.

zrób kolumnę xk z x oraz kolumnę yk z y

(xk*x)+(yk*y)

już będziesz mieć x(i)*x(i) + y(j)*y(j)

już dawno w matlabie nie grzebałem, wolę matematykę od Wolfram ale jest tam wywołanie podanej operacji na każdej komórce macierzy,

tak zrobisz z tego pierwiastek.

Twój sposób daje ujemne wyniki, więc na pewno nie jest to suma kwadratów.

Mój sposób nie może dawać ujemnych wyników, jeżeli daje ujemne wyniki to jest to jakiś tam twój sposób odmienny od tego co napisałem wyżej.

Najprostsze rozwiązanie tego problemu w MATLAB-ie / Octave:

x = linspace(-10, 10, 100);

y = linspace(-20, 20, 100);

[xx, yy] = meshgrid(x, y);

m = sqrt(xx.^2 + yy.^2);

Ps Jeśli już stosujesz pętle, to dobrym zwyczajem jest “zainicjowanie” macierzy tworzonej przy pomocy pętli poprzez wypełnienie jej zerami.

r = zeros(100, 100);


for i = 1:100

  for j = 1:100

    r(i,j) = sqrt(x(i)^2 + y(j)^2);

  end;

end;

To inicjowanie dobrze można zilustrować w Pythonie, korzystając z biblioteki NumPy. Ten sam przykład można zapisać w ten sposób:

import numpy as np


x = np.linspace(-10, 10, 100)

y = np.linspace(-20, 20, 100)


xx, yy = np.meshgrid(x, y)

m = np.sqrt(xx **2 + yy** 2)


r = np.zeros((100, 100), dtype = np.float64)


for i in range(100):

    for j in range(100):

        r[i, j] = np.sqrt(x[i] **2 + y[j]** 2)

gdzie dtype = np.float64 oznacza typ danych, którymi wypełniona będzie macierz. Tutaj float64 zostanie użyty domyślnie, bo operujemy na liczbach rzeczywistych, ale jeśli mamy np. macierz z numerami węzłów zdyskretyzowanej powierzchni to wtedy koniecznie stosujemy np. int32. Na koniec można sprawdzić na kawałku macierzy czy uzyskane wyniki są takie same:

print(m[0] == r[0].T)

Tutaj .T oznacza transpozycję. W matlabie stosuje się symbol ’ .

[[True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]

 [True True True True True True True True True True]]