Алгоритм метода расщепления - PullRequest
0 голосов
/ 23 февраля 2019

(x^3 - 2x^2 - 5) - это мое уравнение. Прежде всего, у меня есть два значения типа x = 2 and x = 4. Мои первые два значения должны учитываться для уравнения, и их результаты должны быть отрицательными и положительными каждый раз.И второй шаг - (2 + 4) / 2 = 3 на этот раз x = 3 в уравнении.И математическая операция продолжается с последним положительным значением и одним отрицательным значением.Я пытаюсь это

var x = 2.0
var equation = pow(x, 3) - 2 * pow(x, 2) - 5

switch x {
case x : 2
equation = pow(x, 3) - 2 * pow(x, 2) - 5
case x : 4
equation = pow(x, 3) - 2 * pow(x, 2) - 5
default:
0
}  
print(equation)

Как я могу назначить первые два значения, как 2 и 4 для одного var x?

1 Ответ

0 голосов
/ 23 февраля 2019

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

func f(_ x: Double) -> Double {
    return pow(x, 3) - 2 * pow(x, 2) - 5
}

Затем вам понадобятся две переменные для левой и правой границытекущий интервалОни должны быть выбраны так, чтобы f(x) имел противоположные знаки на границах.В вашем примере:

var xleft = 2.0   // f(xleft) < 0
var xright = 4.0  // f(xright) > 0

Теперь вы можете запустить итерацию: вычислите f(x) в средней точке текущего интервала и замените xleft на xright, в зависимости от того, является ли f(x) отрицательнымили положительный.Продолжайте, пока приближение не будет достаточно для ваших целей:

let eps = 0.0000001 // Desired precision
let leftSign = f(xleft).sign

repeat {
    let x = (xleft + xright)/2.0
    let y = f(x)
    if y == 0 {
        xleft = x
        break
    } else if y.sign == leftSign {
        xleft = x
    } else {
        xright = x
    }
    // print(xleft, xright)
} while xright - xleft > eps

// Print approximate solution:
print(xleft)

Следующим шагом будет реализация самого метода деления пополам как функции:

func bisect(_ f: ((Double) -> Double), xleft: Double, xright: Double, eps: Double = 1.0e-6) -> Double {
    let yleft = f(xleft)
    let yright = f(xright)

    precondition(yleft * yright <= 0, "f must have opposite sign at the boundaries")

    var xleft = xleft
    var xright = xright

    repeat {
        let x = (xleft + xright)/2.0
        let y = f(x)
        if y == 0 {
            return x
        } else if y.sign == yleft.sign {
            xleft = x
        } else {
            xright = x
        }
    } while xright - xleft > eps

    return (xleft + xright)/2.0
}

, чтобы онможет использоваться с произвольными уравнениями:

let sol1 = bisect({ x in pow(x, 3) - 2 * pow(x, 2) - 5 }, xleft: 2.0, xright: 4.0)
print(sol1) // 2.690647602081299

let sol2 = bisect({ x in cos(x/2)}, xleft: 3.0, xright: 4.0, eps: 1.0e-15)
print(sol2) // 3.1415926535897936
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...