aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/integral.c8
-rw-r--r--src/main.c109
-rw-r--r--src/roots.c8
3 files changed, 98 insertions, 27 deletions
diff --git a/src/integral.c b/src/integral.c
index d2ae11f..f791803 100644
--- a/src/integral.c
+++ b/src/integral.c
@@ -5,8 +5,7 @@
double accrc = 10000.0;
// интеграл прямоугольниками
-double int_rect(f_t f, double a, double b) {
- // f(x + dx/2) * dx
+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;
@@ -16,8 +15,7 @@ double int_rect(f_t f, double a, double b) {
}
// интеграл трапециями
-double int_trap(f_t f, double a, double b) {
- // ( f(x) + f(x+dx) )/2 * dx
+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)
@@ -26,7 +24,7 @@ double int_trap(f_t f, double a, double b) {
}
// интегрирование параболами
-double int_simp(f_t f, double a, double b) {
+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;
diff --git a/src/main.c b/src/main.c
index c3844f0..79251a5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <math.h>
#include <unistd.h>
#include <sys/fcntl.h>
@@ -22,12 +21,17 @@
void *sohandle;
// This will be the type of the function
-typedef double(*f_t)(double);
+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_HORDE, // хорды
+ SOL_CHORD, // хорды
SOL_NEWTN, // касательные
SOL_ITERN, // итерации
// численное интегрирование
@@ -36,8 +40,28 @@ enum optype {
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.
-f_t input_and_compile(void) {
+func_t input_and_compile(void) {
puts("Напечатайте функцию от x используя синтаксис С и функции библиотеки cmath: \n"
"(например, 'atan(x) / (1-exp(2*x))').\n"
"Закончите ввод, нажав enter." BLINK_TERM);
@@ -67,7 +91,7 @@ f_t input_and_compile(void) {
// load dynamic library
sohandle = dlopen(FIFO_NAME, RTLD_NOW);
if (!sohandle) return NULL;
- f_t ret = dlsym(sohandle, SYMNAME);
+ func_t ret = dlsym(sohandle, SYMNAME);
// free resources and return
free(buffer);
@@ -77,22 +101,71 @@ f_t input_and_compile(void) {
// Prompts user to choose input method
enum optype get_optype(void) {
- return INT_SIMP;
+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(int argc, char *argv[]) {
- (void)argc; (void)argv;
- f_t f = input_and_compile();
+int main(void) {
+ func_t f = input_and_compile();
if (!f) goto exit;
- double sln = sol_binsr(f, 0, 10, 0.001, 0.001);
- printf("%lf\n", sln);
- sln = sol_binsr(f, 0, 10, 0.001, 0.001);
- printf("%lf\n", sln);
- sln = sol_newtn(f, 5, 0.001, 0.001);
- printf("%lf\n", sln);
- sln = sol_itern(f, 0, 0.001, 0.001);
- printf("%lf\n", sln);
-
+ 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:
dlclose(sohandle);
return 0;
diff --git a/src/roots.c b/src/roots.c
index 0aef762..f07240e 100644
--- a/src/roots.c
+++ b/src/roots.c
@@ -10,7 +10,7 @@ char is_root_ok(void) {
}
// метод дихтомии
-double sol_binsr(f_t f, double a, double b, double ex, double ey) {
+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;
@@ -27,7 +27,7 @@ double sol_binsr(f_t f, double a, double b, double ex, double ey) {
}
// метод хорд
-double sol_chord(f_t f, double a, double b, double ex, double ey) {
+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;
@@ -46,7 +46,7 @@ double sol_chord(f_t f, double a, double b, double ex, double ey) {
}
// метод касательных (Ньютона)
-double sol_newtn(f_t f, double x0, double ex, double ey) {
+double sol_newtn(func_t f, double x0, double ex, double ey) {
const double dx = 1e-6;
double diff = x0+2*ex;
@@ -71,7 +71,7 @@ double sol_newtn(f_t f, double x0, double ex, double ey) {
}
// метод итераций
-double sol_itern(f_t f, double x0, double ex, double ey) {
+double sol_itern(func_t f, double x0, double ex, double ey) {
const double dx = 1e-6;
double diff = x0 + 2*ex;