Output:

lua5.3: Main.lua:33: attempt to call a nil value (field 'abs')
stack traceback:
	Main.lua:33: in field 'exp'
	Main.lua:40: in main chunk
	[C]: in ?
```lua
-- mathematic.lua
local mathematic = {}

-- =======================
-- Константы
-- =======================

-- Приближение числа пи с использованием ряда Нилаканта
local function calculate_pi(iterations)
    local pi = 3
    local sign = 1
    local denominator = 2
    for _ = 1, iterations do
        pi = pi + sign * (4 / (denominator * (denominator + 1) * (denominator + 2)))
        sign = -sign
        denominator = denominator + 2
    end
    return pi
end

mathematic.pi = calculate_pi(100000)

-- Определение бесконечности
mathematic.infinity = 1 / 0

-- Число e
function mathematic.exp(x)
    local sum = 1
    local term = 1
    for n = 1, 100 do
        term = term * x / n
        sum = sum + term
        if mathematic.abs(term) < 1e-14 then
            break
        end
    end
    return sum
end

mathematic.e = mathematic.exp(1)

-- =======================
-- Алгебраические функции
-- =======================

function mathematic.abs(x)
    return x >= 0 and x or -x
end

function mathematic.sqrt(x)
    if x < 0 then
        error("Square root of negative number")
    end
    local guess = x / 2
    for i = 1, 20 do
        guess = (guess + x / guess) / 2
    end
    return guess
end

function mathematic.ln(x)
    if x <= 0 then
        error("ln undefined for non-positive values")
    end
    local n = 1000
    local sum = 0
    for k = 1, n do
        sum = sum + (1 / k) * ((x - 1) / x)^k
    end
    return sum
end

function mathematic.power(a, b)
    if a == 0 then
        if b == 0 then
            return 1
        elseif b > 0 then
            return 0
        else
            error("Zero cannot be raised to a negative power")
        end
    elseif a > 0 then
        return mathematic.exp(b * mathematic.ln(a))
    elseif a < 0 then
        if b % 1 == 0 then
            local result = mathematic.exp(b * mathematic.ln(-a))
            return (b % 2 == 1) and -result or result
        else
            error("Negative base with non-integer exponent results in complex number")
        end
    end
end

function mathematic.factorial(n)
    if n < 0 then
        error("Factorial is not defined for negative numbers")
    end
    local result = 1
    for i = 2, n do
        result = result * i
    end
    return result
end

function mathematic.floor(x)
    if x >= 0 then
        local integer_part = 0
        while integer_part + 1 <= x do
            integer_part = integer_part + 1
        end
        return integer_part
    else
        local integer_part = 0
        while integer_part - 1 >= x do
            integer_part = integer_part - 1
        end
        return integer_part
    end
end

function mathematic.mod(a, b)
    if b == 0 then
        error("Modulo by zero")
    end
    return a - mathematic.floor(a / b) * b
end

function mathematic.int(x)
    return mathematic.floor(x)
end

function mathematic.gcd(a, b)
    a = mathematic.abs(a)
    b = mathematic.abs(b)
    while b ~= 0 do
        a, b = b, mathematic.mod(a, b)
    end
    return a
end

function mathematic.lcm(a, b)
    if a == 0 or b == 0 then
        return 0
    end
    return mathematic.abs((a * b) / mathematic.gcd(a, b))
end

-- Метод Ньютона для нахождения корня функции f с производной df
function mathematic.newton_method(f, df, x0, tolerance, max_iterations)
    tolerance = tolerance or 1e-10
    max_iterations = max_iterations or 1000
    local x = x0
    for i = 1, max_iterations do
        local y = f(x)
        local y_prime = df(x)
        if y_prime == 0 then
            error("Производная равна нулю. Метод Ньютона не применим.")
        end
        local x_new = x - y / y_prime
        if mathematic.abs(x_new - x) < tolerance then
            return x_new
        end
        x = x_new
    end
    error("Метод Ньютона не сошелся за заданное число итераций.")
end

-- Вычисление значения полинома по коэффициентам и значению x
function mathematic.evaluate_polynomial(coefficients, x)
    local result = 0
    for i = #coefficients, 1, -1 do
        result = result * x + coefficients[i]
    end
    return result
end

-- Вычисление производной полинома
function mathematic.evaluate_polynomial_derivative(coefficients, x)
    local result = 0
    for i = #coefficients, 2, -1 do
        result = result * x + (i - 1) * coefficients[i]
    end
    return result
end

-- Решение полинома произвольной степени методом Ньютона
function mathematic.solve_polynomial(coefficients, x0_values, tolerance, max_iterations)
    local roots = {}
    local found_roots = {}
    for _, x0 in ipairs(x0_values) do
        local status, root = pcall(function()
            return mathematic.newton_method(
                function(x) return mathematic.evaluate_polynomial(coefficients, x) end,
                function(x) return mathematic.evaluate_polynomial_derivative(coefficients, x) end,
                x0, tolerance, max_iterations
            )
        end)
        if status then
            local is_new = true
            for _, r in ipairs(found_roots) do
                if mathematic.abs(r - root) < tolerance then
                    is_new = false
                    break
                end
            end
            if is_new then
                table.insert(roots, root)
                table.insert(found_roots, root)
            end
        end
    end
    return roots
end

-- =======================
-- Тригонометрические функции
-- =======================

function mathematic.deg_to_rad(degrees)
    return degrees * mathematic.pi / 180
end

function mathematic.rad_to_deg(radians)
    return radians * 180 / mathematic.pi
end

function mathematic.sin(x)
    x = x % (2 * mathematic.pi)
    if x > mathematic.pi then
        x = x - 2 * mathematic.pi
    elseif x < -mathematic.pi then
        x = x + 2 * mathematic.pi
    end

    local term = x
    local sum = term
    local n = 1
    local sign = -1

    while mathematic.abs(term) > 1e-10 do
        term = term * x * x / ((2 * n) * (2 * n + 1))
        sum = sum + sign * term
        sign = -sign
        n = n + 1
    end

    return sum
end

function mathematic.cos(x)
    x = x % (2 * mathematic.pi)
    if x > mathematic.pi then
        x = x - 2 * mathematic.pi
    elseif x < -mathematic.pi then
        x = x + 2 * mathematic.pi
    end

    local term = 1
    local sum = term
    local n = 1
    local sign = -1

    while mathematic.abs(term) > 1e-10 do
        term = term * x * x / ((2 * n - 1) * (2 * n))
        sum = sum + sign * term
        sign = -sign
        n = n + 1
    end

    return sum
end

function mathematic.tan(x)
    local cosx = mathematic.cos(x)
    if cosx == 0 then
        return mathematic.infinity
    end
    return mathematic.sin(x) / cosx
end

function mathematic.cot(x)
    local sinx = mathematic.sin(x)
    if sinx == 0 then
        return mathematic.infinity
    end
    return mathematic.cos(x) / sinx
end

function mathematic.sec(x)
    local cosx = mathematic.cos(x)
    if cosx == 0 then
        return mathematic.infinity
    end
    return 1 / cosx
end

function mathematic.csc(x)
    local sinx = mathematic.sin(x)
    if sinx == 0 then
        return mathematic.infinity
    end
    return 1 / sinx
end

function mathematic.sinh(x)
    return (mathematic.exp(x) - mathematic.exp(-x)) / 2
end

function mathematic.cosh(x)
    return (mathematic.exp(x) + mathematic.exp(-x)) / 2
end

function mathematic.tanh(x)
    local coshx = mathematic.cosh(x)
    if coshx == 0 then
        return mathematic.infinity
    end
    return mathematic.sinh(x) / coshx
end

function mathematic.asin(x)
    if x < -1 or x > 1 then
        error("Asin undefined for |x| > 1")
    end
    if x == 1 then
        return mathematic.pi / 2
    elseif x == -1 then
        return -mathematic.pi / 2
    end

    local guess = x
    for _ = 1, 100 do
        local f = mathematic.sin(guess) - x
        local f_derivative = mathematic.cos(guess)
        if f_derivative == 0 then
            break
        end
        local new_guess = guess - f / f_derivative
        if mathematic.abs(new_guess - guess) < 1e-10 then
            return new_guess
        end
        guess = new_guess
    end
    return guess
end

function mathematic.acos(x)
    return mathematic.pi / 2 - mathematic.asin(x)
end

function mathematic.atan(x)
    if x == mathematic.infinity then
        return mathematic.pi / 2
    elseif x == -mathematic.infinity then
        return -mathematic.pi / 2
    end

    local guess = x
    for _ = 1, 100 do
        local sine = mathematic.sin(guess)
        local cosine = mathematic.cos(guess)
        local f = sine / cosine - x
        local cosine_sq = cosine * cosine
        if cosine_sq == 0 then
            break
        end
        local f_derivative = 1 / cosine_sq
        local new_guess = guess - f / f_derivative
        if mathematic.abs(new_guess - guess) < 1e-10 then
            return new_guess
        end
        guess = new_guess
    end
    return guess
end

function mathematic.arctanh(x)
    if x <= -1 or x >= 1 then
        error("atanh undefined for |x| >= 1")
    end
    return 0.5 * mathematic.ln((1 + x) / (1 - x))
end

function mathematic.asinh(x)
    return mathematic.ln(x + mathematic.sqrt(x * x + 1))
end

function mathematic.acosh(x)
    if x < 1 then
        error("acosh undefined for x < 1")
    end
    return mathematic.ln(x + mathematic.sqrt(x * x - 1))
end

function mathematic.atanh(x)
    if x <= -1 or x >= 1 then
        error("atanh undefined for |x| >= 1")
    end
    return 0.5 * mathematic.ln((1 + x) / (1 - x))
end

-- =======================
-- Полиномиальные функции
-- =======================

function mathematic.solve_quadratic(a, b, c)
    if a == 0 then
        if b == 0 then
            error("No solution")
        else
            return -c / b
        end
    end
    local discriminant = b * b - 4 * a * c
    if discriminant > 0 then
        local sqrt_d = mathematic.sqrt(discriminant)
        return (-b + sqrt_d) / (2 * a), (-b - sqrt_d) / (2 * a)
    elseif discriminant == 0 then
        return -b / (2 * a)
    else
        return nil, nil
    end
end

function mathematic.solve_cubic(a, b, c, d)
    if a == 0 then
        return mathematic.solve_quadratic(b, c, d)
    end
    b = b / a
    c = c / a
    d = d / a

    local Q = (3 * c - b * b) / 9
    local R = (9 * b * c - 27 * d - 2 * b * b * b) / 54
    local D = Q * Q * Q + R * R

    if D >= 0 then
        local S = mathematic.cbrt(R + mathematic.sqrt(D))
        local T = mathematic.cbrt(R - mathematic.sqrt(D))
        return S + T - b / 3
    else
        local theta = mathematic.acos(R / mathematic.sqrt(-Q * Q * Q))
        return 2 * mathematic.sqrt(-Q) * mathematic.cos(theta / 3) - b / 3
    end
end

function mathematic.factorize_polynomial(coefficients)
    local roots = {}
    local a0 = coefficients[1]
    local an = coefficients[#coefficients]

    local function possible_roots()
        local factors_a0 = {}
        local factors_an = {}
        for i = 1, mathematic.abs(a0) do
            if a0 % i == 0 then
                table.insert(factors_a0, i)
                table.insert(factors_a0, -i)
            end
        end
        for i = 1, mathematic.abs(an) do
            if an % i == 0 then
                table.insert(factors_an, i)
                table.insert(factors_an, -i)
            end
        end
        local candidates = {}
        for _, p in ipairs(factors_a0) do
            for _, q in ipairs(factors_an) do
                if q ~= 0 then
                    table.insert(candidates, p / q)
                end
            end
        end
        return candidates
    end

    local candidates = possible_roots()
    for _, r in ipairs(candidates) do
        if mathematic.abs(mathematic.evaluate_polynomial(coefficients, r)) < 1e-6 then
            table.insert(roots, r)
        end
    end
    return roots
end

-- =======================
-- Линейная алгебра
-- =======================

function mathematic.vector_add(v1, v2)
    if #v1 ~= #v2 then
        error("Vectors must be of the same length")
    end
    local result = {}
    for i = 1, #v1 do
        result[i] = v1[i] + v2[i]
    end
    return result
end

function mathematic.dot_product(v1, v2)
    if #v1 ~= #v2 then
        error("Vectors must be of the same length")
    end
    local result = 0
    for i = 1, #v1 do
        result = result + v1[i] * v2[i]
    end
    return result
end

function mathematic.cross_product(v1, v2)
    if #v1 ~= 3 or #v2 ~= 3 then
        error("Cross product is defined for 3-dimensional vectors only")
    end
    return {
        v1[2] * v2[3] - v1[3] * v2[2],
        v1[3] * v2[1] - v1[1] * v2[3],
        v1[1] * v2[2] - v1[2] * v2[1]
    }
end

function mathematic.matrix_add(m1, m2)
    local rows = #m1
    local cols = #m1[1]
    if rows ~= #m2 or cols ~= #m2[1] then
        error("Matrices must have the same dimensions")
    end
    local result = {}
    for i = 1, rows do
        result[i] = {}
        for j = 1, cols do
            result[i][j] = m1[i][j] + m2[i][j]
        end
    end
    return result
end

function mathematic.matrix_subtract(m1, m2)
    local rows = #m1
    local cols = #m1[1]
    if rows ~= #m2 or cols ~= #m2[1] then
        error("Matrices must have the same dimensions")
    end
    local result = {}
    for i = 1, rows do
        result[i] = {}
        for j = 1, cols do
            result[i][j] = m1[i][j] - m2[i][j]
        end
    end
    return result
end

function mathematic.matrix_multiply(m1, m2)
    local rows_m1 = #m1
    local cols_m1 = #m1[1]
    local rows_m2 = #m2
    local cols_m2 = #m2[1]

    if cols_m1 ~= rows_m2 then
        error("Number of columns of first matrix must equal number of rows of second matrix")
    end

    local result = {}
    for i = 1, rows_m1 do
        result[i] = {}
        for j = 1, cols_m2 do
            local sum = 0
            for k = 1, cols_m1 do
                sum = sum + m1[i][k] * m2[k][j]
            end
            result[i][j] = sum
        end
    end
    return result
end

function mathematic.matrix_transpose(m)
    local rows = #m
    local cols = #m[1]
    local result = {}
    for i = 1, cols do
        result[i] = {}
        for j = 1, rows do
            result[i][j] = m[j][i]
        end
    end
    return result
end

function mathematic.matrix_determinant(m)
    local n = #m
    for i = 1, n do
        if #m[i] ~= n then
            error("Determinant is defined for square matrices only")
        end
    end

    if n == 1 then
        return m[1][1]
    elseif n == 2 then
        return m[1][1]*m[2][2] - m[1][2]*m[2][1]
    else
        local det = 0
        for col = 1, n do
            local submatrix = {}
            for i = 2, n do
                submatrix[i-1] = {}
                local subcol = 1
                for j = 1, n do
                    if j ~= col then
                        submatrix[i-1][subcol] = m[i][j]
                        subcol = subcol + 1
                    end
                end
            end
            det = det + ((col % 2 == 1) and 1 or -1) * m[1][col] * mathematic.matrix_determinant(submatrix)
        end
        return det
    end
end

function mathematic.matrix_inverse(m)
    local det = mathematic.matrix_determinant(m)
    if det == 0 then
        error("Matrix is singular and cannot be inverted")
    end

    local n = #m
    local adjugate = {}
    for i = 1, n do
        adjugate[i] = {}
        for j = 1, n do
            local submatrix = {}
            for row = 1, n do
                if row ~= i then
                    submatrix[#submatrix + 1] = {}
                    for col = 1, n do
                        if col ~= j then
                            table.insert(submatrix[#submatrix], m[row][col])
                        end
                    end
                end
            end
            adjugate[j][i] = ((i + j) % 2 == 0 and 1 or -1) * mathematic.matrix_determinant(submatrix)
        end
    end

    for i = 1, n do
        for j = 1, n do
            adjugate[i][j] = adjugate[i][j] / det
        end
    end

    return adjugate
end

-- =======================
-- Матричные функции
-- =======================

function mathematic.matrix_identity(n)
    local identity = {}
    for i = 1, n do
        identity[i] = {}
        for j = 1, n do
            identity[i][j] = (i == j) and 1 or 0
        end
    end
    return identity
end

function mathematic.matrix_zero(n)
    local zero = {}
    for i = 1, n do
        zero[i] = {}
        for j = 1, n do
            zero[i][j] = 0
        end
    end
    return zero
end

function mathematic.matrix_scalar_multiply(m, scalar)
    local result = {}
    for i = 1, #m do
        result[i] = {}
        for j = 1, #m[1] do
            result[i][j] = m[i][j] * scalar
        end
    end
    return result
end

function mathematic.matrix_copy(matrix)
    local copy = {}
    for i, row in ipairs(matrix) do
        copy[i] = {}
        for j, val in ipairs(row) do
            copy[i][j] = val
        end
    end
    return copy
end

function mathematic.matrix_exp(m)
    local n = #m
    local result = mathematic.matrix_identity(n)
    local term = mathematic.matrix_identity(n)
    for k = 1, 20 do
        term = mathematic.matrix_multiply(term, m)
        for i = 1, n do
            for j = 1, n do
                term[i][j] = term[i][j] / k
            end
        end
        result = mathematic.matrix_add(result, term)
    end
    return result
end

function mathematic.matrix_log(m)
    local n = #m
    local identity = mathematic.matrix_identity(n)
    local diff = mathematic.matrix_subtract(m, identity)
    local term = mathematic.matrix_copy(diff)
    local result = mathematic.matrix_copy(diff)
    for k = 2, 20 do
        term = mathematic.matrix_multiply(term, diff)
        local factor = ((-1)^(k+1)) / k
        local scaled_term = mathematic.matrix_scalar_multiply(term, factor)
        result = mathematic.matrix_add(result, scaled_term)
    end
    return result
end

function mathematic.matrix_sin(m)
    local n = #m
    local result = mathematic.matrix_zero(n)
    local term = m
    local sign = 1
    for k = 1, 20, 2 do
        local factor = 1 / mathematic.factorial(k)
        local scaled_term = mathematic.matrix_scalar_multiply(term, factor * sign)
        result = mathematic.matrix_add(result, scaled_term)
        term = mathematic.matrix_multiply(term, mathematic.matrix_multiply(m, m))
        sign = -sign
    end
    return result
end

function mathematic.matrix_cos(m)
    local n = #m
    local result = mathematic.matrix_identity(n)
    local term = mathematic.matrix_multiply(m, m)
    local sign = -1
    for k = 2, 20, 2 do
        local factor = 1 / mathematic.factorial(k)
        local scaled_term = mathematic.matrix_scalar_multiply(term, factor * sign)
        result = mathematic.matrix_add(result, scaled_term)
        term = mathematic.matrix_multiply(term, mathematic.matrix_multiply(m, m))
        sign = -sign
    end
    return result
end

-- =======================
-- Комбинаторика
-- =======================

function mathematic.permutation(n, k)
    if k > n then
        return 0
    end
    return mathematic.factorial(n) / mathematic.factorial(n - k)
end

function mathematic.combination(n, k)
    if k > n then
        return 0
    end
    return mathematic.factorial(n) / (mathematic.factorial(k) * mathematic.factorial(n - k))
end

function mathematic.generate_combinations(arr, k)
    local result = {}
    local function combinate(prefix, start, k)
        if k == 0 then
            table.insert(result, prefix)
            return
        end
        for i = start, #arr do
            local new_prefix = {table.unpack(prefix)}
            table.insert(new_prefix, arr[i])
            combinate(new_prefix, i + 1, k - 1)
        end
    end
    combinate({}, 1, k)
    return result
end

function mathematic.generate_permutations(arr)
    local result = {}
    local function permute(a, n)
        if n == 0 then
            table.insert(result, {table.unpack(a)})
        else
            for i = 1, n do
                a[n], a[i] = a[i], a[n]
                permute(a, n - 1)
                a[n], a[i] = a[i], a[n]
            end
        end
    end
    permute(arr, #arr)
    return result
end

-- =======================
-- Численные методы
-- =======================

function mathematic.newton_optimization(f, df, ddf, x0, tolerance, max_iterations)
    tolerance = tolerance or 1e-10
    max_iterations = max_iterations or 1000
    local x = x0
    for i = 1, max_iterations do
        local y_prime = df(x)
        local y_double_prime = ddf(x)
        if y_double_prime == 0 then
            error("Вторая производная равна нулю. Метод Ньютона не применим.")
        end
        local x_new = x - y_prime / y_double_prime
        if mathematic.abs(x_new - x) < tolerance then
            return x_new
        end
        x = x_new
    end
    error("Метод Ньютона не сошелся за заданное число итераций.")
end

function mathematic.stochastic_gradient_descent(f, df, data, params, learning_rate, epochs)
    for epoch = 1, epochs do
        for i, sample in ipairs(data) do
            local gradient = df(sample, params)
            for j = 1, #params do
                params[j] = params[j] - learning_rate * gradient[j]
            end
        end
    end
    return params
end

-- =======================
-- Анализ и высшая математика
-- =======================

function mathematic.dft(input)
    local N = #input
    local output = {}
    for k = 0, N - 1 do
        local sum_real = 0
        local sum_imag = 0
        for n = 0, N - 1 do
            local angle = -2 * mathematic.pi * k * n / N
            sum_real = sum_real + input[n + 1] * mathematic.cos(angle)
            sum_imag = sum_imag + input[n + 1] * mathematic.sin(angle)
        end
        output[k + 1] = { real = sum_real, imag = sum_imag }
    end
    return output
end

-- =======================
-- Статистика и теория вероятностей
-- =======================

function mathematic.mean(data)
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    return sum / #data
end

function mathematic.sum(data)
    local total = 0
    for _, v in ipairs(data) do
        total = total + v
    end
    return total
end

function mathematic.chi_squared_test(observed, expected)
    if #observed ~= #expected then
        error("Массивы наблюдаемых и ожидаемых частот должны быть одинаковой длины.")
    end
    local chi_sq = 0
    for i = 1, #observed do
        if expected[i] == 0 then
            error("Ожидаемая частота не может быть нулевой.")
        end
        chi_sq = chi_sq + ((observed[i] - expected[i])^2) / expected[i]
    end
    return chi_sq
end

function mathematic.anova_one_way(groups)
    local k = #groups
    local n_total = 0
    local grand_mean = 0

    for _, group in ipairs(groups) do
        n_total = n_total + #group
        grand_mean = grand_mean + mathematic.sum(group)
    end
    grand_mean = grand_mean / n_total

    local ss_between = 0
    for _, group in ipairs(groups) do
        local mean = mathematic.mean(group)
        ss_between = ss_between + #group * (mean - grand_mean)^2
    end

    local ss_within = 0
    for _, group in ipairs(groups) do
        local mean = mathematic.mean(group)
        for _, value in ipairs(group) do
            ss_within = ss_within + (value - mean)^2
        end
    end

    local df_between = k - 1
    local df_within = n_total - k
    local ms_between = ss_between / df_between
    local ms_within = ss_within / df_within
    local F = ms_between / ms_within

    return {
        ss_between = ss_between,
        ss_within = ss_within,
        df_between = df_between,
        df_within = df_within,
        ms_between = ms_between,
        ms_within = ms_within,
        F = F
    }
end

-- =======================
-- Функции комплексного анализа
-- =======================

function mathematic.differentiate(f, x, h)
    h = h or 1e-5
    return (f(x + h) - f(x - h)) / (2 * h)
end

function mathematic.is_analytic(f, x, y)
    local h = 1e-5
    local u = function(a, b)
        return f(a, b).real
    end
    local v = function(a, b)
        return f(a, b).imag
    end
    local du_dx = mathematic.differentiate(function(a) return u(a, y) end, x, h)
    local du_dy = mathematic.differentiate(function(b) return u(x, b) end, y, h)
    local dv_dx = mathematic.differentiate(function(a) return v(a, y) end, x, h)
    local dv_dy = mathematic.differentiate(function(b) return v(x, b) end, y, h)
    return mathematic.abs(du_dx - dv_dy) < 1e-5 and mathematic.abs(du_dy + dv_dx) < 1e-5
end

function mathematic.residue(f, z0, order)
    local factorial = mathematic.factorial
    local function derivative(n, x)
        local h = 1e-5
        if n == 0 then
            return f(x)
        else
            return (derivative(n - 1, x + h) - derivative(n - 1, x - h)) / (2 * h)
        end
    end
    local res = (1 / factorial(order - 1)) * derivative(order - 1, z0)
    return res
end

-- Возвращение таблицы библиотеки
return mathematic
```