-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathmatrix.cpp
135 lines (105 loc) · 3.73 KB
/
matrix.cpp
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
// Copyright (c) 2018-2024 Jean-Louis Leroy
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <memory>
#include <string>
#include <typeinfo>
#include <yorel/yomm2/keywords.hpp>
using std::make_shared;
using std::shared_ptr;
using std::string;
struct matrix {
virtual ~matrix() {
}
virtual double at(int row, int col) const = 0;
// ...
};
struct dense_matrix : matrix {
virtual double at(int row, int col) const {
return 0;
}
};
struct diagonal_matrix : matrix {
virtual double at(int row, int col) const {
return 0;
}
};
register_classes(matrix, dense_matrix, diagonal_matrix);
declare_method(string, to_json, (virtual_<const matrix&>));
define_method(string, to_json, (const dense_matrix& m)) {
return "json for dense matrix...";
}
define_method(string, to_json, (const diagonal_matrix& m)) {
return "json for diagonal matrix...";
}
// -----------------------------------------------------------------------------
// matrix * matrix
declare_method(
shared_ptr<const matrix>, times,
(virtual_<const shared_ptr<const matrix>&>,
virtual_<const shared_ptr<const matrix>&>));
// catch-all matrix * matrix -> dense_matrix
define_method(
auto, times,
(const shared_ptr<const matrix>& a, const shared_ptr<const matrix>& b)) {
return make_shared<dense_matrix>();
}
// diagonal_matrix * diagonal_matrix -> diagonal_matrix
define_method(
auto, times,
(const shared_ptr<const diagonal_matrix>& a,
const shared_ptr<const diagonal_matrix>& b)) {
return make_shared<diagonal_matrix>();
}
inline shared_ptr<const matrix>
operator*(shared_ptr<const matrix> a, shared_ptr<const matrix> b) {
return times(a, b);
}
// -----------------------------------------------------------------------------
// scalar * matrix
declare_method(
shared_ptr<const matrix>, times,
(double, virtual_<shared_ptr<const matrix>>));
// catch-all matrix * scalar -> dense_matrix
define_method(auto, times, (double a, shared_ptr<const matrix> b)) {
return make_shared<dense_matrix>();
}
define_method(auto, times, (double a, shared_ptr<const diagonal_matrix> b)) {
return make_shared<diagonal_matrix>();
}
// -----------------------------------------------------------------------------
// matrix * scalar
// just swap
inline shared_ptr<const matrix>
times(const shared_ptr<const matrix>& a, double b) {
return times(b, a);
}
// -----------------------------------------------------------------------------
// main
#define check(expr) \
{ \
if (!(expr)) { \
cerr << #expr << " failed\n"; \
} \
}
int main() {
using std::cerr;
using std::cout;
yorel::yomm2::update();
shared_ptr<const matrix> a = make_shared<dense_matrix>();
shared_ptr<const matrix> b = make_shared<diagonal_matrix>();
double s = 1;
#ifndef _MSC_VER
#pragma clang diagnostic ignored "-Wpotentially-evaluated-expression"
#endif
check(typeid(*times(a, a)) == typeid(dense_matrix));
check(typeid(*times(a, b)) == typeid(dense_matrix));
check(typeid(*times(b, b)) == typeid(diagonal_matrix));
check(typeid(*times(s, a)) == typeid(dense_matrix));
check(typeid(*times(s, b)) == typeid(diagonal_matrix));
cout << to_json(*a) << "\n"; // json for dense matrix
cout << to_json(*b) << "\n"; // json for diagonal matrix
return 0;
}