multi.cpp 4.05 KB
Newer Older
1
2
3
4
5
6
/**
* @file multi.cpp
* @date 2020-05-14
* @version 1.0
*/

7
8
#include "Matrix.hpp"

9
// Value to cut the matrices
10
11
12
13
14
15
16
int cut = 64;

Matrix mult_std(Matrix a, Matrix b) {
    Matrix c(a.dim);
    for (int i = 0; i < a.dim; i++)
        for (int k = 0; k < a.dim; k++)
            for (int j = 0; j < a.dim; j++)
17
                c(i,j) = (c(i,j) + (a(i,k) * b(k,j))) % 2;
18
19
20
21
22
23
24
25
26
27
28

    return c;
}

Matrix get_part(int pi, int pj, Matrix m) {
    Matrix p(m.dim / 2);
    pi = pi * p.dim;
    pj = pj * p.dim;

    for (int i = 0; i < p.dim; i++)
        for (int j = 0; j < p.dim; j++)
29
            p(i,j) = m(i + pi,j + pj) % 2;
30
31
32
33
34
35
36
37
38
39

    return p;
}

void set_part(int pi, int pj, Matrix* m, Matrix p) {
    pi = pi * p.dim;
    pj = pj * p.dim;

    for (int i = 0; i < p.dim; i++)
        for (int j = 0; j < p.dim; j++)
40
            (*m)(i + pi,j + pj) = p(i,j) % 2;
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
}

Matrix mult_strassen(Matrix a, Matrix b) {
    if (a.dim <= cut)
        return mult_std(a, b);

    Matrix a11 = get_part(0, 0, a);
    Matrix a12 = get_part(0, 1, a);
    Matrix a21 = get_part(1, 0, a);
    Matrix a22 = get_part(1, 1, a);

    Matrix b11 = get_part(0, 0, b);
    Matrix b12 = get_part(0, 1, b);
    Matrix b21 = get_part(1, 0, b);
    Matrix b22 = get_part(1, 1, b);

    Matrix m1 = mult_strassen(a11 + a22, b11 + b22);
    Matrix m2 = mult_strassen(a21 + a22, b11);
    Matrix m3 = mult_strassen(a11, b12 - b22);
    Matrix m4 = mult_strassen(a22, b21 - b11);
    Matrix m5 = mult_strassen(a11 + a12, b22);
    Matrix m6 = mult_strassen(a21 - a11, b11 + b12);
    Matrix m7 = mult_strassen(a12 - a22, b21 + b22);

    Matrix c(a.dim);
    set_part(0, 0, &c, m1 + m4 - m5 + m7);
    set_part(0, 1, &c, m3 + m5);
    set_part(1, 0, &c, m2 + m4);
    set_part(1, 1, &c, m1 - m2 + m3 + m6);

    return c;
}

Matrix run(Matrix (*f)(Matrix, Matrix), Matrix a, Matrix b) {
    Matrix c(a.dim);
    if(a.dim != b.dim) {
77
        cout << "ERROR: Dimensions of Matrices do not match!" << endl;
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
        return c;
    }
    c = f(a, b);
    return c;
}

int main(){
    Cgicc formData;

    htmlHeader("multi.cgi");
    cout << "<body>\n";
    cout << "<div class=\"container\">" << endl;

    string matrixs1 = "";
    string matrixs2 = "";
Mario Bajer's avatar
Mario Bajer committed
93
    string matrixs3 = "";
94
    int targetID = 0;
95
96
    form_iterator fi1 = formData.getElement("multi1");
    if( !fi1->isEmpty() && fi1 != (*formData).end()) {
97
        matrixs1 = "Json/" + **fi1 + ".json";
98
        cout << "Multiplying " << matrixs1 << " with " << endl;
99
100
101
102
103
104
105
    }
    else {
        cout << "Error on Matrix 1!" << endl;
    }

    form_iterator fi2 = formData.getElement("multi2");
    if( !fi2->isEmpty() && fi2 != (*formData).end()) {
106
        matrixs2 = "Json/" + **fi2 + ".json";
107
        cout << matrixs2 << " and storing result in " << endl;
108
109
110
111
112
    }
    else {
        cout << "Error on Matrix 2!" << endl;
    }

Mario Bajer's avatar
Mario Bajer committed
113
114
    form_iterator fi3 = formData.getElement("multi3");
    if( !fi3->isEmpty() && fi3 != (*formData).end()) {
115
116
        targetID = stoi(**fi3);
        matrixs3 = "Json/" + **fi3 + ".json";
Mario Bajer's avatar
Mario Bajer committed
117
118
119
120
121
122
        cout << matrixs3 << endl;
    }
    else {
        cout << "Error on Matrix 3 (result)!" << endl;
    }

123
124
    json json1;
    json json2;
Mario Bajer's avatar
Mario Bajer committed
125
    json json3;
126
127
128
129
130
    ifstream in1(matrixs1);
    ifstream in2(matrixs2);
    in1 >> json1;
    in2 >> json2;
    Matrix matrix1(2);
131
    const vector<int>& v1 = json1["matrix"];
132
133
    matrix1.ID = json1["id"];
    matrix1.dim = json1["dimension"];
134
    matrix1.data = const_cast<int *>(&v1[0]);
135
    Matrix matrix2(2);
136
137
138
139
    const vector<int>& v2 = json1["matrix"];
    matrix2.ID = json2["id"];
    matrix2.dim = json2["dimension"];
    matrix2.data = const_cast<int *>(&v2[0]);
140
141
142
143

    Matrix result(matrix1.dim);
    result = run(mult_strassen, matrix1, matrix2);

Mario Bajer's avatar
Mario Bajer committed
144
145
    int size = result.dim * result.dim;
    vector<int> v(result.data, result.data + size);
146
147
    json3["id"] = targetID;
    json3["dimension"] = result.dim;
Mario Bajer's avatar
Mario Bajer committed
148
    json3["matrix"] = v;
149
150
151
152
    ofstream o;
    o.open(matrixs3);
    o << json3 << endl;
    o.close();
Mario Bajer's avatar
Mario Bajer committed
153

154
    cout << "</div>" << endl;
Mario Bajer's avatar
Mario Bajer committed
155
    cout << "<a href=\"http://localhost:80/index.html\">Back to Index</a>";
156
157
158
159
    cout << "</body>\n";
    cout << "</html>\n";
    return 0;
}