diff --git a/TestMatrix.c b/TestMatrix.c index 8c5d564..8aae28b 100644 --- a/TestMatrix.c +++ b/TestMatrix.c @@ -26,25 +26,89 @@ /*--- Funktionsdefinitionen ------------------------------------------*/ /*--- main -----------------------------------------------------------*/ -int main(void) -{ - unsigned int z, s; - float firstElem; +int main(void) { + unsigned int zeilen, spalten; + float startWert; printf("Test verschiedener Funktionen der Bibliothek\n"); - printf("Gew\x81nschte Matrizen-Gr\x94sse eingeben\n Zeilen, Spalten (> 0; z.B.: 3,4):"); - scanf("%d,%d", &z, &s); - printf("Matrix Elemente eingeben (F. Test nur 1.Elem.,\n weitere Elemente werden mit +1 erzeugt)\n"); - printf(" Element in [1,1] (z.B.: 4.5):"); - scanf("%f", &firstElem); + printf("Gewuenschte Matrizen-Groesse eingeben\n"); + printf(" Zeilen, Spalten (> 0; z.B. 3,4): "); + scanf("%u,%u", &zeilen, &spalten); - createMatrix(s, z); - printf("Test Create Zero und Rand:\n"); - printf("CreateMatrixZero: a[%u,%u]=\n", z, s); - Matrix zeroMat = createMatrixZero(s, z); - printMatrix(zeroMat); + Matrix a = createMatrix(spalten, zeilen); - printf("CreateMatrixRand: a[%u,%u]=\n", z, s); - Matrix randMat = createMatrixRand(s, z); + printf("Matrix Elemente eingeben (F. Test nur 1.Elem., weitere Elemente werden mit +1 erzeugt)\n"); + printf(" Element in [1,1] (z.B.: 4.5): "); + scanf("%f", &startWert); + + float wert = startWert; + for (unsigned int y = 0; y < zeilen; y++) { + for (unsigned int x = 0; x < spalten; x++) { + setEntryAt(a, x, y, wert); + wert += 1.0f; + } + } + + printf("\nTest Create Zero und Rand:\n"); + + Matrix zero = createMatrixZero(spalten, zeilen); + printf("CreateMatrixZero: a[%d,%d]=\n", spalten, zeilen); + printMatrix(zero); + + printf("\nInfo: Called srand!\n"); + srand((unsigned int)time(NULL)); + Matrix randMat = createMatrixRand(spalten, zeilen); + printf("CreateMatrixRand: a[%d,%d]=\n", spalten, zeilen); printMatrix(randMat); + + printf("\nTests mit eingegebenen Werten:\n"); + printf("CreateMatrix: a[%d,%d]=\n", spalten, zeilen); + printMatrix(a); + + Matrix b = copyMatrix(a); + printf("\nCreateMatrix: b[%d,%d]=\n", spalten, zeilen); + printMatrix(b); + + Matrix sum = addMatrix(a, b); + printf("\nc[%d,%d]= a + b =\n", sum.spalten, sum.zeilen); + printMatrix(sum); + + Matrix diff = subMatrix(a, b); + printf("\nc[%d,%d]= a - b =\n", diff.spalten, diff.zeilen); + printMatrix(diff); + + Matrix bT = transposeMatrix(b); + printf("\nc[%d,%d]= b^T\n", bT.spalten, bT.zeilen); + printMatrix(bT); + + Matrix c = multMatrix(a, bT); // a * b^T + printf("a * b^T = c\n"); + + // Nur die obere linke 2x2-Matrix drucken + printf("{\n"); + for (int y = 0; y < 2; y++) { + printf(" "); + for (int x = 0; x < 2; x++) { + printf("%6.2f", getEntryAt(c, x, y)); + if (x < 1) printf(" "); + } + printf("\n"); + } + printf("}\n"); + + + printf("\ndet(c) = %.2f\n", determMatrix(c)); + + // Speicher freigeben + destroyMatrix(&a); + destroyMatrix(&b); + destroyMatrix(&sum); + destroyMatrix(&diff); + destroyMatrix(&zero); + destroyMatrix(&randMat); + destroyMatrix(&bT); + destroyMatrix(&c); + + return 0; } + diff --git a/matrixOp.c b/matrixOp.c index 27e3194..31cc529 100644 --- a/matrixOp.c +++ b/matrixOp.c @@ -14,29 +14,18 @@ #include #include "matrixOp.h" -/*--- #defines -------------------------------------------------------*/ - -/*--- Lokale Datentypen (typedef) ------------------------------------*/ - -/*--- Modulglobale static Variablen ----------------------------------*/ - -/*--- Prototypen lokaler Funktionen ----------------------------------*/ - -/*--- Funktionsdefinitionen ------------------------------------------*/ - -/*--------------------------------------------------------------------*\ +/*--------------------------------------------------------------------*\ * Erstellt eine neue Matrix (cM) * - reserviert lediglich den notwendigen Speicher -* - dynamische Verwaltung von Speicher muss mit malloc() und free() +* - 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 matrix1; - matrix1.mElement = (float *)malloc(spalten * zeilen * sizeof(float)); - matrix1.zeilen = zeilen; - matrix1.spalten = spalten; - return matrix1; +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; } /*--------------------------------------------------------------------*\ @@ -44,19 +33,14 @@ Matrix createMatrix(unsigned int spalten, unsigned int zeilen) * - reserviert den notwendigen Speicher * - befuellt die Matrix mit 0 \*--------------------------------------------------------------------*/ -Matrix createMatrixZero(unsigned int spalten, unsigned int zeilen) -{ - Matrix matrix1 = createMatrix(spalten,zeilen); - - float inhalt[zeilen][spalten]; - //matrix1.mElement = *inhalt; - - for (int i = 0; i < zeilen; ++i) { - for (int j = 0; j < spalten; ++j) { - inhalt[i][j] = 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 matrix1; + return m; } /*--------------------------------------------------------------------*\ @@ -64,28 +48,24 @@ Matrix createMatrixZero(unsigned int spalten, unsigned int zeilen) * - reserviert den notwendigen Speicher * - befuellt die Matrix mit Zufallszahlen \*--------------------------------------------------------------------*/ -Matrix createMatrixRand(unsigned int spalten, unsigned int zeilen) -{ - Matrix matrix1 = createMatrix(spalten,zeilen); - - float inhalt[zeilen][spalten]; - - for (int i = 0; i < zeilen; ++i) { - for (int j = 0; j < spalten; ++j) { - inhalt[i][j] = 69; - } +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 matrix1; + return m; } /*--------------------------------------------------------------------*\ * Kopiert eine Matrix und gibt die Kopie zurueck (yM) \*--------------------------------------------------------------------*/ -Matrix copyMatrix(const Matrix toCopy) -{ - // TODO - return toCopy; +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; } /*--------------------------------------------------------------------*\ @@ -93,54 +73,55 @@ Matrix copyMatrix(const Matrix toCopy) * - gibt reservierten Speicher wieder frei ! * - in der urspruenglichen, uebergebenen Matrix bleiben die Werte erhalten! \*--------------------------------------------------------------------*/ -void deleteMatrix(Matrix toDelete) -{ - // TODO +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 !!! +* - Beachte Unterschiede zur vorigen Funktion !!! \*--------------------------------------------------------------------*/ -void destroyMatrix(Matrix *pToDestroy) -{ - // TODO +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) -{ - // TODO - return *ma.mElement; +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) -{ - // TODO +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) -{ - float inhalt[ma.zeilen][ma.spalten]; - //inhalt[0][0] = *ma.mElement; - - for (int i = 0; i < ma.zeilen; ++i) { - for (int j = 0; j < ma.spalten; ++j) { - printf("%.2f\t", inhalt[i][j]); +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"); + printf(")\n"); } } @@ -150,10 +131,15 @@ void printMatrix(const Matrix ma) * - Ergebnis der Addition in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ -Matrix addMatrix(const Matrix ma, const Matrix mb) -{ - // TODO - return ma; +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; } /*--------------------------------------------------------------------*\ @@ -162,10 +148,15 @@ Matrix addMatrix(const Matrix ma, const Matrix mb) * - Ergebnis der Subtraktion in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ -Matrix subMatrix(const Matrix ma, const Matrix mb) -{ - // TODO - return ma; +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; } /*--------------------------------------------------------------------*\ @@ -174,20 +165,33 @@ Matrix subMatrix(const Matrix ma, const Matrix mb) * - Ergebnis der Multiplikation in neu erzeugter Matrix * - Rueckgabe im Fehlerfall: Matrix der Groesse "0" \*--------------------------------------------------------------------*/ -Matrix multMatrix(const Matrix ma, const Matrix mb) -{ - // TODO - return ma; +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) -{ - // TODO - return ma; +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; } /*--------------------------------------------------------------------*\ @@ -197,9 +201,11 @@ Matrix transposeMatrix(const Matrix ma) * fuer kleine Matrizen reicht ein einfacher Algorithmus * wer moechte kann auch ein effizientes Verfahren implementieren \*--------------------------------------------------------------------*/ -double determMatrix(const Matrix ma) -{ - // TODO - return 6.9; +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; } -