diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml
new file mode 100644
index 0000000..7ef04e2
--- /dev/null
+++ b/.idea/copilot.data.migration.ask.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/output.csv b/output.csv
new file mode 100644
index 0000000..df8ed59
--- /dev/null
+++ b/output.csv
@@ -0,0 +1,21 @@
+X;f(X)
+-1.0;-0.5869665480423778
+-0.9;-0.9352384029718002
+-0.8;-1.4961760304210368
+-0.7000000000000001;-2.6709130967375065
+-0.6000000000000001;-7.731313457128241
+-0.5000000000000001;10.536936447964717
+-0.40000000000000013;3.2217613031197727
+-0.30000000000000016;1.92971965792051
+-0.20000000000000015;1.4064231946343844
+-0.10000000000000014;1.1414743318601792
+0.09999999999999987;5.6049822447303335
+0.19999999999999987;0.6792599777698426
+0.2999999999999999;0.06689887171282584
+0.3999999999999999;-0.02176594607783879
+0.4999999999999999;-0.02248614282716569
+0.5999999999999999;-0.012196322980954091
+0.6999999999999998;-0.0048145086174475014
+0.7999999999999998;-0.0012728922251139007
+0.8999999999999998;-1.3893249002483576E-4
+0.9999999999999998;NaN
diff --git a/src/main/kotlin/function/FunctionSystem.kt b/src/main/kotlin/function/FunctionSystem.kt
new file mode 100644
index 0000000..7a8a8f9
--- /dev/null
+++ b/src/main/kotlin/function/FunctionSystem.kt
@@ -0,0 +1,62 @@
+package function
+
+import function.base.ILn
+import function.base.ISin
+import function.logarithmic.ILog
+import function.trigonometric.ICos
+import function.trigonometric.ICot
+import function.trigonometric.ICsc
+import function.trigonometric.ISec
+import kotlin.math.pow
+
+class FunctionSystem(
+ private val sinImpl: ISin,
+ private val lnImpl: ILn,
+ private val cosImpl: ICos,
+ private val cscImpl: ICsc,
+ private val secImpl: ISec,
+ private val cotImpl: ICot,
+ private val logImpl: ILog,
+) {
+ fun compute(
+ x: Double,
+ eps: Double = 1e-10,
+ ): Double =
+ if (x <= 0) {
+ computeTrigPart(x, eps)
+ } else {
+ computeLogPart(x, eps)
+ }
+
+ private fun computeTrigPart(
+ x: Double,
+ eps: Double,
+ ): Double {
+ val sinX = sinImpl.sin(x, eps)
+ val cscX = cscImpl.csc(x, eps)
+ val secX = secImpl.sec(x, eps)
+ val cosX = cosImpl.cos(x, eps)
+ val cotX = cotImpl.cot(x, eps)
+
+ val numerator = (sinX + cscX).pow(2) / cscX
+ val denominator = secX.pow(3) + cosX.pow(2) * (sinX + cotX)
+
+ return numerator / denominator
+ }
+
+ private fun computeLogPart(
+ x: Double,
+ eps: Double,
+ ): Double {
+ val log10X = logImpl.log(10.0, x, eps)
+ val log5X = logImpl.log(5.0, x, eps)
+ val log3X = logImpl.log(3.0, x, eps)
+ val log2X = logImpl.log(2.0, x, eps)
+ val lnX = lnImpl.ln(x, eps)
+
+ val leftPart = log10X / log5X * log10X * log10X * log3X
+ val rightPart = (log2X / log2X).pow(3) - (log3X * lnX + log5X - log5X)
+
+ return leftPart * rightPart
+ }
+}
diff --git a/src/main/kotlin/function/base/ILn.kt b/src/main/kotlin/function/base/ILn.kt
new file mode 100644
index 0000000..7b4d60f
--- /dev/null
+++ b/src/main/kotlin/function/base/ILn.kt
@@ -0,0 +1,5 @@
+package function.base
+
+interface ILn {
+ fun ln(x: Double, eps: Double = 1e-10): Double
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/base/ISin.kt b/src/main/kotlin/function/base/ISin.kt
new file mode 100644
index 0000000..2c2bce3
--- /dev/null
+++ b/src/main/kotlin/function/base/ISin.kt
@@ -0,0 +1,5 @@
+package function.base
+
+interface ISin {
+ fun sin(x: Double, eps: Double = 1e-10): Double
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/base/LnTaylor.kt b/src/main/kotlin/function/base/LnTaylor.kt
new file mode 100644
index 0000000..3592805
--- /dev/null
+++ b/src/main/kotlin/function/base/LnTaylor.kt
@@ -0,0 +1,22 @@
+package function.base
+
+import kotlin.math.abs
+
+class LnTaylor : ILn {
+ override fun ln(
+ x: Double,
+ eps: Double,
+ ): Double {
+ if (x <= 0) throw IllegalArgumentException("Ln is undefined for x <= 0")
+ val y = (x - 1) / (x + 1)
+ var result = 0.0
+ var term = y
+ var k = 1
+ while (abs(term) >= eps) {
+ result += term / (2 * k - 1)
+ term *= y * y
+ k++
+ }
+ return 2 * result
+ }
+}
diff --git a/src/main/kotlin/function/base/SinTaylor.kt b/src/main/kotlin/function/base/SinTaylor.kt
new file mode 100644
index 0000000..1ff6e7e
--- /dev/null
+++ b/src/main/kotlin/function/base/SinTaylor.kt
@@ -0,0 +1,21 @@
+package function.base
+
+import kotlin.math.PI
+import kotlin.math.abs
+
+class SinTaylor : ISin {
+ override fun sin(
+ x: Double,
+ eps: Double,
+ ): Double {
+ var result = 0.0
+ var term = x
+ var n = 1
+ while (abs(term) >= eps) {
+ result += term
+ term *= -x * x / ((2 * n) * (2 * n + 1))
+ n++
+ }
+ return result
+ }
+}
diff --git a/src/main/kotlin/function/logarithmic/ILog.kt b/src/main/kotlin/function/logarithmic/ILog.kt
new file mode 100644
index 0000000..d20a906
--- /dev/null
+++ b/src/main/kotlin/function/logarithmic/ILog.kt
@@ -0,0 +1,5 @@
+package function.logarithmic
+
+interface ILog {
+ fun log(base: Double, x: Double, eps: Double = 1e-10): Double
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/logarithmic/Log.kt b/src/main/kotlin/function/logarithmic/Log.kt
new file mode 100644
index 0000000..10ce475
--- /dev/null
+++ b/src/main/kotlin/function/logarithmic/Log.kt
@@ -0,0 +1,13 @@
+package function.logarithmic
+
+import function.base.ILn
+
+class Log(private val lnImpl: ILn) : ILog {
+ override fun log(base: Double, x: Double, eps: Double): Double {
+ if (base <= 0 || base == 1.0) throw IllegalArgumentException("Log base must be > 0 and != 1")
+ if (x <= 0) throw IllegalArgumentException("Log argument must be > 0")
+ val lnX = lnImpl.ln(x, eps)
+ val lnBase = lnImpl.ln(base, eps)
+ return lnX / lnBase
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/stubs/CosStub.kt b/src/main/kotlin/function/stubs/CosStub.kt
new file mode 100644
index 0000000..45f18dd
--- /dev/null
+++ b/src/main/kotlin/function/stubs/CosStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.trigonometric.ICos
+
+class CosStub : ICos {
+ override fun cos(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/CotStub.kt b/src/main/kotlin/function/stubs/CotStub.kt
new file mode 100644
index 0000000..e6bcffd
--- /dev/null
+++ b/src/main/kotlin/function/stubs/CotStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.trigonometric.ICot
+
+class CotStub : ICot {
+ override fun cot(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/CscStub.kt b/src/main/kotlin/function/stubs/CscStub.kt
new file mode 100644
index 0000000..77bcf69
--- /dev/null
+++ b/src/main/kotlin/function/stubs/CscStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.trigonometric.ICsc
+
+class CscStub : ICsc {
+ override fun csc(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/LnStub.kt b/src/main/kotlin/function/stubs/LnStub.kt
new file mode 100644
index 0000000..d7bd68b
--- /dev/null
+++ b/src/main/kotlin/function/stubs/LnStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.base.ILn
+
+class LnStub : ILn {
+ override fun ln(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/LogStub.kt b/src/main/kotlin/function/stubs/LogStub.kt
new file mode 100644
index 0000000..9e90dbb
--- /dev/null
+++ b/src/main/kotlin/function/stubs/LogStub.kt
@@ -0,0 +1,11 @@
+package function.stubs
+
+import function.logarithmic.ILog
+
+class LogStub : ILog {
+ override fun log(
+ base: Double,
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/SecStub.kt b/src/main/kotlin/function/stubs/SecStub.kt
new file mode 100644
index 0000000..6784997
--- /dev/null
+++ b/src/main/kotlin/function/stubs/SecStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.trigonometric.ISec
+
+class SecStub : ISec {
+ override fun sec(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/stubs/SinStub.kt b/src/main/kotlin/function/stubs/SinStub.kt
new file mode 100644
index 0000000..1d0a66a
--- /dev/null
+++ b/src/main/kotlin/function/stubs/SinStub.kt
@@ -0,0 +1,10 @@
+package function.stubs
+
+import function.base.ISin
+
+class SinStub : ISin {
+ override fun sin(
+ x: Double,
+ eps: Double,
+ ): Double = 1.0
+}
diff --git a/src/main/kotlin/function/trigonometric/Cos.kt b/src/main/kotlin/function/trigonometric/Cos.kt
new file mode 100644
index 0000000..968c1f3
--- /dev/null
+++ b/src/main/kotlin/function/trigonometric/Cos.kt
@@ -0,0 +1,9 @@
+package function.trigonometric
+
+import function.base.ISin
+
+class Cos(private val sinImpl: ISin) : ICos {
+ override fun cos(x: Double, eps: Double): Double {
+ return sinImpl.sin(x + Math.PI / 2, eps)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/trigonometric/Cot.kt b/src/main/kotlin/function/trigonometric/Cot.kt
new file mode 100644
index 0000000..c4d5902
--- /dev/null
+++ b/src/main/kotlin/function/trigonometric/Cot.kt
@@ -0,0 +1,20 @@
+package function.trigonometric
+
+import function.base.ISin
+import kotlin.math.abs
+
+class Cot(
+ private val sinImpl: ISin,
+) : ICot {
+ private val cosImpl = Cos(sinImpl)
+
+ override fun cot(
+ x: Double,
+ eps: Double,
+ ): Double {
+ val sinVal = sinImpl.sin(x, eps)
+ val cosVal = cosImpl.cos(x, eps)
+ if (abs(sinVal) < 1e-8) throw ArithmeticException("Cot is undefined for sin(x) = 0")
+ return cosVal / sinVal
+ }
+}
diff --git a/src/main/kotlin/function/trigonometric/Csc.kt b/src/main/kotlin/function/trigonometric/Csc.kt
new file mode 100644
index 0000000..f34c330
--- /dev/null
+++ b/src/main/kotlin/function/trigonometric/Csc.kt
@@ -0,0 +1,17 @@
+package function.trigonometric
+
+import function.base.ISin
+import kotlin.math.abs
+
+class Csc(
+ private val sinImpl: ISin,
+) : ICsc {
+ override fun csc(
+ x: Double,
+ eps: Double,
+ ): Double {
+ val sinVal = sinImpl.sin(x, eps)
+ if (abs(sinVal) < 1e-8) throw ArithmeticException("Csc is undefined for sin(x) = 0")
+ return 1.0 / sinVal
+ }
+}
diff --git a/src/main/kotlin/function/trigonometric/ICos.kt b/src/main/kotlin/function/trigonometric/ICos.kt
new file mode 100644
index 0000000..a544fb9
--- /dev/null
+++ b/src/main/kotlin/function/trigonometric/ICos.kt
@@ -0,0 +1,5 @@
+package function.trigonometric
+
+interface ICos {
+ fun cos(x: Double, eps: Double = 1e-10): Double
+}
\ No newline at end of file
diff --git a/src/main/kotlin/function/trigonometric/Sec.kt b/src/main/kotlin/function/trigonometric/Sec.kt
new file mode 100644
index 0000000..4bcc72d
--- /dev/null
+++ b/src/main/kotlin/function/trigonometric/Sec.kt
@@ -0,0 +1,19 @@
+package function.trigonometric
+
+import function.base.ISin
+import kotlin.math.abs
+
+class Sec(
+ sinImpl: ISin,
+) : ISec {
+ private val cosImpl = Cos(sinImpl)
+
+ override fun sec(
+ x: Double,
+ eps: Double,
+ ): Double {
+ val cosVal = cosImpl.cos(x, eps)
+ if (abs(cosVal) < 1e-8) throw ArithmeticException("Sec is undefined for cos(x) = 0")
+ return 1.0 / cosVal
+ }
+}
diff --git a/src/main/kotlin/util/CsvWriter.kt b/src/main/kotlin/util/CsvWriter.kt
new file mode 100644
index 0000000..ab8cf90
--- /dev/null
+++ b/src/main/kotlin/util/CsvWriter.kt
@@ -0,0 +1,18 @@
+package util
+
+import java.io.File
+
+class CsvWriter {
+ fun writeToCsv(
+ filename: String,
+ data: List>,
+ label: String = "Result",
+ ) {
+ File(filename).printWriter().use { out ->
+ out.println("X;$label(X)")
+ for ((x, result) in data) {
+ out.println("$x;$result")
+ }
+ }
+ }
+}
diff --git a/src/test/kotlin/CosTest.kt b/src/test/kotlin/CosTest.kt
new file mode 100644
index 0000000..4c0047d
--- /dev/null
+++ b/src/test/kotlin/CosTest.kt
@@ -0,0 +1,36 @@
+package test
+
+import function.base.SinTaylor
+import function.trigonometric.Cos
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.test.assertEquals
+
+class CosTest {
+ private val cosImpl = Cos(SinTaylor())
+
+ @Test
+ fun testCosZero() {
+ val eps = 1e-10
+ val result = cosImpl.cos(0.0, eps)
+ assertEquals(cos(0.0), result, eps)
+ }
+
+ @Test
+ fun testCosPi() {
+ val eps = 1e-10
+ val x = PI
+ val result = cosImpl.cos(x, eps)
+ assertEquals(cos(x), result, eps)
+ }
+
+ @Test
+ fun testCosPiOver2() {
+ val eps = 1e-10
+ val x = PI / 2
+ val expected = cos(x)
+ val result = cosImpl.cos(x, eps)
+ assertEquals(expected, result, eps)
+ }
+}
diff --git a/src/test/kotlin/CotTest.kt b/src/test/kotlin/CotTest.kt
new file mode 100644
index 0000000..e756a08
--- /dev/null
+++ b/src/test/kotlin/CotTest.kt
@@ -0,0 +1,39 @@
+package test
+
+import function.base.SinTaylor
+import function.trigonometric.Cot
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
+
+class CotTest {
+ private val cotImpl = Cot(SinTaylor())
+
+ @Test
+ fun testCot() {
+ val eps = 1e-10
+ val x = 1.0
+ val result = cotImpl.cot(x, eps)
+ assertTrue(result.isFinite())
+ }
+
+ @Test
+ fun testCotInvalid() {
+ val eps = 1e-10
+ assertFailsWith {
+ cotImpl.cot(0.0, eps)
+ }
+ }
+
+ @Test
+ fun testCotPiOver4() {
+ val eps = 1e-10
+ val x = PI / 4
+ val result = cotImpl.cot(x, eps)
+ assertEquals(cos(x) / sin(x), result, eps * 10)
+ }
+}
diff --git a/src/test/kotlin/CscTest.kt b/src/test/kotlin/CscTest.kt
new file mode 100644
index 0000000..d3a54f1
--- /dev/null
+++ b/src/test/kotlin/CscTest.kt
@@ -0,0 +1,29 @@
+package test
+
+import function.base.SinTaylor
+import function.trigonometric.Csc
+import integration.eps
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.math.sin
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class CscTest {
+ private val cscImpl = Csc(SinTaylor())
+
+ @Test
+ fun testCscPiOver2() {
+ val eps = 1e-10
+ val x = PI / 2
+ val result = cscImpl.csc(x, eps)
+ assertEquals(1.0 / sin(x), result, eps)
+ }
+
+ @Test
+ fun testCscInvalid() {
+ assertFailsWith {
+ cscImpl.csc(0.0, eps)
+ }
+ }
+}
diff --git a/src/test/kotlin/FunctionSystemTest.kt b/src/test/kotlin/FunctionSystemTest.kt
new file mode 100644
index 0000000..69cc9e9
--- /dev/null
+++ b/src/test/kotlin/FunctionSystemTest.kt
@@ -0,0 +1,58 @@
+package test
+
+import function.FunctionSystem
+import function.base.LnTaylor
+import function.base.SinTaylor
+import function.logarithmic.Log
+import function.trigonometric.Cos
+import function.trigonometric.Cot
+import function.trigonometric.Csc
+import function.trigonometric.Sec
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
+
+class FunctionSystemTest {
+ private val funcSys =
+ FunctionSystem(SinTaylor(), LnTaylor(), Cos(SinTaylor()), Csc(SinTaylor()), Sec(SinTaylor()), Cot(SinTaylor()), Log(LnTaylor()))
+
+ @Test
+ fun testTrigPart() {
+ val eps = 1e-10
+ val x = -0.5
+ val result = funcSys.compute(x, eps)
+ assertTrue(result.isFinite())
+ }
+
+ @Test
+ fun testLogPart() {
+ val eps = 1e-10
+ val x = 2.0
+ val result = funcSys.compute(x, eps)
+ assertTrue(result.isFinite())
+ }
+
+ @Test
+ fun testBoundaryXEqualsZero() {
+ val eps = 1e-10
+ assertFailsWith {
+ funcSys.compute(0.0, eps)
+ }
+ }
+
+ @Test
+ fun testBoundaryXEqualsOne() {
+ val eps = 1e-10
+ val result = funcSys.compute(1.0, eps)
+ assertTrue((result).isNaN())
+ }
+
+ @Test
+ fun testTrigInvalidPoint() {
+ val eps = 1e-10
+ assertFailsWith {
+ funcSys.compute(-PI, eps)
+ }
+ }
+}
diff --git a/src/test/kotlin/LnTest.kt b/src/test/kotlin/LnTest.kt
new file mode 100644
index 0000000..df08fb3
--- /dev/null
+++ b/src/test/kotlin/LnTest.kt
@@ -0,0 +1,47 @@
+package test
+
+import function.base.LnTaylor
+import org.junit.jupiter.api.Test
+import kotlin.math.ln
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class LnTest {
+
+ private val lnTaylor = LnTaylor()
+
+ @Test
+ fun testLnOf1() {
+ val eps = 1e-10
+ val result = lnTaylor.ln(1.0, eps)
+ assertEquals(0.0, result, eps)
+ }
+
+ @Test
+ fun testLnOfE() {
+ val eps = 1e-10
+ val x = Math.E
+ val expected = ln(x)
+ val result = lnTaylor.ln(x, eps)
+ assertEquals(expected, result, eps)
+ }
+
+ @Test
+ fun testLnSmallPositive() {
+ val eps = 1e-10
+ val x = 2.0
+ val expected = ln(x)
+ val result = lnTaylor.ln(x, eps)
+ assertEquals(expected, result, eps)
+ }
+
+ @Test
+ fun testLnInvalid() {
+ assertFailsWith {
+ lnTaylor.ln(0.0)
+ }
+ assertFailsWith {
+ lnTaylor.ln(-1.0)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/LogTest.kt b/src/test/kotlin/LogTest.kt
new file mode 100644
index 0000000..5a3394f
--- /dev/null
+++ b/src/test/kotlin/LogTest.kt
@@ -0,0 +1,49 @@
+package test
+
+import function.base.LnTaylor
+import function.logarithmic.Log
+import org.junit.jupiter.api.Test
+import kotlin.math.log
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class LogTest {
+
+ private val logImpl = Log(LnTaylor())
+
+ @Test
+ fun testLog10() {
+ val eps = 1e-10
+ val x = 100.0
+ val result = logImpl.log(10.0, x, eps)
+ assertEquals(log(x, 10.0), result, eps)
+ }
+
+ @Test
+ fun testLog5Of25() {
+ val eps = 1e-10
+ val x = 25.0
+ val result = logImpl.log(5.0, x, eps)
+ assertEquals(2.0, result, eps)
+ }
+
+ @Test
+ fun testLogInvalidBase() {
+ assertFailsWith {
+ logImpl.log(-1.0, 1.0)
+ }
+ assertFailsWith {
+ logImpl.log(1.0, 1.0)
+ }
+ }
+
+ @Test
+ fun testLogInvalidX() {
+ assertFailsWith {
+ logImpl.log(10.0, 0.0)
+ }
+ assertFailsWith {
+ logImpl.log(10.0, -1.0)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/SecTest.kt b/src/test/kotlin/SecTest.kt
new file mode 100644
index 0000000..c97cbf9
--- /dev/null
+++ b/src/test/kotlin/SecTest.kt
@@ -0,0 +1,38 @@
+package test
+
+import function.base.SinTaylor
+import function.trigonometric.Sec
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class SecTest {
+ private val secImpl = Sec(SinTaylor())
+
+ @Test
+ fun testSecOne() {
+ val eps = 1e-10
+ val x = 0.5
+ val expected = 1.0 / cos(x)
+ val result = secImpl.sec(x, eps)
+ assertEquals(expected, result, eps * 10)
+ }
+
+ @Test
+ fun testSecZero() {
+ val eps = 1e-10
+ val x = 0.0
+ val result = secImpl.sec(x, eps)
+ assertEquals(1.0 / cos(x), result, eps * 10)
+ }
+
+ @Test
+ fun testSecInvalid() {
+ val eps = 1e-10
+ assertFailsWith {
+ secImpl.sec(PI / 2, eps)
+ }
+ }
+}
diff --git a/src/test/kotlin/SinTest.kt b/src/test/kotlin/SinTest.kt
new file mode 100644
index 0000000..5fca050
--- /dev/null
+++ b/src/test/kotlin/SinTest.kt
@@ -0,0 +1,45 @@
+package test
+
+import function.base.SinTaylor
+import org.junit.jupiter.api.Test
+import kotlin.math.PI
+import kotlin.math.sin
+import kotlin.test.assertEquals
+
+class SinTest {
+ private val sinTaylor = SinTaylor()
+
+ @Test
+ fun testSinZero() {
+ val eps = 1e-10
+ val result = sinTaylor.sin(0.0, eps)
+ assertEquals(0.0, result, eps)
+ }
+
+ @Test
+ fun testSinPiOver2() {
+ val eps = 1e-10
+ val x = PI / 2
+ val expected = sin(x)
+ val result = sinTaylor.sin(x, eps)
+ assertEquals(expected, result, eps)
+ }
+
+ @Test
+ fun testSinSmallX() {
+ val eps = 1e-10
+ val x = 0.1
+ val expected = sin(x)
+ val result = sinTaylor.sin(x, eps)
+ assertEquals(expected, result, eps)
+ }
+
+ @Test
+ fun testSinNegative() {
+ val eps = 1e-10
+ val x = -0.1
+ val expected = sin(x)
+ val result = sinTaylor.sin(x, eps)
+ assertEquals(expected, result, eps)
+ }
+}
diff --git a/src/test/kotlin/integration/BottomUpIntegrationTest.kt b/src/test/kotlin/integration/BottomUpIntegrationTest.kt
new file mode 100644
index 0000000..bf66b11
--- /dev/null
+++ b/src/test/kotlin/integration/BottomUpIntegrationTest.kt
@@ -0,0 +1,144 @@
+package integration
+
+import function.FunctionSystem
+import function.base.LnTaylor
+import function.base.SinTaylor
+import function.logarithmic.Log
+import function.stubs.CosStub
+import function.stubs.CotStub
+import function.stubs.CscStub
+import function.stubs.LnStub
+import function.stubs.LogStub
+import function.stubs.SecStub
+import function.stubs.SinStub
+import function.trigonometric.Cos
+import function.trigonometric.Cot
+import function.trigonometric.Csc
+import function.trigonometric.Sec
+import org.junit.jupiter.api.Test
+
+val eps = 1e-10
+
+class BottomUpIntegrationTest {
+ @Test
+ fun step1ReplaceLnStub() {
+ val sin = SinStub()
+ val ln = LnTaylor()
+ val cos = CosStub()
+ val csc = CscStub()
+ val sec = SecStub()
+ val cot = CotStub()
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ funcSys.compute(0.5)
+ }
+
+ @Test
+ fun step2ReplaceSinStub() {
+ val sin = SinTaylor()
+ val ln = LnStub()
+ val cos = CosStub()
+ val csc = CscStub()
+ val sec = SecStub()
+ val cot = CotStub()
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ }
+
+ @Test
+ fun step3CosWithSin() {
+ val sin = SinTaylor()
+ val ln = LnStub()
+ val cos = Cos(sin)
+ val csc = CscStub()
+ val sec = SecStub()
+ val cot = CotStub()
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ }
+
+ @Test
+ fun step4CscWithSin() {
+ val sin = SinTaylor()
+ val ln = LnStub()
+ val cos = CosStub()
+ val csc = Csc(sin)
+ val sec = SecStub()
+ val cot = CotStub()
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ }
+
+ @Test
+ fun step5SecWithCosSin() {
+ val sin = SinTaylor()
+ val ln = LnStub()
+ val cos = Cos(sin)
+ val csc = CscStub()
+ val sec = Sec(sin)
+ val cot = CotStub()
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ }
+
+ @Test
+ fun step6CotWithSinCos() {
+ val sin = SinTaylor()
+ val ln = LnStub()
+ val cos = Cos(sin)
+ val csc = CscStub()
+ val sec = SecStub()
+ val cot = Cot(sin)
+ val log = LogStub()
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ }
+
+ @Test
+ fun step7LogWithLn() {
+ val sin = SinStub()
+ val ln = LnTaylor()
+ val cos = CosStub()
+ val csc = CscStub()
+ val sec = SecStub()
+ val cot = CotStub()
+ val log = Log(ln)
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(0.5)
+ }
+
+ @Test
+ fun step8FullIntegration() {
+ val sin = SinTaylor()
+ val ln = LnTaylor()
+ val cos = Cos(sin)
+ val csc = Csc(sin)
+ val sec = Sec(sin)
+ val cot = Cot(sin)
+ val log = Log(ln)
+
+ val funcSys = FunctionSystem(sin, ln, cos, csc, sec, cot, log)
+
+ funcSys.compute(-0.5)
+ funcSys.compute(0.5)
+ }
+}