aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2024-10-13 19:28:57 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2024-10-13 19:28:57 +0300
commitf5e0076a8455eec5b4a515b39202217f8a8b9e71 (patch)
treef5cd306d8eb2a516e2d3a83a9276d5aa60b658c0 /src
parent1fe251abc83ee3a38d9faea5be947c90d162c6ae (diff)
Initial committask5
Diffstat (limited to 'src')
-rw-r--r--src/integral.c36
-rw-r--r--src/main.c186
-rw-r--r--src/roots.c94
3 files changed, 0 insertions, 316 deletions
diff --git a/src/integral.c b/src/integral.c
deleted file mode 100644
index f791803..0000000
--- a/src/integral.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "integral.h"
-
-// эта переменная позволяет контролировать точность интегрирования
-// и может быть установлена в файле main
-double accrc = 10000.0;
-
-// интеграл прямоугольниками
-double int_rect(func_t f, double a, double b) {
- const double dx = (b-a) / accrc;
- const double dx_2 = dx / 2.0;
- double sum = 0.0;
- for (double i = a + dx; i < b; i += dx)
- sum += f(i - dx_2) * dx;
- return sum;
-}
-
-// интеграл трапециями
-double int_trap(func_t f, double a, double b) {
- const double dx = (b-a) / accrc;
- double sum = 0.0;
- for (double i = a; i < b; i += dx)
- sum += dx * (f(i) + f(i+dx))/2 ;
- return sum;
-}
-
-// интегрирование параболами
-double int_simp(func_t f, double a, double b) {
- const double dx = (b-a) / accrc;
- const double dx_2 = dx / 2;
- const double dx_6 = dx / 6;
- double sum = 0.0;
- for(double i = a; i < b; i += dx) {
- sum += dx_6 * (f(i) + 4 * f(i + dx_2) + f(i + dx));
- }
- return sum;
-}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index ff1a59e..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <unistd.h>
-#include <termios.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <dlfcn.h>
-
-#include "integral.h"
-#include "roots.h"
-
-#define BLINK_TERM "\x1b[5m"
-#define RESET_TERM "\x1b[0m"
-#define FIFO_NAME "/tmp/compiler.tmp"
-#define SYMNAME "f"
-#define RDCHUNK 1024
-
-void *sohandle = NULL;
-
-#define defer(val) do {ret = val; goto exit;} while(0)
-
-// This will be the type of the function
-typedef double(*func_t)(double);
-
-typedef double(*calc2_t)(func_t, double, double);
-typedef double(*calc3_t)(func_t, double, double, double);
-typedef double(*calc4_t)(func_t, double, double, double, double);
-
-// для выбора того, что делать с функцией
-enum optype {
- // решение уравнений
- SOL_BINSR, // дихтомии
- SOL_CHORD, // хорды
- SOL_NEWTN, // касательные
- SOL_ITERN, // итерации
- // численное интегрирование
- INT_RECT, // прямоугольники
- INT_TRAP, // трапеции
- INT_SIMP, // симпсон
-};
-
-struct funcdescr {
- void *f;
- int argc;
- const char *descr;
-};
-
-#define DESCR2 "начало и конец области интегрирования\n"
-#define DESCR3 "начальное приближение, допустимую погрешность корня и невязку\n"
-#define DESCR4 "левую и правую границы поиска, допустимую погрешность корня и невязку\n"
-
-static struct funcdescr functions[] = {
- [SOL_BINSR] = {&sol_binsr, 4, DESCR4},
- [SOL_CHORD] = {&sol_chord, 4, DESCR4},
- [SOL_NEWTN] = {&sol_newtn, 3, DESCR3},
- [SOL_ITERN] = {&sol_itern, 3, DESCR3},
- [INT_RECT] = {&int_rect, 2, DESCR2},
- [INT_TRAP] = {&int_trap, 2, DESCR2},
- [INT_SIMP] = {&int_simp, 2, DESCR2},
-};
-
-// Function that reads Your function, compiles and loads it.
-func_t input_and_compile(void) {
- puts("Напечатайте функцию от x используя синтаксис С и функции библиотеки cmath: \n"
- "(например, 'atan(x) / (1-exp(2*x))').\n"
- "Закончите ввод, нажав enter." BLINK_TERM);
- func_t ret;
- char *buffer = NULL, *source = NULL;
-
- // input the function
- size_t blen = 1024;
- buffer = malloc(sizeof (char) * blen);
- blen = read(STDIN_FILENO, buffer, 1024);
- buffer[--blen] = '\0';
- if (blen <= 0) defer(NULL);
- puts(RESET_TERM);
-
- // format the source
- const char *fmt =
- "#include <math.h>\n"
- "double " SYMNAME "(double x) { return %s; }\n";
- size_t sourcelen = strlen(fmt) - strlen("%s") + blen + 1;
- source = malloc(sizeof (char) * sourcelen);
- snprintf(source, sourcelen, fmt, buffer);
-
- // spawn the compiler process
- FILE *cc = popen("cc -shared -fPIE -fPIC -o " FIFO_NAME " -xc - -lm", "w");
- fwrite(source, sizeof (char), sourcelen - 1, cc);
- if (ferror(cc)) { pclose(cc); defer(NULL); }
- if (pclose(cc) != 0) defer(NULL);
-
- // load dynamic library
- sohandle = dlopen(FIFO_NAME, RTLD_NOW);
- if (!sohandle) defer(NULL);
- ret = dlsym(sohandle, SYMNAME);
-
- // free resources and return
-exit:
- free(buffer);
- free(source);
- return ret;
-}
-
-char _getchar(void) {
- char ret;
- while (isspace(ret = getchar()));
- return ret;
-}
-
-// Prompts user to choose input method
-enum optype get_optype(void) {
-prompt_init:
- fputs("Что вы хотите сделать с функцией?\n"
- "\t1: решить уравнение f(x) = x\n"
- "\t2: решить уравнение f(x) = 0\n"
- "\t3: численно вычислить интеграл f(x)\n"
- "Введите число: ", stdout);
- char c;
- switch (_getchar()-'0') {
- case 1: return SOL_ITERN;
-
- case 2:
- prompt_sol:
- fputs("\nКаким методом?\n"
- "\t1: дихтомии (двоичный поиск)\n"
- "\t2: хорд\n"
- "\t3: касательных (Ньютона)\n"
- "Введите число:", stdout);
- c = _getchar() - '0';
- if (c <= 0 || c > 3) goto prompt_sol;
- return SOL_BINSR + c - 1;
-
- case 3:
- prompt_int:
- fputs("\nКаким методом?\n"
- "\t1: прямоугольников\n"
- "\t2: трапеций\n"
- "\t3: Симпсона (парабол)\n"
- "Введите число: ", stdout);
- c = _getchar() - '0';
- if (c <= 0 || c > 3) goto prompt_int;
- return INT_RECT + c - 1;
-
- default:
- puts("\nОшибка: ведите число от 1 до 3");
- goto prompt_init;
- }
-}
-
-int main(void) {
- func_t f = input_and_compile();
- if (!f) goto exit;
- struct funcdescr descr = functions[get_optype()];
- double a, b, c, d;
- printf("Введите %i аргумента через пробел:\n\t%s\n", descr.argc, descr.descr);
- double res;
- switch (descr.argc) {
- case 2:
- scanf("%lf %lf", &a, &b);
- res = ((calc2_t)descr.f)(f, a, b);
- break;
- case 3:
- scanf("%lf %lf %lf", &a, &b, &c);
- res = ((calc3_t)descr.f)(f, a, b, c);
- break;
- case 4:
- scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
- res = ((calc4_t)descr.f)(f, a, b, c, d);
- break;
- default: __builtin_unreachable();
- }
- if (!is_root_ok()) {
- fputs("Корень не посчитан из-за ограничений метода\n", stderr);
- goto exit;
- }
- printf("Результат: %lf\n", res);
-exit:
- if (sohandle) dlclose(sohandle);
- remove(FIFO_NAME);
- return 0;
-}
diff --git a/src/roots.c b/src/roots.c
deleted file mode 100644
index f07240e..0000000
--- a/src/roots.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "roots.h"
-#include <math.h>
-#include <stdio.h>
-
-char root_ok = 1;
-
-// функция для проверки того, успешно ли выполнилась последняя функция
-char is_root_ok(void) {
- return root_ok;
-}
-
-// метод дихтомии
-double sol_binsr(func_t f, double a, double b, double ex, double ey) {
- if (copysign(1.0, f(a)) == copysign(1.0, f(b))) {
- root_ok = 0;
- return NAN;
- }
-
- double mid;
- do {
- mid = (a + b) / 2;
- if (copysign(1.0, f(a)) != copysign(1.0, f(mid))) b = mid;
- else a = mid;
- } while (f(mid) > ey || (b-a) > ex);
- root_ok = 1;
- return mid;
-}
-
-// метод хорд
-double sol_chord(func_t f, double a, double b, double ex, double ey) {
- if (copysign(1.0, f(a)) == copysign(1.0, f(b))) {
- root_ok = 0;
- return NAN;
- }
- double mid = a + fabs( f(a) / (f(b)-f(a)) ) * (b-a);
- double diff = mid;
- while (f(mid) > ey || fabs(diff - mid) > ex) {
- diff = mid;
- mid = a + fabs( f(a) / (f(b)-f(a)) ) * (b-a);
- if (copysign(1.0, f(a)) != copysign(1.0, f(mid))) b = mid;
- else a = mid;
- }
- root_ok = 1;
- return mid;
-
-}
-
-// метод касательных (Ньютона)
-double sol_newtn(func_t f, double x0, double ex, double ey) {
- const double dx = 1e-6;
- double diff = x0+2*ex;
-
- // check for divergence
- double d2x0 = (f(x0 + 2*dx) - 2*f(x0 + dx) + f(x0))/(dx*dx);
- if (copysign(1.0, d2x0) != copysign(1.0, f(x0))) {
- root_ok = 0;
- return NAN;
- }
- while ((fabs(diff - x0) > ex || f(x0) > ey)) {
- double fx0 = f(x0);
- double dx0 = (f(x0+dx) - fx0) / dx;
- diff = x0;
- x0 -= fx0/dx0;
- if (isinf(x0) || isnan(x0)) {
- root_ok = 0;
- return NAN;
- }
- }
- root_ok = 1;
- return x0;
-}
-
-// метод итераций
-double sol_itern(func_t f, double x0, double ex, double ey) {
- const double dx = 1e-6;
- double diff = x0 + 2*ex;
-
- do {
- double dx0 = (f(x0+dx) - f(x0))/dx;
- if (fabs(dx0) > 1.0) {
- root_ok = 0;
- return NAN;
- }
- diff = x0;
- x0 = f(x0);
- printf("x0=%lf, f(x0)=%lf\n", x0, f(x0));
- getchar();
- } while (fabs(diff - x0) > ex || fabs(f(x0) - x0) > ey);
- root_ok = 1;
- return x0;
-}
-
-
-