MMS-Loesung-2024-25/MMS24-25.c

185 lines
4.8 KiB
C

/* =========================STYLE-GUIDELINES===========================
* All comments use MD-Syntax;
* Formulas are written in KaTeX/TeX Syntax.
* We adhere by the `kernel.org` style-guidelines.
* See: https://www.kernel.org/doc/html/v4.10/process/coding-style.html
* =============================AUTHORS================================
* Created by Frederik Beimgraben, Minh Dan Cam and Lea Hornberger in
* the winter term of 2024/25 at the faculty of computer science at
* Reutlingen University.
* After grading the full source code will be available at:
* https://git.beimgraben.net/MMS-2024-25/MMS-Loesung-2024-25.git
*/
#include "MMS24-25.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>
#include "MMS24-25.h"
#include <stdio.h>
#include <stdarg.h>
void _error(char *fmt, ...) {
fprintf(stderr, "<\x1B[31;1m ERROR \x1B[0m: \x1B[34m'");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m >\n");
#ifndef _TESTS_NONSTOP
exit(EXIT_FAILURE);
#endif
}
void _debug(char *fmt, ...) {
fprintf(stderr, "[\x1B[31;1m DEBUG \x1B[0m] \x1B[34m'");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m\n");
}
void _warn(char *fmt, ...) {
fprintf(stderr, "[\x1B[33;1m WARN \x1B[0m] \x1B[34m'");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m\n");
}
double interpolateLine(
double dX1,
double dY1,
double dX2,
double dY2,
double dXq
) {
if (dX2 == dX1)
_error("interpolateLine: dX1 and dX2 must differ!");
double y = dY1 *(
(dX2 - dXq) / (dX2 - dX1)
) + dY2 *(
(dXq - dX1) / (dX2 - dX1)
);
#ifdef _DEBUG_
// DEBUG: print the parameters and result
_debug("interpolateLine(%lf, %lf, %lf, %lf, %lf) -> %lf\n",
dX1,dY1,dX2,dY2,dXq,y);
#endif
return y;
}
void rescaleDoubleArray(
double *pdIn,
int iLen,
double dMin,
double dFactor,
double *pdOut
) {
/* Rescale an array of double values, so that the following rules apply:
* Given $ |pdIn| = |pdOut| = iLen $ it should be, that:
* $ min(pdIn) > dMin $, as well as
* \[ \forall i, j \in (0,\dots,iLen-1):
* (pdOut_i - pdOut_j) = (pdIn_i - pdIn_j) *dFactor \],
* which naturally results from:
* $ pdOut_i = pdIn_i *dFactor + dMin $
*/
for (int i = 0; i < iLen; i++) {
pdOut[i] = pdIn[i] *dFactor + dMin;
}
}
double *generateSineValues(
int iNumValues,
int iNumSamplesPerPeriod,
double dAmp
) {
/* Generate an array of `iNumValues` double value, so that the values
* represent the Y-coordinates of a sine curve of which one full period
* occupies `iNumSamplesPerPeriod` values.
*/
if (iNumSamplesPerPeriod == 0)
_error("*generateSineValues: iNumSamplesPerPeriod must be non-0!");
if (iNumSamplesPerPeriod < 0)
_warn("*generateSineValues: iNumSamplesPerPeriod is less than 0!");
if (iNumValues < 0)
_error("*generateSineValues: iNumValues must be equal to or greater than 0!");
if (iNumValues == 0)
_warn("*generateSineValues: iNumValues is 0!");
// Initialize the output array
double *sineArray = NULL;
sineArray = (double*) malloc(sizeof(double) *iNumValues);
if (sineArray == NULL)
_error("*generateSineValues: Failed to allocate memory for Sine Array\n");
for (int i=0; i<iNumValues;i++){
sineArray[i] = dAmp*sin(((2*M_PI)/iNumSamplesPerPeriod) *i);
}
return sineArray;
}
void writeDoubleArray(double *pdOut, int iLen, char *pcOutName) {
// Write a list of double values to a file
FILE *file = fopen(pcOutName, "w");
if (file == NULL)
_error("writeDoubleArray: Error while opening file '%s'.\n", pcOutName);
for (int i = 0; i < iLen; i++) {
fprintf(file, "%f\n", pdOut[i]);
}
fclose(file);
}
int readDoubleArray(char *pcInName, double **ppdIn) {
char *line = NULL;
size_t len = 0;
ssize_t read;
int i = 0;
*ppdIn = NULL;
FILE *file = fopen(pcInName, "r");
if (file == NULL)
_error("readDoubleArray: Error while opening file '%s'.\n", pcInName);
while ((read = getline(&line, &len, file)) != -1) {
if (*ppdIn == NULL) {
*ppdIn = (double*) malloc(sizeof(double));
} else {
*ppdIn = (double*) realloc(*ppdIn, sizeof(double) *(i+1));
}
if (*ppdIn == NULL)
_error("readDoubleArray: Failed to allocate or re-allocate memory for pdIn\n");
(*ppdIn)[i] = atof(line);
i++;
}
free(line);
fclose(file);
return i;
}