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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

// Mat_Mul1.cpp - This program inputs two matrices, [A] and [B], from a file and then multiplies them: [A][B] = [C]
// First, the user is prompted to input the sizes of the arrays to be multiplied, M X N, and N X P.
// The arrays are then created. The entries for all three arrays are input from a text file.
// The product array, [C], is output to another text file.
// Written in Visual C++ 2012 Express Edition
// 26 June 2013

#include <iostream>
#include <fstream>
#include <cctype>
#include <cmath>
#include <vector>
#include <float.h>

using namespace std;

typedef vector<vector<double> > C2DArray;

void Matrix_Mult(bool* error_flag, const int mRows, const int nCols, const int pCols, const C2DArray A_Matrix, const C2DArray B_Matrix, C2DArray& C_Matrix) {
    // Routine to compute the product of two matrices: [A][B] = [C]
    // [A] and [B] are inputs, [C] is the product matrix, output.
    // [A] is of size M X N
    // [B] is of size N X P
    // [C] is of size M X P

    int i = A_Matrix.size(), j = A_Matrix[0].size(), k = B_Matrix[0].size();
    double dummy;

    // Do some double-checks to make sure matrix dimensions are actually what was fed in to this sub-routine.
    // If data not consistent, perhaps other problems present too. User should re-check information.
    // Also make sure C matrix is proper size to receive data.

    if ((B_Matrix.size() != j) || (C_Matrix.size() != i) || (C_Matrix[0].size() != k) || (i != mRows) || (j != nCols) || (k != pCols)){
        *error_flag = true;
    }

    if (!(*error_flag)){
        for (k = 0; k < mRows; k++) { // Do each row of A with each column of B
            for (i = 0; i < pCols; i++) {
                dummy = 0.0;
                for (j = 0; j < nCols; j++) {
                    dummy += A_Matrix[k][j]*B_Matrix[j][i];
                } // End for j
               C_Matrix[k][i] = dummy;
           } // End for i
        } // End for k
    }

    return;
} // End Matrix_Mult

int main()
{char rflag = 0; //Readiness flag

cout << " Mat_Mul1 (26 June 2013)\n";
cout << "=========================================================================== \n";
cout << "This program multiplies two matrices, [A] and [B]: [A][B] = [C].\n";
cout << "[A] is M X N, [B] is N X P, and [C] is M X P.\n";
cout << "The dimensions of the [A] and [B] matrices, M, N, and P, should \n";
cout << "have been saved beforehand in a file named mulmatdat.txt.\n";
cout << "mulmatdat should be in the same folder as the Mat_Mul1 executable.\n";
cout << "The next values of mulmatdat should be the entries for matrix [A],\n";
cout << "with data for row 1 first, then row 2, then row 3, etc.\n";
cout << "The entries for the [B] matrix should follow, in the same order.\n";
cout << "\nThe data is assumed to be of type double. Variables used within this program\n";
cout << "are type double.\n";
cout << "\nThe output is written to the file mulmatout.txt.\n";

cout << "\nIs everything ready (are you ready to continue?)? If yes, Enter y. \n";
cout << "Otherwise Enter any other key. \n";
cin >> rflag;

if (toupper(rflag) == 'Y') {
    C2DArray A, B, C; // A, B, and C Matrices
    int i, j, mDim, nDim, pDim; // Array index variables and matrix dimensions
    bool erFlag = false; // Error flag

    ifstream in("mulmatdat.txt", ios::in);

    if (!in) {
        cout << "\nCannot open the input file.\n";
        cout << "\nEnter any key to continue. \n";
        cin >> rflag;
        return 0;
    }

    in >> mDim >> nDim >> pDim; //Input the Matrices' dimensions from the file
    if ((mDim < 1) || (nDim < 1) || (pDim < 1)){
        cout << "\nInvalid dimension entered. Program terminated. \n";
        cout << "\nEnter any key to continue. \n";
        cin >> rflag;
        in.close(); //Close the input file before terminating
        return 0;
    }

    ofstream out("mulmatout.txt", ios::out);
    if (!out) {
        cout << "\nCannot open the output file. Program terminated.\n";
        cout << "\nEnter any key to continue. \n";
        cin >> rflag;
        in.close(); //Close the input file before terminating
        return 0;
    }

    // Beginning of try block, if vector re-sizing unsuccessful
    try {

        // Resize the arrays to the appropriate sizes
        A.resize(mDim); // M rows
        B.resize(nDim); // N rows
        C.resize(mDim); // M rows
        for (i = 0; i < mDim; i++){
            A[i].resize(nDim); // N columns
            C[i].resize(pDim); // P columns
        } // End for i

        for (i = 0; i < nDim; i++){
            B[i].resize(pDim); // P columns
        } // End for i

    } // End of try block

    catch (bad_alloc& xa) { // Catch block, for exceptions

        in.close();
        out.close();
        cerr << "\nIn catch block, so an exception occurred: " << xa.what() << "\n";
        cout << "\nEnter any key to continue. \n";
        cin >> rflag;
        return 0;

    } // End of catch block

    for (i = 0; i < mDim; i++){ //Input the A Matrix from the file
        for (j = 0; j < nDim; j++){
            in >> A[i][j];
        }//End for j
    }//End for i

    for (i = 0; i < nDim; i++){ //Input the B Matrix from the file
        for (j = 0; j < pDim; j++){
            in >> B[i][j];
        }//End for j
    }//End for i

    in.close(); //Close the input file

    Matrix_Mult(&erFlag, mDim, nDim, pDim, A, B, C);

    if (erFlag){
        cout << "Inconsistent data sent to Matrix_Mult routine. Matrix multiplication NOT performed. Check data before running again.\n";
    }
    else {

        out.precision(DBL_DIG);

        out << "\nThe A matrix follows:\n";
        out << "\n";
        for (i = 0; i < mDim; i++){
            for (j = 0; j < nDim; j++){
                out << A[i][j] << " ";
            } // End for j
            out << "\n";
        }//End for i

        out << "\nThe B matrix follows:\n";
        out << "\n";
        for (i = 0; i < nDim; i++){
            for (j = 0; j < pDim; j++){
                out << B[i][j] << " ";
            } // End for j
            out << "\n";
        }//End for i

        out << "\nThe product matrix, C, follows:\n";
        out << "\n";
        for (i = 0; i < mDim; i++){
            for (j = 0; j < pDim; j++){
                out << C[i][j] << " ";
            } // End for j
            out << "\n";
        }//End for i

        cout << "\nDone! The solution is in the text file mulmatout.txt \n";
    } // End else !erFlag
    out.close();
} //End if rflag = 'Y'
else cout << "\nNot ready. Try again when ready with information. \n";
cout << "\nEnter any key to continue. \n";
cin >> rflag;
return 0;
} // End main program.