|
1 | | -lab3 |
| 1 | +# Completed by |
| 2 | +Зонов Николай |
| 3 | + - - - |
| 4 | +# Lab 3 |
| 5 | + |
| 6 | +Запуск |
| 7 | + |
| 8 | +```bash |
| 9 | +./lab3.escript --linear --lagrange --newton --gauss --step 0.1 -n 4 |
| 10 | +``` |
| 11 | +--linear, --lagrange, --newton, --gauss — включение соответствующих методов. |
| 12 | + |
| 13 | +--step S — шаг генерации промежуточных точек (по умолчанию 0.5). |
| 14 | + |
| 15 | +# Ключевые моменты реализации |
| 16 | + |
| 17 | +## Точка входа |
| 18 | +```erlang |
| 19 | +-record(state, { |
| 20 | + methods = [], % [linear,lagrange,newton,gauss] |
| 21 | + step = 0.5, |
| 22 | + n = 4 |
| 23 | +}). |
| 24 | + |
| 25 | +main(Args) -> |
| 26 | + State0 = parse_args(Args, #state{}), |
| 27 | + Methods = |
| 28 | + case State0#state.methods of |
| 29 | + [] -> [linear]; |
| 30 | + Ms -> lists:usort(Ms) |
| 31 | + end, |
| 32 | + State = State0#state{methods = Methods}, |
| 33 | + |
| 34 | + PrinterPid = spawn(fun() -> printer_loop() end), |
| 35 | + GeneratorPid = spawn(fun() -> generator_loop(State#state.step) end), |
| 36 | + MethodPids = start_methods(State, GeneratorPid, PrinterPid), |
| 37 | + |
| 38 | + GeneratorPid ! {methods, MethodPids}, |
| 39 | + input_loop(State, MethodPids, GeneratorPid, []), |
| 40 | + |
| 41 | + receive after 1000 -> ok end, |
| 42 | + |
| 43 | + GeneratorPid ! eof, |
| 44 | + lists:foreach(fun(P) -> P ! eof end, MethodPids), |
| 45 | + PrinterPid ! eof, |
| 46 | + ok. |
| 47 | +``` |
| 48 | +## Цикл для ввода |
| 49 | +```erlang |
| 50 | +input_loop(State, MethodPids, GenPid, Points) -> |
| 51 | + case io:get_line("") of |
| 52 | + eof -> ok; |
| 53 | + Line -> |
| 54 | + case parse_point(Line) of |
| 55 | + {ok, {X, Y}} -> |
| 56 | + NewPoints0 = Points ++ [{X, Y}], |
| 57 | + NewPoints = lists:sort(fun({A,_},{B,_}) -> A =< B end, NewPoints0), |
| 58 | + lists:foreach(fun(Pid) -> Pid ! {window, NewPoints} end, MethodPids), |
| 59 | + input_loop(State, MethodPids, GenPid, NewPoints); |
| 60 | + error -> input_loop(State, MethodPids, GenPid, Points) |
| 61 | + end |
| 62 | + end. |
| 63 | + |
| 64 | +``` |
| 65 | +## Интерполяции всякие |
| 66 | +```erlang |
| 67 | +compute_linear(_X, []) -> undefined; |
| 68 | +compute_linear(_X, [_]) -> undefined; |
| 69 | +compute_linear(X, Points) -> |
| 70 | + case find_segment(X, Points) of |
| 71 | + none -> undefined; |
| 72 | + {{X1,Y1},{X2,Y2}} -> |
| 73 | + case X2 =:= X1 of |
| 74 | + true -> Y1; |
| 75 | + false -> |
| 76 | + T = (X - X1) / (X2 - X1), |
| 77 | + Y1 + T * (Y2 - Y1) |
| 78 | + end |
| 79 | + end. |
| 80 | + |
| 81 | +compute_lagrange(_X, []) -> undefined; |
| 82 | +compute_lagrange(_X, [{_,Y}]) -> Y; |
| 83 | +compute_lagrange(X, Points) -> |
| 84 | + Indexed = index_points(Points, 1), |
| 85 | + lists:sum( |
| 86 | + [ Yi * lagrange_basis(I, X, Points, Indexed) |
| 87 | + || {I,{_Xi,Yi}} <- Indexed ]). |
| 88 | + |
| 89 | +compute_newton(_X, []) -> undefined; |
| 90 | +compute_newton(_X, [{_,Y}]) -> Y; |
| 91 | +compute_newton(X, Points) -> |
| 92 | + Coefs = newton_divided_diffs(Points), |
| 93 | + newton_eval(X, Points, Coefs). |
| 94 | + |
| 95 | +``` |
0 commit comments