Приближенные определенные интегралы с использованием сумм Римана

19

Левая и правая римановы суммы являются приближениями к определенным интегралам . Конечно, в математике мы должны быть очень точными, поэтому мы стремимся вычислять их с помощью ряда подразделений, приближающихся к бесконечности, но это не требуется для целей этой задачи. Вместо этого вы должны попытаться написать самую короткую программу с вводом и выводом с помощью любого из методов по умолчанию на любом языке программирования , который выполняет следующие действия:

задача

Учитывая два рациональных числа и (пределы определенного интеграла), положительное целое число , логическое значение представляющее левый / правый и функцию черного ящика , вычисляют левую или правую сумму Римана (в зависимости от ) от , используя равных подразделений.aбNК еКaбе(Икс)dИксN

Спецификации ввода / вывода

  • a и могут быть рациональными числами или числами с плавающей точкой или дробями. б

  • К может быть представлено любыми двумя различными и непротиворечивыми значениями, но имейте в виду, что вы не можете принимать полные или частичные функции в качестве входных данных.

  • е - это функция черного ящика. Ссылаясь на мета-ответ, связанный выше, содержимое (то есть код) функций черного ящика может быть недоступно, вы можете только вызывать их (передавая аргументы, если применимо) и наблюдать за их выводом . При необходимости, пожалуйста, включите необходимую информацию о синтаксисе вашего языка, чтобы мы могли проверить вашу заявку.

В качестве вывода вы должны предоставить рациональную / с плавающей запятой / дробь, представляющую сумму Римана, о которой вы просили. Как обсуждалось в прошлом , неточность с плавающей запятой можно игнорировать, при условии, что ваши выходные данные с точностью не менее трех десятичных знаков при округлении до ближайшего кратного 1/1000 (например, 1.4529999в порядке вместо 1.453).

Математические характеристики

  • е гарантированно будет непрерывным между и (без скачков, без дырок, без вертикальных асимптот).aб

  • Есть три возможных случая, которые вы должны обработать: (результат должен быть или его эквивалентами), или .aзнак равноб0a<бa>б

  • Если , интеграл меняет свой знак. Кроме того , право смысл интеграла в данном случае по отношению к .б<aa

  • Области под графиком отрицательные, а над графиком положительные.

Примеры / Тестовые случаи

Разрешение не является оптимальным, потому что мне пришлось немного уменьшить их, но они все еще читаемы.

  • е(Икс)знак равно2Икс+1,aзнак равно5,бзнак равно13,Nзнак равно4 , k = справа:

    2х + 1

    Результат должен быть , потому что ширина каждого прямоугольника равна и соответствующему высоты .152+192+232+272знак равно168|б-a|Nзнак равно2е(7)знак равно15,е(9)знак равно19,е(11)знак равно23,е(13)знак равно27

  • е(Икс)знак равноИкс,aзнак равно1,бзнак равно2.5,Nзнак равно3 , k = слева:

    Квадратный корень

    Выход должен быть .1,8194792169

  • е(Икс)знак равно-3Икс+4+Икс25,aзнак равно12,5,бзнак равно2.5,Nзнак равно10 , k = справа:

    -3x + 4 + 1 / 5x ^ 2

    Ожидаемое выходное значение составляет , потому что интеграл меняет знаки при переключении границ ( ) .-(-4,05-5,45-6,45-7,05-7,25-7,05-6,45-5,45-4,05-2,25)знак равно55,5б<a

  • е(Икс)знак равно9-4Икс+2Икс27,aзнак равно0,бзнак равно15,Nзнак равно3 , k = слева:

    9-4X + 2 / 7x ^ 2

    Подсчитав нашу сумму Римана, мы получим .+13,5714285715

  • е(Икс)знак равно6,aзнак равно1,бзнак равно4,Nзнак равно2 , k = вправо - Выход: .18

  • е(Икс)знак равноИкс7+165Икс+1,aзнак равно7,бзнак равно7,Nзнак равно4 , k = слева - Выход: .0

  • е(Икс)знак равноИксгрех(Икс-1),aзнак равно0,бзнак равно1,Nзнак равно50 , k = вправо - Выход: . Обратите внимание, что здесь синус использует радианы, но вы можете использовать градусы.+0,385723952885505

Мистер Xcoder
источник
3
Особая благодарность: Эта проблема была опубликована в Песочнице , где она получила ценные отзывы от пользователей202729 , AdmBorkBork и Leaky Nun .
г-н Xcoder
Я очень надеюсь, что эти решения помогут многолетним студентам Calc I ...
Джузеппе
f(x) = x * sin(1 / x); a = 0; b = 1; n = 50; k = right — Output: 0.385723952885505. Note that sine uses radians here, but feel free to use degrees instead.Теперь, когда f (x) черный ящик, почему это важно?
м2 17
@ l4m2 Это не имеет большого значения, просто хотел, чтобы люди знали, что им не следует беспокоиться о таких вещах.
г-н Xcoder
@ Giuseppe Нет. Методы программ здесь даже хуже, чем методы ручных калькуляторов. [просто говорю]
user202729

Ответы:

8

R , 69 65 63 57 байт

function(a,b,n,k,f,w=(b-a)/n)sum(sapply(a+w*(1:n-k),f))*w

Попробуйте онлайн!

Принимает k=FALSEдля правых сумм, хотя ссылка TIO теперь включает псевдонимы для «левого» и «правого» для простоты использования.

a+w*(1:n-k) генерирует соответствующие левые или правые точки.

Затем sapplyприменяется fк каждому элементу результата, который мы затем sumувеличиваем и умножаем на ширину интервала, (b-a)/nчтобы получить результат. Это последнее также аккуратно решает любые проблемы со знаками, которые могут у нас возникнуть.

Giuseppe
источник
4

SNOBOL4 (CSNOBOL4) , 127 байт

	DEFINE('R(a,b,n,k,p)')
R	l =(b - a) / n
	i =1
l	R =R + eval(p '(a + l * (i - k))')
	i =lt(i,n) i + 1	:s(l)
	R =R * l :(return)

Попробуйте онлайн!

Предполагая, что функция pгде-то определена, это берет a,b,n,k,(name of p), с k=0для правого и l=1для левого.

Catspaw SNOBOL4+поддерживает REALs, но не имеет встроенных функций trig. Тем не менее, я полагаю, можно найти разумную sinфункцию, используя ряд Тейлора.

Я не уверен на 100%, что это «правильный» способ передать функцию черного ящика в SNOBOL (которая, насколько мне известно, не имеет функций первого класса), но мне кажется, что это разумно.

Я предполагаю, что при условии, что функция определена как fбудет короче, поскольку строка lможет быть

l	R =R + f(a + l * (i - k))

но тогда это не передается в качестве аргумента, который выглядит как «обман».

Обратите внимание, что ссылка TIO имеет оператор :(e)after DEFINE, поэтому код будет работать правильно.

Giuseppe
источник
4

Юлия 0,6 , 50 байтов

R(f,a,b,n,k)=(c=(b-a)/n;sum(f.(a+[k:n+k-1...]c))c)

Попробуйте онлайн!

Нормализованный диапазон строится, собирается в вектор и затем масштабируется. Сбор диапазона в вектор с помощью [X...]необходимо, чтобы избежать inexact errorумножения диапазона непосредственно на 0, когда a=b. Точно так же, построение диапазона непосредственно с :или range()невозможно, когда a=b.

Использование k очень похоже на решение Guiseppe с k=1for rightи k=0for left.

LUKEŠ
источник
f.векторизовать fсвои аргументы?
Джузеппе
@ Джузеппе: Точно. f.поэлементное применение f.
LukeS
2

Haskell , 73 67 байт

Спасибо H.PWiz и Брюсу Форте за советы!

(f&a)b n k|d<-(b-a)/realToFrac n=d*sum(f<$>take n(drop k[a,a+d..]))

Попробуйте онлайн!

Довольно простое решение.

kявляется 0для левого и 1для правого.

Кристиан Лупаску
источник
1
Если вы принимаете n, вам не нужно идти доb
H.PWiz
2

Python 2 , 99 94 байта

Немного наивного решения.

def R(f,a,b,n,k):s=cmp(b,a);d=s*(b-a)/n;return s*sum(d*f([0,a,b][s]+i*d)for i in range(k,n+k))

Попробуйте онлайн!

mbomb007
источник
По какой-то причине я подумал, что мы должны обрабатывать целочисленный ввод. Благодарю.
mbomb007
1

Желе , 21 байт

ƓḶ+Ɠ÷
IḢ×¢A+ṂɠvЀÆm×I

Попробуйте онлайн!

Бери a,bот аргументов и

n
right
f

из стандартного


Если вы не знакомы с Jelly, вы можете использовать Python для написания функции черного ящика f:

f (x) = 2x + 1 ; а = 5; б = 13; n = 4; k = право

f (x) = √x ; а = 1; б = 2,5; n = 3; k = слева

f (x) = -3x + 4 + 1/5 * x 2 ; а = 12,5; б = 2,5; n = 10; k = право

f (x) = 9 - 4x + 2/7 * x 2 ; а = 0; б = 15; n = 3; k = слева

f (x) = 6 ; а = 1; б = 4; n = 2; k = право

f (x) = x * sin (1 / x) ; а = 0; б = 1; n = 50; k = право


Объяснение:


ƓḶ+Ɠ÷     Helper niladic link.
Ɠ         First line from stdin. (n). Assume n = 4.
 Ḷ        Lowered range (unlength). Get [0, 1, 2, 3].
  +Ɠ      Add second line from stdin (k). Assume k = 1 (right).
            Get [1, 2, 3, 4].
    ÷     Divide by (n). Get [0.25,0.5,0.75,1].

IḢ×¢A+ṂɠvЀÆm×I   Main monadic link. Take input `[a, b]`, assume `a=2,b=6`.
IḢ                `a-b`. Get `-4`.
  ×¢              Multiply by value of niladic link above. Get `[-1,-2,-3,-4]`.
    A             Absolute value. Get `[1,2,3,4]`.
     +Ṃ           Add min(a, b) = 2. Get `[3,4,5,6]`.
        vЀ       For each number, evaluate with...
       ɠ            input line from stdin.
           Æm     Arithmetic mean.
             ×I   Multiply by `a-b`.

user202729
источник
1

Perl 6 , 65 байт

{my \d=($^b-$^a)/$^n;sum ($a,*+d...*)[($^k+^0>d)+ ^$n]».&^f X*d}

Попробуйте онлайн!

Относительно просто. Единственное осложнение является обработка a > bдела, которое я делаю по XOR-инге флаг ввода $^kс 0 > d, который инвертирует его , когда a > b.

Шон
источник
0

APL (Dyalog Classic) , 37 байт

{(a b n k)←⍵⋄ln÷⍨b-al×+/⍺⍺a+l×k+⍳n}

Попробуйте онлайн!

APL NARS, 37 символов

Функция имеет аргумент слева от функции, справа числовой аргумент abn k. В оставленном здесь вопросе k = это означает k = ¯1; k = прямо здесь это означает, что k = 0. Тестовое задание:

  f←{(a b n k)←⍵⋄ln÷⍨b-al×+/⍺⍺a+l×k+⍳n}
  {1+2×⍵} f 5 13 4 0
168
  {√⍵} f 1 2.5 3 ¯1
1.819479217
  {4+(¯3×⍵)+0.2×⍵×⍵} f 12.5 2.5 10 0
55.5
  {9+(¯4×⍵)+7÷⍨2×⍵×⍵} f 0 15 3 ¯1
13.57142857
  {6-0×⍵} f 1 4 2 0
18
  {1+(165×⍵)+⍵*7} f 7 7 4 ¯1
0
  {⍵×1○÷⍵} f 0 1 50 0
0.3857239529
RosLuP
источник
Представления учитываются в байтах, а не в символах. Я не помню, имеет ли NARS пользовательскую кодовую страницу (так что это также будет 37 байт) или использует UTF16.
Уриэль
@Uriel Это 37 байтов в Dyalog APL classic, перейдите по ссылке; возможно 35x2 байта для Nars Apl ...
RosLuP
Так почему ты пишешь это как НАРС? У NARS даже есть dfnss? Кстати, вы можете отбросить первых родителей на 35 байт
Уриэль
APL NARS, 37 символов означает, что он должен работать и в NARS APL
RosLuP