/**********************************************************************\ * Kurzbeschreibung: matrixOp.c * Bietet Funktionen fuer Operationen mit Matrizen * * Datum: Autor: Grund der Aenderung: * * \**********************************************************************/ /*--- #includes ------------------------------------------------------*/ #include #include #include #include #include "matrixOp.h" /*--------------------------------------------------------------------*\ * Erstellt eine neue Matrix (cM) * - reserviert lediglich den notwendigen Speicher * - dynamische Verwaltung von Speicher muss mit malloc() und free() * durchgef�hrt werden; dynamische Arrays sind nicht erlaubt !!! \*--------------------------------------------------------------------*/ Matrix createMatrix(unsigned int spalten, unsigned int zeilen) { Matrix m; m.spalten = spalten; m.zeilen = zeilen; m.mElement = (MatTyp *)malloc(sizeof(MatTyp) * spalten * zeilen); return m; } /*--------------------------------------------------------------------*\ * Erstellt und initialisiert eine neue Matrix (zM) * - reserviert den notwendigen Speicher * - befuellt die Matrix mit 0 \*--------------------------------------------------------------------*/ Matrix createMatrixZero(unsigned int spalten, unsigned int zeilen) { Matrix m = createMatrix(spalten, zeilen); if (m.mElement != NULL) { for (unsigned int i = 0; i < spalten * zeilen; i++) { m.mElement[i] = 0.0f; } } return m; } /*--------------------------------------------------------------------*\ * Erstellt und initialisiert eine neue Matrix (rM) * - reserviert den notwendigen Speicher * - befuellt die Matrix mit Zufallszahlen \*--------------------------------------------------------------------*/ Matrix createMatrixRand(unsigned int spalten, unsigned int zeilen) { Matrix m = createMatrix(spalten, zeilen); srand((unsigned int)time(NULL)); for (unsigned int i = 0; i < spalten * zeilen; i++) { m.mElement[i] = ((float)rand() / RAND_MAX) * 200.0f - 100.0f; } return m; } /*--------------------------------------------------------------------*\ * Kopiert eine Matrix und gibt die Kopie zurueck (yM) \*--------------------------------------------------------------------*/ Matrix copyMatrix(const Matrix toCopy) { Matrix copy = createMatrix(toCopy.spalten, toCopy.zeilen); for (unsigned int i = 0; i < toCopy.spalten * toCopy.zeilen; i++) { copy.mElement[i] = toCopy.mElement[i]; } return copy; } /*--------------------------------------------------------------------*\ * "Loescht" eine Matrix (dM) * - gibt reservierten Speicher wieder frei ! * - in der urspruenglichen, uebergebenen Matrix bleiben die Werte erhalten! \*--------------------------------------------------------------------*/ void deleteMatrix(Matrix toDelete) { free(toDelete.mElement); } /*--------------------------------------------------------------------*\ * "Loescht / Zerstoert" eine uebergegebene Matrix (ddM) * - gibt Speicher wieder frei, setzt alle Werte auf NULL bzw. "0" ! * - Beachte Unterschiede zur vorigen Funktion !!! \*--------------------------------------------------------------------*/ void destroyMatrix(Matrix *pToDestroy) { if (pToDestroy->mElement != NULL) { free(pToDestroy->mElement); pToDestroy->mElement = NULL; pToDestroy->spalten = 0; pToDestroy->zeilen = 0; } } /*--------------------------------------------------------------------*\ * Gibt den Eintrag der Matrix an der Stelle (xPos, yPos) zurueck (gE) * Rueckgabe im Fehlerfall: ERROR \*--------------------------------------------------------------------*/ MatTyp getEntryAt(const Matrix ma, unsigned int xPos, unsigned int yPos) { if (xPos >= ma.spalten || yPos >= ma.zeilen) return ERROR; return ma.mElement[yPos * ma.spalten + xPos]; } /*--------------------------------------------------------------------*\ * Setzt den Eintrag der Matrix an der Stelle (xPos, yPos) (sE) * Rueckgabe: TRUE, im Fehlerfall: FALSE \*--------------------------------------------------------------------*/ Bool setEntryAt(Matrix ma, unsigned int xPos, unsigned int yPos, MatTyp value) { if (xPos >= ma.spalten || yPos >= ma.zeilen) return FALSE; ma.mElement[yPos * ma.spalten + xPos] = value; return TRUE; } /*--------------------------------------------------------------------*\ * Gibt eine Matrix im Kommandofenster "schoen formatiert" aus (pM) \*--------------------------------------------------------------------*/ void printMatrix(const Matrix ma) { printf("(\n"); for (unsigned int y = 0; y < ma.zeilen; y++) { printf(" "); for (unsigned int x = 0; x < ma.spalten; x++) { printf("%6.2f ", getEntryAt(ma, x, y)); } printf(")\n"); } } /*--------------------------------------------------------------------*\ * Addiert zwei Matrizen (aM) * Rueckgabe: * - Ergebnis der Addition in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ Matrix addMatrix(const Matrix ma, const Matrix mb) { if (ma.spalten != mb.spalten || ma.zeilen != mb.zeilen) { return createMatrix(0, 0); } Matrix result = createMatrix(ma.spalten, ma.zeilen); for (unsigned int i = 0; i < ma.spalten * ma.zeilen; i++) { result.mElement[i] = ma.mElement[i] + mb.mElement[i]; } return result; } /*--------------------------------------------------------------------*\ * Subtrahiert zwei Matrizen (sM) * Rueckgabe: "ma - mb" * - Ergebnis der Subtraktion in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ Matrix subMatrix(const Matrix ma, const Matrix mb) { if (ma.spalten != mb.spalten || ma.zeilen != mb.zeilen) { return createMatrix(0, 0); } Matrix result = createMatrix(ma.spalten, ma.zeilen); for (unsigned int i = 0; i < ma.spalten * ma.zeilen; i++) { result.mElement[i] = ma.mElement[i] - mb.mElement[i]; } return result; } /*--------------------------------------------------------------------*\ * Multipliziert zwei Matrizen (mM) * Rueckgabe: "ma * mb" * - Ergebnis der Multiplikation in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ Matrix multMatrix(const Matrix ma, const Matrix mb) { if (ma.spalten != mb.zeilen) return createMatrix(0, 0); Matrix result = createMatrix(mb.spalten, ma.zeilen); for (unsigned int y = 0; y < result.zeilen; y++) { for (unsigned int x = 0; x < result.spalten; x++) { float sum = 0.0f; for (unsigned int k = 0; k < ma.spalten; k++) { sum += getEntryAt(ma, k, y) * getEntryAt(mb, x, k); } setEntryAt(result, x, y, sum); } } return result; } /*--------------------------------------------------------------------*\ * Transponiert eine Matrix (tM) * Rueckgabe: "ma^T" \*--------------------------------------------------------------------*/ Matrix transposeMatrix(const Matrix ma) { Matrix transposed = createMatrix(ma.zeilen, ma.spalten); for (unsigned int y = 0; y < ma.zeilen; y++) { for (unsigned int x = 0; x < ma.spalten; x++) { setEntryAt(transposed, y, x, getEntryAt(ma, x, y)); } } return transposed; } /*--------------------------------------------------------------------*\ * Gibt die Determinante der Matrix ma zurueck (dt) * Rueckgabe im Fehlerfall: ERROR * !!! Optional / Implementation freiwillig !!! * fuer kleine Matrizen reicht ein einfacher Algorithmus * wer moechte kann auch ein effizientes Verfahren implementieren \*--------------------------------------------------------------------*/ double determMatrix(const Matrix ma) { if (ma.spalten != 2 || ma.zeilen != 2) return ERROR; float a = getEntryAt(ma, 0, 0); float b = getEntryAt(ma, 1, 0); float c = getEntryAt(ma, 0, 1); float d = getEntryAt(ma, 1, 1); return a * d - b * c; }