Skip to content

Instantly share code, notes, and snippets.

@peheje
Last active October 27, 2021 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peheje/d27805c273592d55ace090b12aa5c447 to your computer and use it in GitHub Desktop.
Save peheje/d27805c273592d55ace090b12aa5c447 to your computer and use it in GitHub Desktop.
fun main() {
}
typealias Function = (x: Double) -> Double
typealias Rule = (f: Function, x: Double, h: Double) -> Double
fun leftRectangle(f: Function, x: Double, h: Double) = f(x)
fun midRectangle(f: Function, x: Double, h: Double) = f(x + h / 2.0)
fun rightRectangle(f: Function, x: Double, h: Double) = f(x + h)
fun trapezium(f: Function, x: Double, h: Double) = (f(x) + f(x + h)) / 2.0
fun simpson(f: Function, x: Double, h: Double) = (f(x) + 4.0 * f(x + h / 2.0) + f(x + h)) / 6.0
fun integral(
from: Double,
to: Double,
columns: Int,
rule: Rule,
f: (Double) -> Double
): Double {
val h = (to - from) / columns
var sum = 0.0
for (i in 0 until columns) {
val x = from + i * h
sum += rule(f, x, h)
}
val integral = sum * h
println(integral)
return integral
}
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import kotlin.math.ln
import org.junit.jupiter.api.Assertions.assertEquals as equals
internal class MainKtTest {
private val n = 10000
private val delta = 0.01
@Test
fun integralShould() {
val methods = mapOf(
"LeftRectangle" to ::leftRectangle,
"MidRectangle" to ::midRectangle,
"RightRectangle" to ::rightRectangle,
"Trapezium" to ::trapezium,
"Simpson" to ::simpson
)
for ((name, method) in methods) {
println(name)
val powerOfTwo: (Double) -> Double = { it * it }
equals(1.0 / 3.0, integral(0.0, 1.0, n, method, powerOfTwo), delta)
equals(8.0 / 3.0, integral(0.0, 2.0, n, method, powerOfTwo), delta)
equals(9.0, integral(0.0, 3.0, n, method, powerOfTwo), delta)
val oneOver: (Double) -> Double = { 1.0 / it }
equals(ln(100.0), integral(1.0, 100.0, n, method, oneOver), delta)
equals(ln(20.0 / 3.0), integral(6.0, 40.0, n, method, oneOver), delta)
}
}
}
import std/sugar
import std/strformat
import std/math
type
F = proc(x: float): float
Rule = proc(f: F, x, h: float): float
Experiment = ref object
name: string
f: F
start, to, answer: float
rule: Rule
proc integral(
start, to: float,
cols: int,
rule: Rule,
f: F): float =
let h = (to - start) / cols.toFloat()
var sum = 0.0
for i in 0..<cols:
let x = start + i.toFloat() * h
sum += rule(f, x, h)
sum * h
proc leftRectangle(f: F, x, h: float): float = f(x)
proc rightRectangle(f: F, x, h: float): float = f(x + h)
proc midRectangle(f: F, x, h: float): float = f(x + h / 2.0)
proc trapezium(f: F, x, h: float): float = (f(x) + f(x + h)) / 2.0
proc simpson(f: F, x, h: float): float = (f(x) + 4.0 * f(x + h / 2.0) + f(x + h)) / 6.0
proc main() =
const
cols = 100
powerOfTwo = (x: float) => x * x
oneOver = (x: float) => 1.0 / x
echo fmt"Columns: {cols}"
for ex in @[
Experiment(name: "Left-Rectangle x^2", f: powerOfTwo, start: 0.0, to: 1.0, answer: 1.0/3.0, rule: leftRectangle),
Experiment(name: "Simpson, x^2", f: powerOfTwo, start: 0.0, to: 1.0, answer: 1.0/3.0, rule: simpson),
Experiment(name: "Left-Rectangle 1/x", f: oneOver, start: 1.0, to: 100.0, answer: ln(100.0), rule: leftRectangle),
Experiment(name: "Simpson 1/x", f: oneOver, start: 1.0, to: 100.0, answer: ln(100.0), rule: simpson)
]:
stdout.write ex.name & ": "
echo fmt"{integral(ex.start, ex.to, cols, ex.rule, ex.f)} == {ex.answer} ?"
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment