Mátrix szorzó program. Lépésről lépésre útmutató. Mátrixszorzás. Párhuzamos számítástechnikai megoldás

Természetesen a bemeneti adatokból rekonstruálhatunk mátrixokat, ezeket triviálisan megszorozhatjuk és az eredményt adott formában megjeleníthetjük. Példa a rossz programozási stílusra: egy naiv algoritmus csaknem kétszeresére növeli a felhasznált memória mennyiségét, és jelentősen gyengébb a teljesítménye. Létezik egy másik megoldás is, amely a szabványos mátrixműveletek szekvenciális adaptálásával érhető el a bemeneti adatformátumhoz.

Előszoba gyakorlatok sablonnal

Erre a célra az elvet használják dinamikus programozás. Ebben a bejegyzésben megvitatjuk a mátrixszorzási algoritmust és annak folyamatábráját, amely bármilyen magas szintű nyelven használható mátrixszorzás programozási kódjának írásához.

Ez segít elképzelni a mátrixszorzás működési mechanizmusát, és megérteni, hogyan kell kódot írni, mely lépések követésével. Mivel a mátrix téglalap alakú számok halmaza, szorzási eljárása nem azonos a számok szorzásával. Vannak bizonyos eltérő szabályok, amelyeket be kell tartani, amikor egy mátrixot manuális módszerrel és programozással szorozunk.

A legnagyobb nehézséget mind számítási, mind fogalmi szempontból a mátrixok szorzása jelenti, jelen esetben a négyzetesítés. A következő lépések sorozata lehetővé teszi szimmetrikus mátrixok szorzását a forrásadat-formátumban való lineáris ábrázolásukkal.

1. megjegyzés

A szimmetrikus mátrixok altere nem zárt szorzáskor: két szimmetrikus mátrix szorzata lehet aszimmetrikus mátrix.

Mátrixszorzó algoritmus

Mielőtt tehát rátérnénk a mátrixszorzás algoritmusára és blokkdiagramjára, vessünk egy gyors pillantást a mátrixszorzás végrehajtására. Ha az első mátrix sorainak száma megegyezik a második mátrix oszlopainak számával, folytassa a lépéssel. Nyomtassa ki a terméket mátrixként a konzol kimeneteként.

  • Ellenőrizze az első és a második mátrix sorainak és oszlopainak számát.
  • Ellenkező esetben a nyomtatási mátrix szorzása nem lehetséges, és folytassa a lépéssel.
  • Szorozza meg a mátrixokat beágyazott hurkok segítségével.
A probléma megoldására szolgáló algoritmus és folyamatábra megadja a programozás során használandó alapvető trükköt és a forráskód megírásának alapötletét.

Példa

\left(\begin(array)(ccc) 1 & 1 & 3 \\ 1 & 4 & 5 \\ 3 & 5 & 0\end(array) \right) \cdot \left(\begin(array)(ccc ) 4 & 0 & 0 \\ 0 & 4 & 3 \\ 0 & 3 & 2 \end(array) \right) = \left(\begin(array)(ccc) 4 & 13 & 9 \\ 4 & 31 & 22 \\ 12 & 20 & 15 \end(array) \right)

2. megjegyzés

A szimmetrikus mátrix foka egyben szimmetrikus mátrix is. A bizonyítás egy mátrix lineáris operátor reprezentációjaként való megjelenítésén és a Hermitiánus operátorok tulajdonságain alapul.

A mátrixszorzási folyamatábra tanulmányozása segít a programozónak megjeleníteni a vezérlési folyamatot a program végrehajtása során. A fenti algoritmus és folyamatábra felhasználható arra, hogy megértsük, hogyan kell mátrixszorzó programot írni bármely magas szintű programozási nyelven.

A mátrixokat ugyanúgy meg lehet szorozni skaláris állandókkal, mint tetszőleges számú változót skalárállandóval. A skaláris állandó bármely számra vonatkozik; valós vagy képzeletbeli; pozitív vagy negatív; egész vagy tört, de nem változó.

Minden további számításnál feltételezzük, hogy a mátrixot \frac(n(n+1))(2) elemekből álló lineáris tömb reprezentálja.

Először is megjegyezzük, hogy a C=A^(2) mátrix c_(i,j) eleme egyenlő az A mátrix i-edik sorának skaláris szorzatával (mint vektorok a standard bázisban). a j-edik sora (annak köszönhetően, hogy szimmetrikus mátrixban a j-edik sor egybeesik a j-edik oszloppal). Ezért ahhoz, hogy egy szimmetrikus mátrixot hatványra emeljünk, szükséges és elégséges végrehajtani a két sor skaláris szorzás műveletét.

A mátrixszorzás tulajdonságai

A skaláris állandókkal való szorzáson kívül a mátrixok más mátrixokkal is szorozhatók. A mátrixszorzás azonban nem olyan egyszerű, mint a szabályos szorzás, bizonyos szabályokat be kell tartani, és bizonyos feltételeknek teljesülniük kell. A mátrixszorzásnak van még néhány tulajdonsága, és ezeket mindjárt látni fogjuk.

A mátrixszorzás szabálya

Más szóval, egy mátrix szorzásakor a mátrix bal oldalán lévő oszlopok számának meg kell egyeznie a mátrix jobb oldalán lévő sorok számával. Ez, amint azt valamikor látni fogjuk, a mátrixok szorzásának módjával kapcsolatos. Ez a szabály az oka annak, hogy a mátrixszorzás nem kommutatív. Az optimális módja annak ellenőrzésére, hogy 2 mátrix megszorozható-e egymás melletti méretükkel.

Ezután meg kell értened, hogyan kaphatod meg az i-edik sort egy adott mátrixábrázolásból. A kényelem kedvéért a rendelkezésre álló elemeket komplett mátrix formájában írjuk ki. Vegye figyelembe, hogy az i-edik sor első eleme az első sor i-edik eleme lesz, és általánosítsa ezt a megfigyelést. Jelöljük az aktuális számunkra érdekes elem helyét az i-edik sorban j-vel. Ha j< i, то следует выбрать i-ый элемент j-ой строки, иначе следует выбрать все элементы j-ой строки, лежащие правее данного. Графически можно интерпретировать алгоритм таким образом: начиная с i-го элемента первой строки, спускаться вертикально вниз по матрице до тех пор, пока не будет достигнута i-ая строка, далее — двигаться вправо до конца строки. Наглядность алгоритма позволяет легко воплотить его программно.
Csak azt kell megfigyelni, hogy a mátrix soraiban lefelé haladva hogyan változik az egymás alatt elhelyezkedő elemek távolsága, ami megkönnyíti az algoritmus átvitelét a felső háromszögmátrix lineáris ábrázolására. Megkérjük az olvasót, hogy végezze el ezt az egyszerű, de vizuális gyakorlatot az algoritmus jobb megértése érdekében.

Algoritmus mátrixszorzáshoz

Ha nem, akkor ne törődj vele, csak mondd, hogy nem lehetséges. A mátrixszorzás ugyanazt az algoritmust követi, mint a vektoros szorzás. Emlékezzünk vissza, hogy a vektor lehet egy sor vagy egy oszlop, mint pl. Mindig a szükséges mátrixok telepítésével kezdje, ne keverje a sorrendjüket. Ekkor felmerül a kérdés, hogy mi a következő lépés!

A mátrixszorzás a sorok oszlopokkal való szorzásával történik. Ebben az esetben csak egy sorunk van, de négy oszlopunk van. Ezt úgy tehetjük meg, hogy az összes sort megszorozzuk az összes oszloppal. Ezt azért adjuk hozzá, mert a kapott mátrix minden bejegyzése az adott pozíció sor- és oszlopbejegyzéseinek szorzatának összege.

Most közvetlenül a megvalósításhoz léphet.

Jó napot mindenkinek. Nemrég publikáltam egy rövidet, és most eljött az ideje a párhuzamos algoritmusok megvalósításának. Az első a sorban egy egyszerű mátrixszorzó algoritmus, amely nagyon jól használható párhuzamosításra, mivel három egymásba ágyazott ciklusból áll.

Tehát most azt mondhatjuk, hogy ha két mátrixot megszorozunk, a szorzatukban ugyanannyi sor lesz, mint a bal oldali mátrixokban, és ugyanannyi oszlop lesz, mint a jobb oldali mátrixban. Ez mindig igaz bármilyen mátrixszorzásra. Tehát most négy sorunk és négy oszlopunk van.

Minden sor megszorozza az egyes oszlopokat, és az adott pozíciónak megfelelő bejegyzést hoz létre. Nézzünk most egy másik példát a mátrixszorzás további illusztrálására. Időbe telik, míg megszokjuk a mátrixszorzás egész folyamatát, de a trükk az, hogy minél több példát kell készíteni. Az alábbiakban néhány példa látható.

Nem valószínű, hogy valaki jobban le tudja írni a mátrixszorzó algoritmust, mint a Wikipédia-cikk. Ezért mellékelek egy képernyőképet, és azonnal rátérek a megvalósításra.

Mátrixszorzó algoritmus megvalósítása C/C++ nyelven

Tegyük fel, hogy a mátrix egy kétdimenziós tömb int **mátrixban van tárolva, és az elemeket a kettős indexű mátrix[i][j] éri el. Először egyszerűen ellenőrizzük, hogy a mátrixok konzisztensek-e, majd lefoglalhatjuk a memóriát és elvégezhetjük a szorzást a képlet segítségével.

Példák mátrixszorzásra

Ezután elvégezzük a tényleges szorzást. Ezt a dokumentációt archiválták, és nem dolgozzák fel. Két algoritmus kerül bemutatásra: egy csempe nélkül és egy csempével. A Megoldáskezelőben nyissa meg a forrásfájl helyi menüjét, és kattintson az Új elem hozzáadása elemre. Kattintson a "Tovább" gombra. . A csempézés egy olyan technika, amelyben a partíciókat egyenlő méretű részhalmazokra osztják, amelyeket csempéknek neveznek. Három dolog változik a csempe használatakor.

Itt kizárólag a második esettel kívánunk foglalkozni. Természetesen ennek a funkciónak az első használata szoftver szép munkalapok létrehozása olyan nézetben, ahol a képletek is úgy vannak megírva, mint a matematikai szövegekben.

//Egy n1 x m1 méretű mátrixot megszoroz //egy n2 x m2 méretű mátrixszal int** mátrixMulti(int **mátrix1, int n1, int m1, int **mátrix2, int n2, int m2) ( // Ha nincsenek konzisztens mátrixok, akkor nem hajtunk végre szorzást if(m1 != n2) ( cout<< "Error! m1 != n2" << endl; return NULL; } //Выделяем память под результат умножения int **result; result = (int**)malloc(sizeof(int*)*n1); for(int i = 0; i < n1; i++) { result[i] = (int*)malloc(sizeof(int)*m2); } //Умножение по формуле for(int i = 0; i < n1; i++) { for(int j = 0; j < m2; j++) { result[i][j] = 0; for(int k = 0; k < m1; k++) { result[i][j] += (matrix1[i][k] * matrix2[k][j]); } } } return result; }

Itt azonban szeretnénk kihasználni a szoftver ezen funkcióját érdekes oktatási alkalmazások létrehozására. Alapvetően a szövegrészeket dupla idézőjelbe, a dinamikus részeket a nevükkel, idézőjelek nélkül kell beszúrni; a szövegrészeket és a dinamikus változókat jellel kombináljuk. Figyeljük meg, hogy még a két pont utáni szóköz és a mondat végpontja is bekerül a dupla idézőjelek közé, mivel ez tiszta szöveg.

Kiválaszthatjuk, hogy az összeget vagy a szorzatot az új változók segítségével végezzük-e el, vagy közvetlenül a szövegmezőkben. Példaként az első utat követjük a terméknél, a másodikat pedig az összegnél. \\ balra.

Párhuzamos mátrixszorzás megvalósítása C/C++ nyelven

Nem kell sok kódot írnunk, mivel az MPI-hez hasonlóan osztott memóriaszálakon fogunk működni, nem folyamatokon. A párhuzamosítás lényege az, hogy a külső ciklus előtt hozzáadjuk a #pragma omp párhuzamos direktívát. Ezt követően a szükséges számú szál automatikusan átveszi a számítási feladatokat.

Megfigyelve, hogy két összeadásjellel elválasztott bemeneti mátrixot és egy kimeneti mátrixot kell felírnunk, amelynek elemei a két bemeneti mátrix elemeinek összegei, a következő kódot kapjuk. Mint említettük, a terméknél új változókkal fogunk számításokat végezni, hogy egyszerűsítsük a szövegmezőbe írt kódot. Tehát az algebrai beviteli ablakban szekvenciálisan fogunk írni.

Ezen a ponton készen állunk a termékkód megadására a két mátrixhoz. A \\ tömb determinánsa kiszámítható a Laplace-szabállyal, amelyet az első sor elemeire fejlesztünk. A teljesség kedvéért az alábbiakban felsoroljuk őket.

  • Mátrixok összege \\.
  • Mátrix termék\\.
  • Skaláris többszörös mátrix \\.
Ez a dokumentáció archiválva van, és már nem karbantartják.

Mellékelem a forráskódot a véletlen mátrixgenerálás funkciójával és magának a szorzásuknak a párhuzamos algoritmusával.

#beleértve #beleértve #beleértve névtér használata std; void randomiseMatrix(int ​​** mátrix, int n, int m) ( for(int i = 0; i< n; i++) { for(int j = 0; j < m; j++) { matrix[i][j] = rand() % 11; } } return; } int main(int argc, char** argv) { srand(time(NULL)); int n1 = 1000; int m1 = 500; int n2 = 500; int m2 = 1200; //Матрица n1 x m1 int **matrix1; //Матрица n2 x m2 int **matrix2; matrix1 = (int**)malloc(sizeof(int*)*n1); for(int i = 0; i < n1; i++) { matrix1[i] = (int*)malloc(sizeof(int)*m1); } matrix2 = (int**)malloc(sizeof(int*)*n2); for(int i = 0; i < n2; i++) { matrix2[i] = (int*)malloc(sizeof(int)*m2); } //Генерируем случайные матрицы для умножения randomiseMatrix(matrix1, n1, m1); randomiseMatrix(matrix2, n2, m2); int **result = (int**)malloc(sizeof(int*)*n1);; for(int i = 0; i < n1; i++) { result[i] = (int*)malloc(sizeof(int)*m2); } //Устанавливаем число потоков int threadsNum = 2; omp_set_num_threads(threadsNum); int i, j, k; #pragma omp parallel for shared(matrix1, matrix2, result) private(i, j, k) for (i = 0; i < n1; i++) { for (j = 0; j < m2; j++) { result[i][j] = 0; for (k = 0; k < m1; k++) { result[i][j] += (matrix1[i][k] * matrix2[k][j]); } } } return 0; }

Két algoritmus lesz: az egyik nem használ csempéket, a másik pedig nem. A Megoldáskezelőben nyissa meg a Forrásfájlok alatti előugró menüt, majd válassza a Hozzáadás és az Új elem lehetőséget. A csempézés egy olyan technika, amely az adatokat azonos méretű részhalmazokra, úgynevezett csempékre osztja.

A metódus meghívásával leállíthatja az összes szálat egy töredékben egy adott kódsorban. A helyi index használata megkönnyítheti a kód olvasását és hibakeresését. Ebben a példában a mátrix azonos méretű részanyagokra van felosztva. Az eredményt a podcast szorzásával számítjuk ki.

Következtetés

Úgy tűnik, nem történt semmi, de ha gondosan figyeli a Task Manager()-t a végrehajtás során, láthatja, hogyan oszlik el a terhelés a processzormagok között. Hamarosan több párhuzamos algoritmus implementációt teszek közzé OpenMP segítségével, iratkozz fel a frissítésekre e-mailben. Mára ennyi, köszönöm a figyelmet!

Mátrixok és eredményük ebben a példában. Az algoritmus gyors kiértékeléséhez számítsa ki az eredmény első oszlopának első sorában lévő elem értékét. Kód ennek az algoritmusnak a megvalósításához. Az alkalmazásból való kilépéshez használja a szóköz billentyűt. A mátrixot leggyakrabban zárójelekkel elválasztott számtáblázatként írják fel.

Ez az első sor első eleme, a második sor második eleme stb. Az €e mátrixot, ahol €t = n^, négyzetmátrixnak nevezzük. Bármilyen típusú mátrixot, amelynek minden sorának minden eleme nulla, nulla mátrixnak nevezzük. Legyen A e és € elemekkel rendelkező mátrix. Egy mátrix transzponálása a sorok és oszlopok cseréjét jelenti. A mátrixot megszorozzuk egy állandóval, minden elemet megszorozva ugyanazzal az állandóval.