2 //////////////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation. //
7 // This program is distributed in the hope that it will be useful, but //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
10 // General Public License for more details. //
12 // You should have received a copy of the GNU General Public License //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
15 // Written by Francois Fleuret //
16 // (C) Ecole Polytechnique Federale de Lausanne //
17 // Contact <pom@epfl.ch> for comments & bug reports //
18 //////////////////////////////////////////////////////////////////////////////////
35 // [i][j] is faster on i386 CPU than [i + j * width]
39 inline void resize(int w, int h) {
42 width = w; height = h;
43 content = new T[width * height];
44 heads = new T *[width];
45 for(int i = 0; i < width; i++) heads[i] = content + i * height;
48 inline int get_width() const { return width; }
49 inline int get_height() const { return height; }
51 inline Array() : width(0), height(0), content(0), heads(0) { }
53 inline Array(int w, int h) : width(w), height(h) {
54 content = new T[width * height];
55 heads = new T *[width];
56 for(int i = 0; i < width; i++) heads[i] = content + i * height;
59 inline Array(const Array &a) : width(a.width), height(a.height) {
60 content = new T[width * height];
61 heads = new T *[width];
62 for(int i = 0; i < width; i++) heads[i] = content + i * height;
63 memcpy(content, a.content, height * width * sizeof(T));
66 inline ~Array() { delete[] content; delete[] heads; }
68 inline Array &operator = (const Array &a) {
70 if(a.width != width || a.height != height) resize(a.width, a.height);
71 if(width > 0 && height > 0) memcpy(content, a.content, height * width * sizeof(T));
76 inline Array& clear() {
77 memset(content, 0, height * width * sizeof(T));
81 inline T dot(const Array &a) {
82 ASSERT(width == a.width && height == a.height, "Size mismatch in Array::dot");
83 T *u1 = content, *u2 = a.content;
85 for(int i = 0; i < width * height; i++) s += *(u1++) * *(u2++);
89 inline T sum_square() {
92 for(int i = 0; i < width * height; i++) { s += *u * *u; u++; }
99 for(int i = 0; i < width * height; i++) s += *(u++);
103 inline T &operator () (int i, int j) {
104 ASSERT(i >= 0 && i < width && j >= 0 && j < height, "Index out of bounds in Array::operator ()");
108 inline T operator () (int i, int j) const {
109 ASSERT(i >= 0 && i < width && j >= 0 && j < height, "Index out of bounds in Array::operator () const");
113 inline void print(std::ostream &os) const {
114 for(int i = 0; i < width; i++) for(int j = 0; j < height; j++)
115 os << heads[i][j] << ((i < width-1) ? ' ' : '\n');
118 inline void print_for_gnuplot(std::ostream &os) const {
119 for(int i = 0; i < width; i++) {
120 for(int j = 0; j < height; j++)
121 os << i << " " << j << " " << heads[i][j] << "\n";
126 inline T l2distance(const Array<T> &m) {
127 ASSERT(m.width == width && m.height == height, "Array size mismatch");
129 for(int i = 0; i < width * height; i++) r += (m.content[i] - content[i]) * (m.content[i] - content[i]);
135 std::ostream &operator << (std::ostream &os, const Array<T> &v) { v.print(os); return os; }