How can I write simulations in Erlang?

I want to make some numbers in Erlang as follows:

You have an array with the following values:

[2,3,4]

At each iteration, you compute

0.1 * [n-1] + 0.7 *[n] + 0.2 * [n+1]

It is getting new [n].

If n == 0 then [n-1] = 0. If [n] == length of array then [n] = 0.

So, I will try an example:

[2,3,4]

Calculations:

0.1 * 0 + 0.7 * 2 + 0.2 * 3 = 2

0.1 * 2 + 0.7 * 3 + 0.2 * 4 = 3.1

0.1 * 3 + 0.7 * 4 + 0.2 * 0 = 3.1

So, [2,3,4]after one iteration it becomes [2, 3.1, 3.1].

I know how to write it in a non-functional language, such as C. But it's hard for me to imagine how this can be done in Erlang. I found several guides on how you read a file in a list. So this is not a problem.

Erlang, ? , "", , , ? ?

, Erlang?

.

+3
5

:

-module(simulation).
-export([start/0]).

f([N0, N1, N2]) ->
    M0 =            0.7 * N0 + 0.2 * N1,
    M1 = 0.1 * N0 + 0.7 * N1 + 0.2 * N2,
    M2 = 0.1 * N1 + 0.7 * N2,
    [M0, M1, M2].

iterate(List, Iterations) ->
    iterate(1, List, Iterations).

iterate(_Iteration, List, 0) ->
    List;
iterate(Iteration, List = [N0, N1, N2], MoreIterations) ->
    io:format("~.5f  ~.5f  ~.5f~n", [N0, N1, N2]),
    NextList = f(List),
    iterate(Iteration + 1, NextList, MoreIterations-1).

start() ->
    iterate([2.0, 3.0, 4.0], 10),
    ok.

:

-module(simulation2).
-export([start/0]).

f(Prev, Current, Next) ->
    0.1 * Prev + 0.7 * Current + 0.2 * Next.

transform(List) ->
    transform(0.0, List, 0.0).

transform(_First, [], _Last) ->
    [];
transform(First, [X], Last) ->
    Y = f(First, X, Last),
    [Y];
transform(First, [X1, X2 | More], Last) ->
    Y1 = f(First, X1, X2),
    [Y1 | transform(X1, [X2 | More], Last)].

iterate(List, Iterations) ->
    iterate(1, List, Iterations).

iterate(_Iteration, List, 0) ->
    List;
iterate(Iteration, List, MoreIterations) ->
    io:format("~p~n", [List]),
    NextList = transform(List),
    iterate(Iteration + 1, NextList, MoreIterations-1).

start() ->
    iterate([1.0, 2.0, 3.0, 4.0, 5.0], 10),
    ok.
+3

. , , , ? . - . - - , C. , :

start() ->
    iterate([2.0, 3.0, 4.0, 5.0, ...], 10),
    ok.

. . :). C. , Erlang.

+1

( , , , , , , http://discoproject.org/).

, , Erlang, . (, .) , , .

0

iter([], Acc) ->
    lists:reverse(Acc);
iter([H|Tail], Acc) ->
    iter(Tail, [do_something_with(H)|Acc]).

, , , :

...
iter([H1,H2,H3|Tail], Acc) ->
    iter([H2,H3|Tail], [do_something_with(H1,H2,H3)|Acc]);
...

, , .

0

- , . , - , 4 , crash. , - , % BUG. : /2 , .. : ([1,2,3,4], 7), 7 - . 0 , . PID , . debuger im(). . , . , . , - ?

-module(simulation).
-compile(export_all).
%-export().

f(Prev, Current, Next) ->
    0.1 * Prev + 0.7 * Current + 0.2 * Next.

simulate([], _Iteration) -> [];
simulate([X], 0) -> [X];
simulate([X], Iteration) -> simulate([f(0.0, X, 0.0)], Iteration - 1);
simulate(Liste, 0) -> Liste;
simulate(Liste, Iteration) ->
    PidStarter = self(),
    {Number, ProcList} = startProcesses(Liste, Iteration, PidStarter), %BUG
    Connector = spawn(fun() -> simProcessStarter(0.0, PidStarter, Iteration, 0) end), %untested
    [H1, H2 | _] = ProcList,
    H1 ! {startinformation, Connector, H2}, %untested
    ReversedProcList = lists:reverse(ProcList),
    [L1, L2 | _] = ReversedProcList,
    L1 ! {startinformation, L2, Connector},%untested
    fold(ProcList),%untested
    evaluate(Number, []).%untested

fold([]) -> ready;
fold([_X1]) -> ready;
fold([_X1, _X2]) -> ready;
fold([X1, X2, X3 | Tail]) ->
    X2 ! {statusinformation, X1, X3},
    fold([X2, X3 | Tail]).

evaluate(0, List) ->
    List;
evaluate(N, List) ->
    receive 
        {N, Current} -> 
            Result = [Current | List]
    end,
    evaluate(N-1, Result).

% returns {number of processes, list of processes started}
startProcesses(Liste, Iteration, PidStarter) -> startProcesses(Liste, 0, Iteration, [], PidStarter).

startProcesses([], N, _Iteration, List, _PidStarter) -> {N, lists:reverse(List)};
startProcesses([H | T], N, Iteration, List, PidStarter) ->
    startProcesses([T], N + 1, Iteration, [spawn(fun() -> simProcessStarter(H, PidStarter, Iteration, N + 1) end) | List], PidStarter).

simProcessStarter(Current, PidStarter, Iteration, Number) ->
    receive 
        {startinformation, PidPrev, PidNext} -> 
            Result = simProcess(Current, PidPrev, self(), PidNext, Iteration, Number)
    end,
    PidStarter ! Result.

simProcess(Current, _PidPrev, _PidCurrent, _PidNext, 0, Number) ->
    {Number, Current};
simProcess(Current, PidPrev, PidCurrent, PidNext, Iteration, Number) ->
    PidNext ! {prev, PidCurrent, Current, Iteration},
    receive
        {prev, PidPrev, Prev, Iteration} -> Prev
    end,
    PidPrev ! {next, PidCurrent, Current, Iteration},
    receive
        {next, PidNext, Next, Iteration} -> Next
    end,
    New = f(Prev, Current, Next),
    simProcess(New, PidPrev, PidCurrent, PidNext, Iteration-1, Number).
0
source

Source: https://habr.com/ru/post/1735581/


All Articles