78std::vector<std::vector<T>>
operator*(std::vector<std::vector<T>>
const &A,
79 std::vector<std::vector<T>>
const &B) {
81 size_t N_A = A.size();
83 size_t N_B = B[0].size();
85 std::vector<std::vector<T>> result(N_A);
87 if (A[0].size() != B.size()) {
88 std::cerr <<
"Number of columns in A != Number of rows in B ("
89 << A[0].size() <<
", " << B.size() <<
")" << std::endl;
93 for (
size_t row = 0; row < N_A; row++) {
94 std::vector<T> v(N_B);
95 for (
size_t col = 0; col < N_B; col++) {
96 v[col] =
static_cast<T
>(0);
97 for (
size_t j = 0; j < B.size(); j++) {
98 v[col] += A[row][j] * B[j][col];
227 std::vector<std::vector<T>>
const &A) {
231 std::vector<std::vector<float>> inverse(N);
232 for (
size_t row = 0; row < N; row++) {
234 inverse[row] = std::vector<float>(N);
235 for (
size_t col = 0; col < N; col++) {
236 inverse[row][col] = (row == col) ? 1.f : 0.f;
241 std::cerr <<
"A must be a square matrix!" << std::endl;
246 std::vector<std::vector<float>> temp(N);
247 for (
size_t row = 0; row < N; row++) {
248 std::vector<float> v(N);
249 for (
size_t col = 0; col < N; col++) {
250 v[col] =
static_cast<float>(A[row][col]);
256 for (
size_t row = 0; row < N; row++) {
257 for (
size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) {
259 temp[row] = temp[row] + temp[row2];
260 inverse[row] = inverse[row] + inverse[row2];
263 for (
size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) {
265 for (
size_t row2 = 0; row2 < N; row2++) {
266 temp[row2][row] = temp[row2][row] + temp[row2][col2];
267 inverse[row2][row] = inverse[row2][row] + inverse[row2][col2];
271 if (temp[row][row] == 0) {
273 std::cerr <<
"Low-rank matrix, no inverse!" << std::endl;
278 auto divisor =
static_cast<float>(temp[row][row]);
279 temp[row] = temp[row] / divisor;
280 inverse[row] = inverse[row] / divisor;
282 for (
size_t row2 = 0; row2 < N; row2++) {
286 float factor = temp[row2][row];
287 temp[row2] = temp[row2] - factor * temp[row];
288 inverse[row2] = inverse[row2] - factor * inverse[row];
373 std::cout <<
"Test 1 (quadratic function)....";
375 std::vector<std::vector<float>> data1(
376 {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}});
378 std::vector<float> Y1({20, -4, -5, -4, 31});
382 std::vector<std::vector<float>> test_data1(
383 {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}});
385 std::vector<float> expected1({-1, -1, 95, 95});
389 for (
size_t rows = 0; rows < out1.size(); rows++) {
390 assert(std::abs(out1[rows] - expected1[rows]) < 0.01);
392 std::cout <<
"passed\n";
395 std::cout <<
"Test 2 (cubic function)....";
397 std::vector<std::vector<float>> data2(
398 {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}});
400 std::vector<float> Y2({-200, -100, -100, 98, 152});
404 std::vector<std::vector<float>> test_data2(
405 {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}});
407 std::vector<float> expected2({-104, -88, -1000, 1000});
411 for (
size_t rows = 0; rows < out2.size(); rows++) {
412 assert(std::abs(out2[rows] - expected2[rows]) < 0.01);
414 std::cout <<
"passed\n";
416 std::cout << std::endl;
428 std::cout <<
"Enter number of features: ";
431 std::cout <<
"Enter number of samples: ";
435 std::vector<std::vector<float>>
data(N);
436 std::vector<float> Y(N);
439 <<
"Enter training data. Per sample, provide features and one output."
442 for (
size_t rows = 0; rows < N; rows++) {
443 std::vector<float> v(F);
444 std::cout <<
"Sample# " << rows + 1 <<
": ";
445 for (
size_t cols = 0; cols < F; cols++) {
455 std::cout << std::endl << std::endl <<
"beta:" << beta << std::endl;
458 std::cout <<
"Enter number of test samples: ";
461 std::vector<std::vector<float>> data2(T);
464 for (
size_t rows = 0; rows < T; rows++) {
465 std::cout <<
"Sample# " << rows + 1 <<
": ";
466 std::vector<float> v(F);
467 for (
size_t cols = 0; cols < F; cols++) std::cin >> v[cols];
472 for (
size_t rows = 0; rows < T; rows++) std::cout << out[rows] << std::endl;