212 lines
8.1 KiB
C
212 lines
8.1 KiB
C
/**********************************************************************\
|
|
* Kurzbeschreibung: matrixOp.c
|
|
* Bietet Funktionen fuer Operationen mit Matrizen
|
|
*
|
|
* Datum: Autor: Grund der Aenderung:
|
|
*
|
|
*
|
|
\**********************************************************************/
|
|
|
|
/*--- #includes ------------------------------------------------------*/
|
|
#include <float.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include "matrixOp.h"
|
|
|
|
/*--------------------------------------------------------------------*\
|
|
* Erstellt eine neue Matrix (cM)
|
|
* - reserviert lediglich den notwendigen Speicher
|
|
* - dynamische Verwaltung von Speicher muss mit malloc() und free()
|
|
* durchgef<65>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.0;
|
|
}
|
|
}
|
|
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.0 - 100.0;
|
|
}
|
|
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.0;
|
|
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;
|
|
}
|