Страницы

Поиск по вопросам

Показаны сообщения с ярлыком формулы. Показать все сообщения
Показаны сообщения с ярлыком формулы. Показать все сообщения

четверг, 9 января 2020 г.

Формула в строку Java

#java #строки #формулы


Задача: Составить таблицу значений функции y = f(x) на отрезке [n; m] с шагом k

Собственно вопрос возникает в моменте. Как ввести f(x). Ибо сама формула (для примера
х-2), является строкой, а значение Y числом. 
т.е. Через сканер вводим все значения n,m,k и саму формулу "x-2" или любую другую.
И в коде эту формулу применяем для подсчета значение Y.

while(x<=r.m){
        y=x-5;
        System.out.println("x = " +x+" y = "+ y);
        x=x+r.k;
}


В данном случае у меня стоит формула, введенная изначально "y=х-5" (вторая строчка,
введено топорно, прямо в код), а мне надо, чтоб программа считала ту, которую я введу
через сканер.

upd. После большого количества прочитанного и опробованного, хочется добавить, что
введеное через сканер представляет собой цисловые значения, букву X и знаки арифметических
вычислений ("+","-","/","*"). 
    


Ответы

Ответ 1



Решение ленивого человека выглядит так: import javax.script.*; public class Eval { public static void main (String[] args) throws Exception { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("nashorn"); engine.put("x", 1); System.out.println(engine.eval("x * 2 + 1")); } } В Java есть полноценный движок JavaScript (на русском), который отлично справляется с вычислением произвольных математических выражений (и не только их). Решение же человека, которому описанная задача прилетела в виде лабораторной работы или домашнего задания выглядит сложнее. Преподаватель, скорее всего, ожидает, что вы разберёте вводимую строку на токены (переменная, оператор, число), переведёте её в обратную польскую запись, а затем вычислите, используя стековую машину (раз, два).

пятница, 13 декабря 2019 г.

Составить рекуррентную формулу на Си (от n=0, это важно)

#c #формулы


Есть вот такая формула, надо сравнить левую часть и правую с использованием  такого ряда.
В задании сказано посчитать правую часть, то бишь формулу суммы, c использованием
рекуррентной формулы. Помогите написать часть кода на Си, где будет считать эту сумму
с циклом DO WHILE и рекуррентной формулой! Нельзя использовать pow, надо использовать
отдельную переменную для суммирования. Я такое сделал с функцией, но сказали, что надо
рекуррентную формулу, а вывести ее у меня не выходит.

  s = 0; xn = x; n = 0;
  do {
    an = (factorial(2 * n) * xn) / (factorial(n)*factorial(n) * (n + 1));
    s += an;
    n++; xn *= x;
  } while (fabs(an) > eps && n <= lim);




int factorial(int n) {
  return (n < 2) ? 1 : n * factorial(n - 1);
}



    


Ответы

Ответ 1



Ты уже используешь рекуррентный вариант для xn+1, но продолжаешь вычислять факториал рекурсивно - надо от него тоже избавиться. В формуле есть следующие фрагменты: (2n)! x^(n+1) (n!)^2 (n+1) Что с ними произойдёт при увеличении n на 1? (2(n+1))! = (2n+2)! = (2n)! * (2n+1) * (2n+2) x^((n+1)+1) = x^(n+1) * x ((n+1)!)^2 = (n!*(n+1))^2 = (n!)^2 * (n+1)^2 ((n+1)+1) = (n+1) + 1 = (n+1) * (1 + 1/(n+1)) Пересчитываем коэффициент для следующего n: *= (2(n-1)+1) * (2(n-1)+2) = (2n-1) * 2n *= x /= n^2 /= (1 + 1/n) Получается формула y *= (2*n-1) * 2*n * x / (n*n * (1 + 1/n)); Если разделить на n числитель и знаменатель(сократить), получится: y *= 2 * x * (2*n-1) / (n + 1); Ну это если я нигде не ошибся в вычислениях. Если ошибся, то надо подправить :) n=0, это важно Надо просто задать соответствующее начальное значение при n=0: y = x; в последующей формуле оно просто умножится на нужный коэффициент.

Ответ 2



Выражение равно Σ f(n), где f(x, n) = (2n)!xn+1 / (n!)2(n+1) Предыдущий член суммы: f(x, n-1) = (2(n-1))! xn / ((n-1)!)2n Заметим, что (2n)! / (2(n-1))! = 2n(2n-1) xn+1 / xn = x n!2/(n-1)!2 = n2 (n + 1) / n = 1 + 1/n Тогда, f(x, n) / f(x, n-1) = 2n(2n-1) x / (n2 (1+1/n)) Или, так как n(1+1/n) = n+1 2x(2n-1) / (n+1) Реализация: double kn(int n, double x) { return 2*(2*n-1)*x / (n+1); } double fn(double fn_1, int n, double x) { return fn_1 * kn(n, x); } double EPS = 1e-15; double sum(double x) { double current = x; double sum = current; int n = 0; do { current = fn(current, ++n, x); sum += current; } while (fabs(current) > EPS); return sum; } int main() { printf("sum(%f) = %f\n", -0.25, sum(-0.25)); printf("sum(%f) = %f\n", 0.25, sum(0.25)); }

вторник, 10 декабря 2019 г.

Как вычислить равномерное увеличение сложной 3D фигуры

#3d #геометрия #объекты #threejs #формулы


Добрый день, есть некий абстрактный 3D объект сложной геометрии.
Скажем его объем V₁ кубических метра. 

Задача расчитать величину (на иллюстрации выделена желтым) на которую надо сместить
каждую вершину объекта, чтобы в результате получился объект с новым объемом V₂.

Есть ли какая-нибудь формула для нахождения этой величины? 
В английском сегменте данная операция называется offset.


    


Ответы

Ответ 1



Disclaimer: с three.js не работал. Для каждой вершины новое положение: (kx, ky, kz). где k = кубический_корень_из(V2/V1) То есть координаты каждой вершины надо изменить на ((k - 1)x, (k - 1)y, (k - 1)z) А потом сдвиньте все координаты, чтобы, например, центры тяжести старой и новой фигуры совпадали, или описывающий параллелепипед равномерно расширился/сжался в направлениях координатных осей. Но это уже зависит от дополнительных условий задачи, не включенных в вопрос. Такое не должно пропасть. Сохраним для истории. Если для 2D такая же формула, но только с квадратным корнем, то она не работает. Если конечно правильно считал. Тот же прямоугольник 10x20. Площадь его 200 единиц. Хотим увеличить до 300. корень квадратный (300 / 200 ) = 1.224745... Если его применяем к сторонам, то у полученной фигуры площадь 279.5 Для 10х20 до 300, величина должна быть что-то около 1.51 А разве корень квадратный из 1.5 (300/200) не 1.224745? Остальное я не считал, а строил в Rhinoceros3D.

пятница, 1 марта 2019 г.

Формула в строку Java

Задача: Составить таблицу значений функции y = f(x) на отрезке [n; m] с шагом k
Собственно вопрос возникает в моменте. Как ввести f(x). Ибо сама формула (для примера х-2), является строкой, а значение Y числом. т.е. Через сканер вводим все значения n,m,k и саму формулу "x-2" или любую другую. И в коде эту формулу применяем для подсчета значение Y.
while(x<=r.m){ y=x-5; System.out.println("x = " +x+" y = "+ y); x=x+r.k; }
В данном случае у меня стоит формула, введенная изначально "y=х-5" (вторая строчка, введено топорно, прямо в код), а мне надо, чтоб программа считала ту, которую я введу через сканер.
upd. После большого количества прочитанного и опробованного, хочется добавить, что введеное через сканер представляет собой цисловые значения, букву X и знаки арифметических вычислений ("+","-","/","*").


Ответ

Решение ленивого человека выглядит так:
import javax.script.*;
public class Eval { public static void main (String[] args) throws Exception { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("nashorn"); engine.put("x", 1); System.out.println(engine.eval("x * 2 + 1")); } }
В Java есть полноценный движок JavaScript (на русском), который отлично справляется с вычислением произвольных математических выражений (и не только их).
Решение же человека, которому описанная задача прилетела в виде лабораторной работы или домашнего задания выглядит сложнее. Преподаватель, скорее всего, ожидает, что вы разберёте вводимую строку на токены (переменная, оператор, число), переведёте её в обратную польскую запись, а затем вычислите, используя стековую машину (раз, два).

пятница, 19 октября 2018 г.

Составить рекуррентную формулу на Си (от n=0, это важно)

Есть вот такая формула, надо сравнить левую часть и правую с использованием такого ряда. В задании сказано посчитать правую часть, то бишь формулу суммы, c использованием рекуррентной формулы. Помогите написать часть кода на Си, где будет считать эту сумму с циклом DO WHILE и рекуррентной формулой! Нельзя использовать pow, надо использовать отдельную переменную для суммирования. Я такое сделал с функцией, но сказали, что надо рекуррентную формулу, а вывести ее у меня не выходит.
s = 0; xn = x; n = 0; do { an = (factorial(2 * n) * xn) / (factorial(n)*factorial(n) * (n + 1)); s += an; n++; xn *= x; } while (fabs(an) > eps && n <= lim);

int factorial(int n) { return (n < 2) ? 1 : n * factorial(n - 1); }


Ответ

Ты уже используешь рекуррентный вариант для xn+1, но продолжаешь вычислять факториал рекурсивно - надо от него тоже избавиться.
В формуле есть следующие фрагменты:
(2n)! x^(n+1) (n!)^2 (n+1)
Что с ними произойдёт при увеличении n на 1?
(2(n+1))! = (2n+2)! = (2n)! * (2n+1) * (2n+2) x^((n+1)+1) = x^(n+1) * x ((n+1)!)^2 = (n!*(n+1))^2 = (n!)^2 * (n+1)^2 ((n+1)+1) = (n+1) + 1 = (n+1) * (1 + 1/(n+1))
Пересчитываем коэффициент для следующего n:
*= (2(n-1)+1) * (2(n-1)+2) = (2n-1) * 2n *= x /= n^2 /= (1 + 1/n)
Получается формула
y *= (2*n-1) * 2*n * x / (n*n * (1 + 1/n));
Если разделить на n числитель и знаменатель(сократить), получится:
y *= 2 * x * (2*n-1) / (n + 1);
Ну это если я нигде не ошибся в вычислениях. Если ошибся, то надо подправить :)
n=0, это важно
Надо просто задать соответствующее начальное значение при n=0:
y = x;
в последующей формуле оно просто умножится на нужный коэффициент.