-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrix_server.erl
93 lines (72 loc) · 2.56 KB
/
matrix_server.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
%% @author Daher Daher
%% @doc matrix_server. Server for matrix multiplication
-module(matrix_server).
%% ====================================================================
%% API functions
%% ====================================================================
-export([start_server/0]).
-export([mult/2]).
-export([shutdown/0]).
-export([get_version/0]).
-export([mult2/4]).
-export([cross/5]).
-export([mult_loop/2]).
-export([server_loop/0]).
%% ====================================================================
%% Functions implementation
%% ====================================================================
start_server() ->
spawn(matrix_server_supervisor,matrix_server_start,[]).
shutdown()-> matrix_server ! shutdown.
get_version()->
MsgRef = make_ref(),
matrix_server ! {self(), MsgRef, get_version},
receive
{MsgRef,Version} -> Version
end.
mult(Mat1, Mat2)->
MsgRef = make_ref(),
matrix_server ! {self(), MsgRef, {multiple, Mat1, Mat2}},
receive
{MsgRef,Res} -> Res
end.
%% ====================================================================
%% Auxiliary functions
%% ====================================================================
server_loop() ->
receive
{Pid, MsgRef, {multiple, Mat1, Mat2}} ->
spawn(?MODULE, mult2, [Pid, MsgRef, Mat1, Mat2]),
server_loop();
{Pid, MsgRef, get_version} -> Pid ! {MsgRef, version_1},
server_loop();
sw_upgrade ->
?MODULE:server_loop();
shutdown -> exit(shutdown);
_->
server_loop()
end.
mult2(Pid, MsgRef, Mat1, Mat2)->
ResRowsNum = tuple_size(matrix:getCol(Mat1,1)),
ResColsNum = tuple_size(matrix:getRow(Mat2,1)),
ResSize = ResRowsNum*ResColsNum,
[spawn(matrix_server, cross, [self(), Mat1, Mat2, RowToMult, ColToMult]) ||
RowToMult <-lists:seq(1, ResRowsNum) , ColToMult <-lists:seq(1, ResColsNum)],
ResMat = matrix:getZeroMat(ResRowsNum, ResColsNum),
Pid ! {MsgRef,mult_loop(ResSize, ResMat)}.
mult_loop(Countdown, ResMat) ->
case Countdown of
0 -> ResMat;
_ -> receive
{Row, Col, Res} ->
mult_loop(Countdown-1, matrix:setElementMat(Row, Col, ResMat, Res))
end
end.
cross(Client, Mat1, Mat2, Row, Col)->
RowList = tuple_to_list(matrix:getRow(Mat1, Row)),
ColList = tuple_to_list(matrix:getCol(Mat2, Col)),
Res = vectorProduct(RowList, ColList),
Client ! {Row, Col, Res}.
vectorProduct(RowList,ColList) -> vectorProduct(RowList,ColList,0).
vectorProduct([H1|T1],[H2|T2],Res) -> vectorProduct(T1,T2,Res+H1*H2);
vectorProduct([],[],Res) -> Res.