/*
Событийные функции
*/
//Данные по умолчанию
$(document).on('click', '#default', function(){
$('#HDE').val('Math.cos(y) / (a + x) + k * y * y')
$('#HDE_to').val(1)
$('#HDE_step').val(0.1)
$('#HDE_y0').val(0)
$('#HDE_x0').val(0)
$('#HDE_a').val('')
$('#HDE_k').val('')
$('#HDE_eps').val(0.001)
$('#HDE_opt').prop('checked', 'checked')
$('#opt').val('-Math.exp(-t)*Math.log(t)')
$('#opt_from').val(0)
$('#opt_to').val(2)
$('#opt_eps').val(0.001)
$('#int_point').val(6)
})
//ОДУ
$(document).on('click', '#HDE_getAnswer', function(){
if ($('#HDE_opt').prop('checked')) {
koef = dichotomy(
parseFloat($('#opt_from').val()),
parseFloat($('#opt_to').val()),
parseFloat($('#opt_eps').val()),
function(t) {
return eval($('#opt').val())
}
)
$('#HDE_a').val(koef.a)
$('#HDE_k').val(koef.k)
$('#opt_answer').html('<b>Точка минимума: ' + koef.a + ', ' + koef.k + '</b>')
}
result = autoStep(
parseFloat($('#HDE_x0').val()),
parseFloat($('#HDE_y0').val()),
parseFloat($('#HDE_step').val()),
parseFloat($('#HDE_to').val()),
parseFloat($('#HDE_eps').val()),
function (x, y) {
a = parseFloat($('#HDE_a').val())
k = parseFloat($('#HDE_k').val())
return eval($('#HDE').val())
}
)
if ($('#int_point').val()) {
interp = []
for (i = 0, x = parseFloat($('#HDE_x0').val()); x <= parseFloat($('#HDE_to').val()); x += parseFloat($('#HDE_step').val()), i++) {
interp[i] = [x, LangrangianMethod(result, parseFloat($('#int_point').val()), x)]
}
}
h = parseFloat($('#HDE_step').val())
if (!isInt(Math.abs(lg(h)))) {
h = Math.abs(Math.ceil(h))
}
outputArr(
result,
['x', 'y', 'h', 'm'],
[h, parseFloat($('#HDE_eps').val()), 5, 0],
'#autoStep'
)
plotData = result
for (i = 0; i < plotData.length; i++) {
delete plotData[i][2]
delete plotData[i][3]
}
$.plot($('#HDE_graph'), [plotData])
e = parseFloat($('#opt_eps').val()) / 100
outputArr(
koef.out,
['x1', 'x2', 'f(x1)', 'f(x2)', 'a', 'b'],
[e, e, e/100000, e/100000, e/100, e/100],
'#Dichotomy'
)
plotData = []
for (t = parseFloat($('#opt_from').val()); t <= parseFloat($('#opt_to').val()); t += 0.05) {
plotData.push([t, eval($('#opt').val())])
}
$.plot($('#opt_graph'), [plotData])
outputArr(
interp,
['x', 'y'],
[h, parseFloat($('#HDE_eps').val())],
'#Langrang'
)
$.plot($('#int_graph'), [interp])
})
//Тестовая оптимизация
$(document).on('click', '#opt_getAnswer', function(){
koef = dichotomy(
parseFloat($('#opt_from').val()),
parseFloat($('#opt_to').val()),
parseFloat($('#opt_eps').val()),
function(t) {
return eval($('#opt').val())
}
)
e = parseFloat($('#opt_eps').val()) / 100
outputArr(
koef.out,
['x1', 'x2', 'f(x1)', 'f(x2)', 'a', 'b'],
[e, e, e/100000, e/100000, e/100, e/100],
'#Dichotomy'
)
plotData = []
for (t = parseFloat($('#opt_from').val()); t <= parseFloat($('#opt_to').val()); t += 0.05) {
plotData.push([t, eval($('#opt').val())])
}
$.plot($('#opt_graph'), [plotData])
$('#opt_answer').text('Точка минимума: ' + koef.a + ', ' + koef.k)
})
/*
Мат. методы
*/
//Optimization
function dichotomy(a, b, eps, f) {
d = eps / 10
out = []
i = 0
do {
x1 = (a + b - d) / 2
x2 = (a + b + d) / 2
out[i] = [x1, x2, f(x1), f(x2), a, b]
i++
if ( f(x1) > f(x2) )
a = x1
else
b = x2
} while (b - a >= eps)
x = (a + b) / 2
y = f(x)
return {
"a": x,
"k": y,
"out": out
}
}
//Interpolation
function LangrangianMethod(diff, point, p) {
centralPoint = point == 0 ? Math.floor(diff.length / 2) : point - 1
var X = [diff[0][0], diff[centralPoint][0], diff[diff.length - 1][0]]
var Y = [diff[0][1], diff[centralPoint][1], diff[diff.length - 1][1]]
L = 0
var i, j
for (i = 0; i <= 2; i++) {
L1 = 1
for (j = 0; j <= 2; j++) {
if (i != j)
L1 = ((p - X[j]) / (X[i] - X[j])) * L1
}
L += L1 * Y[i]
}
return L
}
//HDE
function r(x0, y0, h, m, f) {
u = []
y = []
y[0] = y0
var i
for (i = 0; i < m; i++) {
u[0] = f(x0, y[i])
u[1] = f(x0 + h / 2, y[i] + h * u[0] / 2)
u[2] = f(x0 + h / 2, y[i] + h * u[1] / 2)
u[3] = f(x0 + h, y[i] + h * u[2])
y[i + 1] = y[i] + (h / 6) * (u[0] + 2 * u[1] + 2 * u[2] + u[3])
x0 += h
}
return y[m]
}
function autoStep(x0, y0, h0, b, Eps, fun) {
output = []
var h
output[0] = [x0, y0, h0, 0]
n = Math.ceil((b - x0) / h0) + 1
for (i = 1; i < n; i++) {
h = h0
m = 1
y = r(x0, y0, h, m, fun)
do {
y1 = y
h /= 2
x = x0
y = y0
m = 2 * m
y = r(x, y, h, m, fun)
} while (Math.abs(y - y1) >= Eps)
x0 += h0
y0 = y
output[i] = [x0, y0, h, m]
}
return output
}
function outputArr(arr, title, eps, selector) {
for (i = 0; i < eps.length; i++)
eps[i] = isInt(eps[i]) ? eps[i] : Math.abs(Math.log(parseFloat(eps[i])) / Math.log(10)).toFixed(0)
str = '<tr>'
for (i = 0; i < title.length; i++)
str += '<td>' + title[i] + '</td>'
str += '</tr>'
for (i = 0; i < arr.length; i++) {
str += '<tr>'
for (j = 0; j < arr[0].length; j++)
str += '<td>' + arr[i][j].toFixed(eps[j]) + '</td>'
str += '</tr>'
}
$(selector).html(str)
}
function isInt(number) {
return Math.floor(number) == Math.ceil(number) || number + 0.000001 > Math.ceil(number)
}
function lg(number) {
return Math.log(parseFloat(number)) / Math.log(10)
}