Blame view

stim/math/matrix.h 13.5 KB
a19e3c80   David Mayerich   matrix edits for ...
1
2
  #ifndef STIM_MATRIX_H

  #define STIM_MATRIX_H

57729e5b   David Mayerich   changed directory...
3
4
5
6
  

  //#include "rts/vector.h"

  #include <string.h>

  #include <iostream>

91589064   David Mayerich   added a global ma...
7
  #include <fstream>

cce7daf9   Pavel Govyadinov   added glObj.h to ...
8
  #include <stim/math/vector.h>

308a743c   David Mayerich   fixed class compa...
9
  #include <stim/math/vec3.h>

1c92dffe   David Mayerich   simplified CUDA i...
10
  //#include <stim/cuda/cudatools/callable.h>

57729e5b   David Mayerich   changed directory...
11
  

8a86bd56   David Mayerich   changed rts names...
12
  namespace stim{

57729e5b   David Mayerich   changed directory...
13
  

7d01bb90   David Mayerich   matlab matrix sav...
14
15
16
17
18
19
20
21
22
23
  	enum mat4Format {

  		mat4_float64,

  		mat4_float32,

  		mat4_int32,

  		mat4_int16,

  		mat4_uint16,

  		mat4_uint8,

  		mat4_float						//floating point type, determined automatically

  	};

  

a11c7efe   David Mayerich   fixed stim::filen...
24
  	static size_t mat4Format_size(mat4Format f){

7d01bb90   David Mayerich   matlab matrix sav...
25
26
27
28
29
30
31
32
33
34
  		switch(f){

  			case mat4_float64: return 8;

  			case mat4_float32:

  			case mat4_int32:   return 4;

  			case mat4_int16:

  			case mat4_uint16:  return 2;

  			case mat4_uint8:   return 1;

  			default:           return 0;

  		}

  	}

91589064   David Mayerich   added a global ma...
35
  

f4069d3f   David Mayerich   fixed the crop fu...
36
37
38
39
40
41
42
  	//class encapsulates a mat4 file, and can be used to write multiple matrices to a single mat4 file

  	class mat4file {

  		std::ofstream matfile;

  

  	public:

  		/// Constructor opens a mat4 file for writing

  		mat4file(std::string filename) {

7f1ab3c2   Pavel Govyadinov   fixed problems wi...
43
  			matfile.open(filename.c_str(), std::ios::binary);

f4069d3f   David Mayerich   fixed the crop fu...
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
  		}

  

  		bool is_open() {

  			return matfile.is_open();

  		}

  

  		void close() {

  			matfile.close();

  		}

  

  		bool writemat(char* data, std::string varname, size_t sx, size_t sy, mat4Format format) {

  			//save the matrix file here (use the mat4 function above)

  			//data format: https://maxwell.ict.griffith.edu.au/spl/matlab-page/matfile_format.pdf (page 32)

  

  			int MOPT = 0;									//initialize the MOPT type value to zero

  			int m = 0;										//little endian

  			int o = 0;										//reserved, always 0

  			int p = format;

  			int t = 0;

  			MOPT = m * 1000 + o * 100 + p * 10 + t;			//calculate the type value

  			int mrows = (int)sx;

  			int ncols = (int)sy;

  			int imagf = 0;									//assume real (for now)

  			varname.push_back('\0');									//add a null to the string

  			int namlen = (int)varname.size();						//calculate the name size

  

  			size_t bytes = sx * sy * mat4Format_size(format);

  			matfile.write((char*)&MOPT, 4);

  			matfile.write((char*)&mrows, 4);

  			matfile.write((char*)&ncols, 4);

  			matfile.write((char*)&imagf, 4);

  			matfile.write((char*)&namlen, 4);

  			matfile.write((char*)&varname[0], namlen);

  			matfile.write((char*)data, bytes);				//write the matrix data

  			return is_open();

  		}

  	};

  

a11c7efe   David Mayerich   fixed stim::filen...
82
  	static void save_mat4(char* data, std::string filename, std::string varname, size_t sx, size_t sy, mat4Format format){

f4069d3f   David Mayerich   fixed the crop fu...
83
84
85
86
87
  		mat4file outfile(filename);									//create a mat4 file object

  		if (outfile.is_open()) {									//if the file is open

  			outfile.writemat(data, varname, sx, sy, format);		//write the matrix

  			outfile.close();										//close the file

  		}		

91589064   David Mayerich   added a global ma...
88
89
  	}

  

6c4afcac   David Mayerich   introduced a gene...
90
91
  template <class T>

  class matrix {

57729e5b   David Mayerich   changed directory...
92
  	//the matrix will be stored in column-major order (compatible with OpenGL)

6c4afcac   David Mayerich   introduced a gene...
93
94
95
96
  	T* M;								//pointer to the matrix data

  	size_t R;							//number of rows

  	size_t C;							//number of colums

  

7d01bb90   David Mayerich   matlab matrix sav...
97
98
99
  	size_t bytes() {

  		return R * C * sizeof(T);		//return the number of bytes of matrix data

  	}

65c1aac0   David Mayerich   fixed memory leak...
100
  	/*void init(size_t rows, size_t cols){

6c4afcac   David Mayerich   introduced a gene...
101
102
  		R = rows;

  		C = cols;

65c1aac0   David Mayerich   fixed memory leak...
103
104
105
106
107
108
109
110
111
112
113
  		if (R == 0 || C == 0) M = NULL;

  		else

  			M = (T*)malloc(R * C * sizeof(T));	//allocate space for the matrix

  	}*/

  

  	T get(const size_t row, const size_t col) const {

  		if (row >= R || col >= C) {

  			std::cout << "ERROR: row or column out of range." << std::endl;

  			exit(1);

  		}

  		return M[col * R + row];

6c4afcac   David Mayerich   introduced a gene...
114
  	}

57729e5b   David Mayerich   changed directory...
115
  

6c4afcac   David Mayerich   introduced a gene...
116
  	T& at(size_t row, size_t col){

65c1aac0   David Mayerich   fixed memory leak...
117
118
119
120
  		if (row >= R || col >= C) {

  			std::cout << "ERROR: row or column out of range." << std::endl;

  			exit(1);

  		}

6c4afcac   David Mayerich   introduced a gene...
121
  		return M[col * R + row];

57729e5b   David Mayerich   changed directory...
122
123
  	}

  

6c4afcac   David Mayerich   introduced a gene...
124
  public:

65c1aac0   David Mayerich   fixed memory leak...
125
126
127
128
129
130
  	matrix() {

  		R = 0;

  		C = 0;

  		M = NULL;

  	}

  

6c4afcac   David Mayerich   introduced a gene...
131
  	matrix(size_t rows, size_t cols) {

65c1aac0   David Mayerich   fixed memory leak...
132
133
  		R = rows;

  		C = cols;

ef1f6218   David Mayerich   fixed some memory...
134
135
136
  		M = NULL;

  		if (R * C > 0) 

  			M = (T*) malloc(R * C * sizeof(T));

b2d10ff1   Pavel Govyadinov   final edits, expa...
137
138
  	}

  

ef1f6218   David Mayerich   fixed some memory...
139
  	matrix(size_t rows, size_t cols, const T* data) {

65c1aac0   David Mayerich   fixed memory leak...
140
141
  		R = rows;

  		C = cols;

ef1f6218   David Mayerich   fixed some memory...
142
143
144
  		M = NULL;

  		if (R * C > 0)

  			M = (T*)malloc(R * C * sizeof(T));

dd5aab2f   David Mayerich   fixed errors in s...
145
  		memcpy(M, data, R * C * sizeof(T));

8e56a0a7   Pavel Govyadinov   Added the propose...
146
  	}

b2d10ff1   Pavel Govyadinov   final edits, expa...
147
  

6c4afcac   David Mayerich   introduced a gene...
148
  	matrix(const matrix<T>& cpy){

ef1f6218   David Mayerich   fixed some memory...
149
150
151
  		M = NULL;

  		if (cpy.R * cpy.C > 0)

  			M = (T*)malloc(cpy.R * cpy.C * sizeof(T));

65c1aac0   David Mayerich   fixed memory leak...
152
153
154
155
  		memcpy(M, cpy.M, cpy.R * cpy.C * sizeof(T));

  

  		R = cpy.R;

  		C = cpy.C;

6c4afcac   David Mayerich   introduced a gene...
156
  	}

19a3973b   David Mayerich   updates to matrix...
157
  

6c4afcac   David Mayerich   introduced a gene...
158
  	~matrix() {

6c4afcac   David Mayerich   introduced a gene...
159
  		if(M) free(M);

65c1aac0   David Mayerich   fixed memory leak...
160
161
  		M = NULL;

  		R = C = 0;

19a3973b   David Mayerich   updates to matrix...
162
163
  	}

  

65c1aac0   David Mayerich   fixed memory leak...
164
  	size_t rows() const {

6c4afcac   David Mayerich   introduced a gene...
165
  		return R;

57729e5b   David Mayerich   changed directory...
166
167
  	}

  

65c1aac0   David Mayerich   fixed memory leak...
168
  	size_t cols() const {

6c4afcac   David Mayerich   introduced a gene...
169
170
  		return C;

  	}

57729e5b   David Mayerich   changed directory...
171
  

1c92dffe   David Mayerich   simplified CUDA i...
172
  	T& operator()(size_t row, size_t col) {

6c4afcac   David Mayerich   introduced a gene...
173
174
175
  		return at(row, col);

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
176
177
  	matrix<T>& operator=(const T rhs) {

  		//init(R, C);

6c4afcac   David Mayerich   introduced a gene...
178
179
180
181
182
183
184
  		size_t N = R * C;

  		for(size_t n=0; n<N; n++)

  			M[n] = rhs;

  

  		return *this;

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
185
186
187
188
189
190
191
192
193
194
  	matrix<T>& operator=(const matrix<T>& rhs){

  		if (this != &rhs) {											//if the matrix isn't self-assigned

  			T* new_matrix = new T[rhs.R * rhs.C];					//allocate new resources

  			memcpy(new_matrix, rhs.M, rhs.R * rhs.C * sizeof(T));	//copy the matrix

  

  			delete[] M;												//delete the previous array

  			M = new_matrix;

  			R = rhs.R;

  			C = rhs.C;

  		}

57729e5b   David Mayerich   changed directory...
195
196
  		return *this;

  	}

42bb075c   Jiaming Guo   last changes for ...
197
  	

6c4afcac   David Mayerich   introduced a gene...
198
  	//element-wise operations

65c1aac0   David Mayerich   fixed memory leak...
199
  	matrix<T> operator+(const T rhs) const {

6c4afcac   David Mayerich   introduced a gene...
200
201
202
  		matrix<T> result(R, C);					//create a result matrix

  		size_t N = R * C;

  

42bb075c   Jiaming Guo   last changes for ...
203
  		for(int i=0; i<N; i++)

6c4afcac   David Mayerich   introduced a gene...
204
205
206
  			result.M[i] = M[i] + rhs;			//calculate the operation and assign to result

  

  		return result;

42bb075c   Jiaming Guo   last changes for ...
207
  	}

57729e5b   David Mayerich   changed directory...
208
  

65c1aac0   David Mayerich   fixed memory leak...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
  	matrix<T> operator+(const matrix<T> rhs) const {

  		if (R != rhs.R || C != rhs.C) {

  			std::cout << "ERROR: addition is only defined for matrices that are the same size." << std::endl;

  			exit(1);

  		}

  		matrix<T> result(R, C);					//create a result matrix

  		size_t N = R * C;

  

  		for (int i = 0; i < N; i++)

  			result.M[i] = M[i] + rhs.M[i];			//calculate the operation and assign to result

  

  		return result;

  	}

  

  	matrix<T> operator-(const T rhs) const {

6c4afcac   David Mayerich   introduced a gene...
224
225
226
  		return operator+(-rhs);					//add the negative of rhs

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  	matrix<T> operator-(const matrix<T> rhs) const {

  		return operator+(-rhs);

  	}

  

  	matrix<T> operator-() const {

  		matrix<T> result(R, C);					//create a result matrix

  		size_t N = R * C;

  

  		for (int i = 0; i < N; i++)

  			result.M[i] = -M[i];			//calculate the operation and assign to result

  

  		return result;

  	}

  

  	matrix<T> operator*(const T rhs) const {

6c4afcac   David Mayerich   introduced a gene...
242
243
244
245
246
247
248
249
250
  		matrix<T> result(R, C);					//create a result matrix

  		size_t N = R * C;

  

  		for(int i=0; i<N; i++)

  			result.M[i] = M[i] * rhs;			//calculate the operation and assign to result

  

  		return result;

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
251
  	matrix<T> operator/(const T rhs) const {

6c4afcac   David Mayerich   introduced a gene...
252
253
254
255
256
  		matrix<T> result(R, C);					//create a result matrix

  		size_t N = R * C;

  

  		for(int i=0; i<N; i++)

  			result.M[i] = M[i] / rhs;			//calculate the operation and assign to result

487a9b49   David Mayerich   added the ability...
257
  

6c4afcac   David Mayerich   introduced a gene...
258
259
  		return result;

  	}

57729e5b   David Mayerich   changed directory...
260
  

6c4afcac   David Mayerich   introduced a gene...
261
  	//matrix multiplication

65c1aac0   David Mayerich   fixed memory leak...
262
  	matrix<T> operator*(const matrix<T> rhs) const {

6c4afcac   David Mayerich   introduced a gene...
263
264
265
266
267
  		if(C != rhs.R){

  			std::cout<<"ERROR: matrix multiplication is undefined for matrices of size ";

  			std::cout<<"[ "<<R<<" x "<<C<<" ] and [ "<<rhs.R<<" x "<<rhs.C<<"]"<<std::endl;

  			exit(1);

  		}

57729e5b   David Mayerich   changed directory...
268
  

6c4afcac   David Mayerich   introduced a gene...
269
270
  		matrix<T> result(R, rhs.C);				//create the output matrix

  		T inner;								//stores the running inner product

1c92dffe   David Mayerich   simplified CUDA i...
271
272
273
  		size_t c, r, i;

  		for(c = 0; c < rhs.C; c++){

  			for(r = 0; r < R; r++){

6c4afcac   David Mayerich   introduced a gene...
274
  				inner = (T)0;

1c92dffe   David Mayerich   simplified CUDA i...
275
  				for(i = 0; i < C; i++){

65c1aac0   David Mayerich   fixed memory leak...
276
  					inner += get(r, i) * rhs.get(i, c);

6c4afcac   David Mayerich   introduced a gene...
277
278
279
280
  				}

  				result.M[c * R + r] = inner;

  			}

  		}

57729e5b   David Mayerich   changed directory...
281
282
283
  		return result;

  	}

  

6c4afcac   David Mayerich   introduced a gene...
284
285
286
287
  	//returns a pointer to the raw matrix data (in column major format)

  	T* data(){

  		return M;

  	}

8e4f8364   David Mayerich   started a new opt...
288
  

6c4afcac   David Mayerich   introduced a gene...
289
  	//return a transposed matrix

65c1aac0   David Mayerich   fixed memory leak...
290
  	matrix<T> transpose() const {

6c4afcac   David Mayerich   introduced a gene...
291
292
293
294
295
296
297
  		matrix<T> result(C, R);

  		size_t c, r;

  		for(c = 0; c < C; c++){

  			for(r = 0; r < R; r++){

  				result.M[r * C + c] = M[c * R + r];

  			}

  		}

8e4f8364   David Mayerich   started a new opt...
298
299
300
  		return result;

  	}

  

ef1f6218   David Mayerich   fixed some memory...
301
302
303
304
305
306
  	// Reshapes the matrix in place

  	void reshape(size_t rows, size_t cols) {

  		R = rows;

  		C = cols;

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
307
308
309
310
311
312
313
314
315
316
317
  	///Calculate and return the determinant of the matrix

  	T det() const {

  		if (R != C) {

  			std::cout << "ERROR: a determinant can only be calculated for a square matrix." << std::endl;

  			exit(1);

  		}

  		if (R == 1) return M[0];			//if the matrix only contains one value, return it

  

  		int r, c, ri, cia, cib;

  		T a = 0;

  		T b = 0;

f7cf19e4   David Mayerich   fixed warnings, t...
318
  		for (c = 0; c < (int)C; c++) {

65c1aac0   David Mayerich   fixed memory leak...
319
320
  			for (r = 0; r < R; r++) {

  				ri = r;

f7cf19e4   David Mayerich   fixed warnings, t...
321
322
  				cia = (r + c) % (int)C;

  				cib = ((int)C - 1 - r) % (int)C;

65c1aac0   David Mayerich   fixed memory leak...
323
324
325
326
327
328
329
  				a += get(ri, cia);

  				b += get(ri, cib);

  			}

  		}

  		return a - b;

  	}

  

d299c720   David Mayerich   added row and col...
330
331
332
333
334
335
336
337
  	/// Sum all elements in the matrix

  	T sum() const {

  		size_t N = R * C;								//calculate the number of elements in the matrix

  		T s = (T)0;										//allocate a register to store the sum

  		for (size_t n = 0; n < N; n++) s += M[n];		//perform the summation

  		return s;

  	}

  

1c92dffe   David Mayerich   simplified CUDA i...
338
  	/// Sort rows of the matrix by the specified indices

65c1aac0   David Mayerich   fixed memory leak...
339
  	matrix<T> sort_rows(size_t* idx) const {

1c92dffe   David Mayerich   simplified CUDA i...
340
341
342
343
344
345
346
347
348
349
350
  		matrix<T> result(C, R);					//create the output matrix

  		size_t r, c;

  		for (c = 0; c < C; c++) {								//for each column

  			for (r = 0; r < R; r++) {							//for each row element

  				result.M[c * R + r] = M[c * R + idx[r]];		//copy each element of the row into its new position

  			}

  		}

  		return result;

  	}

  

  	/// Sort columns of the matrix by the specified indices

7d01bb90   David Mayerich   matlab matrix sav...
351
  	matrix<T> sort_cols(size_t* idx, size_t data_type = mat4_float) const {

1c92dffe   David Mayerich   simplified CUDA i...
352
353
354
355
356
357
358
359
  		matrix<T> result(C, R);

  		size_t c;

  		for (c = 0; c < C; c++) {											//for each column

  			memcpy(&result.M[c * R], &M[idx[c] * R], sizeof(T) * R);		//copy the entire column from this matrix to the appropriate location

  		}

  		return result;

  	}

  

d299c720   David Mayerich   added row and col...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  	/// Return the column specified by index i

  	matrix<T> col(size_t i) {

  		matrix<T> c(R, 1);										//create a single column matrix

  		memcpy(c.data(), &data()[R*i], C * sizeof(T));				//copy the column

  		return c;

  	}

  

  	/// Return the row specified by index i

  	matrix<T> row(size_t i) {

  		matrix<T> r(1, C);										//create a single row matrix

  		for (size_t c = 0; c < C; c++)

  			r(0, c) = at(i, c);

  		return r;

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
375
  	std::string toStr() const {

57729e5b   David Mayerich   changed directory...
376
377
  		std::stringstream ss;

  

1c92dffe   David Mayerich   simplified CUDA i...
378
  		for(int r = 0; r < R; r++) {

b2d10ff1   Pavel Govyadinov   final edits, expa...
379
  			ss << "| ";

1c92dffe   David Mayerich   simplified CUDA i...
380
  			for(int c=0; c<C; c++) {

6c4afcac   David Mayerich   introduced a gene...
381
  				ss << M[c * R + r] << " ";

57729e5b   David Mayerich   changed directory...
382
  			}

b2d10ff1   Pavel Govyadinov   final edits, expa...
383
  			ss << "|" << std::endl;

57729e5b   David Mayerich   changed directory...
384
  		}

57729e5b   David Mayerich   changed directory...
385
386
  		return ss.str();

  	}

19a3973b   David Mayerich   updates to matrix...
387
  

65c1aac0   David Mayerich   fixed memory leak...
388
389
  	void csv(std::ostream& out) const {

  		//std::stringstream csvss;

c495d065   David Mayerich   Fixed stim::matri...
390
  		for (size_t i = 0; i < R; i++) {

65c1aac0   David Mayerich   fixed memory leak...
391
392
393
394
  			out << std::fixed << M[i];

  			for (size_t j = 1; j < C; j++)

  				out << ", " << std::fixed << M[j * R + i];

  			out << std::endl;

1c92dffe   David Mayerich   simplified CUDA i...
395
  		}

65c1aac0   David Mayerich   fixed memory leak...
396
397
398
399
400
401
402
403
  		//return csvss.str();

  	}

  

  	std::string csv() const {

  		std::stringstream csvss;

  		int digits = std::numeric_limits<double>::max_digits10;

  		csvss.precision(digits);

  		csv(csvss);

1c92dffe   David Mayerich   simplified CUDA i...
404
405
406
  		return csvss.str();

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
407
408
  

  

1c92dffe   David Mayerich   simplified CUDA i...
409
  	//save the data as a CSV file

65c1aac0   David Mayerich   fixed memory leak...
410
  	void csv(std::string filename) const {

792a5d63   Jiaming Guo   fix minor bugs
411
  		std::ofstream basisfile(filename.c_str());

1c92dffe   David Mayerich   simplified CUDA i...
412
413
414
415
  		basisfile << csv();

  		basisfile.close();

  	}

  

dd5aab2f   David Mayerich   fixed errors in s...
416
  	static matrix<T> I(size_t N) {

dd5aab2f   David Mayerich   fixed errors in s...
417
418
419
420
421
422
423
424
  		matrix<T> result(N, N);							//create the identity matrix

  		memset(result.M, 0, N * N * sizeof(T));			//set the entire matrix to zero

  		for (size_t n = 0; n < N; n++) {

  			result(n, n) = (T)1;						//set the diagonal component to 1

  		}

  		return result;

  	}

  

65c1aac0   David Mayerich   fixed memory leak...
425
426
427
428
429
430
431
432
433
434
435
436
437
  	//loads a matrix from a stream in CSV format

  	void csv(std::istream& in) {

  		size_t c, r;

  		T v;

  		for (r = 0; r < R; r++) {

  			for (c = 0; c < C; c++) {

  				in >> v;

  				if (in.peek() == ',') in.seekg(1, std::ios::cur);

  				at(r, c) = v;;

  			}

  		}

  	}

  

d64fa68d   David Mayerich   implemented raw s...
438
  	void raw(std::string filename) {

792a5d63   Jiaming Guo   fix minor bugs
439
  		std::ofstream out(filename, std::ios::binary);

d64fa68d   David Mayerich   implemented raw s...
440
441
442
443
444
445
  		if (out) {

  			out.write((char*)data(), rows() * cols() * sizeof(T));

  			out.close();

  		}

  	}

  

f4069d3f   David Mayerich   fixed the crop fu...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  	void mat4(stim::mat4file& file, std::string name = std::string("unknown"), mat4Format format = mat4_float) {

  		//make sure the matrix name is valid (only numbers and letters, with a letter at the beginning

  		for (size_t c = 0; c < name.size(); c++) {

  			if (name[c] < 48 ||												//if the character isn't a number or letter, replace it with '_'

  				(name[c] > 57 && name[c] < 65) ||

  				(name[c] > 90 && name[c] < 97) ||

  				(name[c] > 122)) {

  				name[c] = '_';

  			}

  		}

  		if (name[0] < 65 ||

  			(name[0] > 91 && name[0] < 97) ||

  			name[0] > 122) {

  			name = std::string("m") + name;

  		}

91589064   David Mayerich   added a global ma...
461
462
463
464
465
466
467
468
  		if (format == mat4_float) {

  			if (sizeof(T) == 4) format = mat4_float32;

  			else if (sizeof(T) == 8) format = mat4_float64;

  			else {

  				std::cout << "stim::matrix ERROR - incorrect format specified" << std::endl;

  				exit(1);

  			}

  		}

f4069d3f   David Mayerich   fixed the crop fu...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  		//the name is now valid

  

  		//if the size of the array is more than 100,000,000 elements, the matrix isn't supported

  		if (rows() * cols() > 100000000) {											//break the matrix up into multiple parts

  			//mat4file out(filename);													//create a mat4 object to write the matrix

  			if (file.is_open()) {

  				if (rows() < 100000000) {												//if the size of the row is less than 100,000,000, split the matrix up by columns

  					size_t ncols = 100000000 / rows();									//calculate the number of columns that can fit in one matrix

  					size_t nmat = (size_t)std::ceil((double)cols() / (double)ncols);			//calculate the number of matrices required

  					for (size_t m = 0; m < nmat; m++) {									//for each matrix

  						std::stringstream ss;

  						ss << name << "_part_" << m + 1;

  						if (m == nmat - 1)

  							file.writemat((char*)(data() + m * ncols * rows()), ss.str(), rows(), cols() - m * ncols, format);

  						else

  							file.writemat((char*)(data() + m * ncols * rows()), ss.str(), rows(), ncols, format);

  					}

  				}

  			}

  		}

  		//call the mat4 subroutine

  		else

  			//stim::save_mat4((char*)M, filename, name, rows(), cols(), format);

  			file.writemat((char*)data(), name, rows(), cols(), format);

  	}

  

  	// saves the matrix as a Level-4 MATLAB file

  	void mat4(std::string filename, std::string name = std::string("unknown"), mat4Format format = mat4_float) {

  		stim::mat4file matfile(filename);

  

  		if (matfile.is_open()) {

  			mat4(matfile, name, format);

  			matfile.close();

  		}

7d01bb90   David Mayerich   matlab matrix sav...
503
  	}

57729e5b   David Mayerich   changed directory...
504
505
  };

  

57729e5b   David Mayerich   changed directory...
506
507
  }	//end namespace rts

  

57729e5b   David Mayerich   changed directory...
508
509
  

  #endif