ryoaro ohara
/
c95_AIchip
AIチップをmbedから駆動するためのプログラムです.
matrix.hpp
- Committer:
- toriten1024
- Date:
- 2019-03-16
- Revision:
- 1:18e8ead6f188
File content as of revision 1:18e8ead6f188:
#include "mbed.h" #include "matrix_const.hpp" #ifndef INCLUDE_MATRIX #define INCLUDE_MATRIX namespace mat { template <typename TYPE> class Matrix { public: TYPE *data; int height;//if height == 0 then dimension y is zero int width;// int channel;// int insert_index;// void assert(int flag){ if(! flag){ printf("error has happend\n\r"); } } /****************************************************************************************** * Calcrate index from x,y,x axis * ***************************************************************************************/ int calc_pos(int x, int y, int d) { int pos = 0; pos += d * (width * height); pos += y * width; pos += x; return pos; } // Constructor Create Matrix Instance void initialize(int width, int height, int channel) { assert(channel > 0 && height > 0 && width > 0); this->channel = channel; this->height = height; this->width = width; this->data = (TYPE *)calloc(width * height * channel, sizeof(TYPE)); this->insert_index = 0; } /****************************************************************************************** * Create 1D Matrix data, like a vector * args * width vector length * ***************************************************************************************/ Matrix(int width) { assert(width > 0); initialize(width, 1, 1); } /****************************************************************************************** * Create 2D Matrix data * args * width : matrix width * height : matrix height * ***************************************************************************************/ Matrix(int width, int height) { assert(width > 0 && height > 0); initialize(width, height, 1); } /****************************************************************************************** * Create 3D Matrix data * args * width : matrix width * height : matrix height * channel : matrix channel, in other word matrix depth * ***************************************************************************************/ Matrix(int width, int height, int channel) { assert(width > 0 && height > 0 && channel > 0); initialize(width, height, channel); } //Copy constructor Matrix(const Matrix &obj) { this->width = obj.width; this->height = obj.height; this->channel = obj.channel; this->insert_index = obj.insert_index; this->data = (TYPE *)calloc(obj.width * obj.height * obj.channel, sizeof(TYPE)); for (int i = 0; i < (obj.width * obj.height * obj.channel); i++) { this->data[i] = obj.data[i]; } } //Copy void operator=(const Matrix<TYPE> &obj) { this->width = obj.width; this->height = obj.height; this->channel = obj.channel; this->insert_index = obj.insert_index; if (this->data != NULL) { free(this->data); } this->data = data = (TYPE *)calloc(obj.width * obj.height * obj.channel, sizeof(TYPE)); for (int i = 0; i < (obj.width * obj.height * obj.channel); i++) { this->data[i] = obj.data[i]; } } //Destructor ~Matrix() { if (this->data != NULL) { free(this->data); this->data = NULL; } } // Reshapes configure aspects /****************************************************************************************** * Convert to 1D Matrix data, like a vector * args * width : vectot lengs * return * reshaped Matrix * ***************************************************************************************/ Matrix<TYPE> reshape(int width) { assert(this->width != 0 && this->height != 0 && this->channel != 0); assertt((this->channel * this->height * this->width) == width); Matrix<TYPE> tmp(width, 1, 1); for (int i = 0; i < this->width * this->height * this->channel; i++) tmp.data[i] = this->data[i]; return tmp; } /****************************************************************************************** * Convert to 2D Matrix data * args * width : matrix width * height : matrix height * return * reshaped Matrix * ***************************************************************************************/ Matrix<TYPE> reshape(int width, int height) { assert(this->width != 0 && this->height != 0 && this->channel != 0); assert((this->channel * this->height * this->width) == width * height); Matrix<TYPE> tmp(width, height, 1); for (int i = 0; i < width * height * channel; i++) tmp.data[i] = this->data[i]; return tmp; } /****************************************************************************************** * Convert to 3D Matrix data * args * width : matrix width * height : matrix height * channel : matrix channel, in other word matrix depth * return * reshaped Matrix * ***************************************************************************************/ Matrix<TYPE> reshape(int width, int height, int channel) { assert(this->width != 0 && this->height != 0 && this->channel != 0); assert((this->channel * this->height * this->width) == (channel * width * height)); Matrix<TYPE> tmp(width, height, channel); for (int i = 0; i < width * height * channel; i++) tmp.data[i] = this->data[i]; return tmp; } /****************************************************************************************** * Opt out Matrix datas * ***************************************************************************************/ void show(void) { for (int i = 0; i < this->channel; i++) { if (i > 1){ printf("channel %d",i); printf("\n\r"); } printf("["); for (int j = 0; j < this->height; j++) { printf("["); for (int k = 0; k < this->width; k++) { int ptr = (i * this->width * this->height) + (j * this->width) + k; printf("%F ",(double)data[ptr].to_double()); //ごめんなさい } printf("]"); if (j < this->height - 1) { printf("\n\r"); } } printf("]"); printf("\n\r"); } } /****************************************************************************************** * Opt out Matrix datas in 1/0 * ***************************************************************************************/ void show_bin(void) { for (int i = 0; i < this->channel; i++) { if (i > 1){ printf("channel %d",i ); printf("\n\r"); } printf("["); for (int j = 0; j < this->height; j++) { printf("["); for (int k = 0; k < this->width; k++) { int ptr = (i * this->width * this->height) + (j * this->width) + k; printf(" %d",((data[ptr] > 0) ? 1 : 0)); } printf("]"); if (j < this->height - 1) { printf("\n\r"); } } printf("]"); printf("\n\r"); } } /****************************************************************************************** * opt out Matrix Dimensions Lengths * ***************************************************************************************/ void shape(void) { if (this->height == 0 || this->channel == 0) { printf"%d",width); printf("\n\r"); } else if (this->channel == 0) { printf("%d,%d",this->width,this->height) printf("\n\r"); } else { printf("%d,%d,%d",this->width,this->height,this->channel); printf("\n\r"); } } /****************************************************************************************** * Calcate Innner Product * args * obj : same type matrix. A.dot(B) is AB * return * Matrix of innner product matrix * ***************************************************************************************/ Matrix<TYPE> dot(Matrix<TYPE> obj) { assert(this->channel == obj.channel); assert(this->width == obj.height); //avoid null assert((0 < this->width && 0 < this->height) || (0 < obj.width && 0 < obj.height)); if ((this->height == 0) || (obj.height == 0)) { //multiplying condition assert(this->width == obj.width); Matrix<TYPE> sum(1); for (int i = 0; i < width; i++) { sum.data[0] = sum.data[0] + this->data[i] * obj.data[i]; } return sum; } else { //multiplying condition assert((0 < this->width || 0 < this->height) || (0 < obj.width || 0 < obj.height)); assert(this->width == obj.height); Matrix<TYPE> result(obj.width, this->height, this->channel); for (int i = 0; i < result.channel; i++) //channel { int channel_offset = (result.width * result.height) * i; for (int j = 0; j < result.height; j++) //height { int line_offset = j * result.width; for (int k = 0; k < result.width; k++) //width { //line inner TYPE sum = 0.0; for (int l = 0; l < this->width; l++) { int pt_this = l + j * this->width; int pt_obj = l * obj.width + k; sum = sum + this->data[pt_this] * obj.data[pt_obj]; } // std::cout << channel_offset + line_offset + k << "=" << sum << printf("\n\r"); result.data[channel_offset + line_offset + k] = sum; } } } return result; } } /****************************************************************************************** * Calcrate self transpose * return * transposed Matrix * ***************************************************************************************/ Matrix<TYPE> transpose(void) { //only 2d array assertt(channel == 1); Matrix<TYPE> result(this->height, this->width, this->channel); for (int h_index = 0; h_index < height; h_index++) { for (int w_index = 0; w_index < width; w_index++) { result.data[result.calc_pos(h_index, w_index, 0)] = this->data[this->calc_pos(w_index, h_index, 0)]; } } return result; } /****************************************************************************************** * Aplly argment function to all elements * return * Applyed Element Matrix * ***************************************************************************************/ Matrix<TYPE> apply(TYPE (*func)(TYPE)) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = func(this->data[i]); } return result; } /****************************************************************************************** * Pic up max value from matrix * arg * axis direction of pic up line or face, this data dimention is lower 1 this Matrix * * If this matrix's dimention is 1, then,, * result is 1 element matrix; * If this matrix's dimention is 2, then... * if axis is 0, pic up veatrical max value array. * else if axis is 1, pic up horizonal max value attai, * If this matrix's dimention is 3 ,then... * if axis is 0, pic up veatrical max value face. * else if axis is 1, pic up horizonal max value face. * else if axis is 2, pic up depth nax value face. * ***************************************************************************************/ Matrix<TYPE> max(int axis) { assert(this->width != 0 && this->height != 0 && this->channel != 0); if ((width == 1 || height == 1) && channel == 1) { Matrix<TYPE> result(1, 1, 1); result.data[0] = this->data[0]; for (int i = 0; i < (this->width * this->height * this->channel); i++) { if (result.data[0] < this->data[i]) { result.data[0] = this->data[i]; } } return result; } else if (channel == 1) { if (axis == 0) //row direction { Matrix<TYPE> result(1, this->height); for (int y = 0; y < this->height; y++) { result.data[result.calc_pos(0, y, 0)] = this->data[calc_pos(0, y, 0)]; for (int i = 0; i < this->width; i++) { if (result.data[result.calc_pos(0, y, 0)] < this->data[calc_pos(i, y, 0)]) { result.data[result.calc_pos(0, y, 0)] = this->data[calc_pos(i, y, 0)]; } } } return result; } else if (axis == 1) //colmn direction { Matrix<TYPE> result(this->width, 1); for (int x = 0; x < this->height; x++) { result.data[result.calc_pos(x, 0, 0)] = this->data[calc_pos(x, 0, 0)]; for (int i = 0; i < this->height; i++) { if (result.data[result.calc_pos(x, 0, 0)] < this->data[calc_pos(x, i, 0)]) { result.data[result.calc_pos(x, 0, 0)] = this->data[calc_pos(x, i, 0)]; } } } return result; } } else if (1 < channel) { if (axis == 0) //row direction { Matrix<TYPE> result(1, this->height, this->channel); for (int y = 0; y < this->height; y++) { for (int z = 0; z < this->channel; z++) { result.data[result.calc_pos(0, y, z)] = this->data[calc_pos(0, y, z)]; for (int i = 0; i < this->width; i++) { if (result.data[result.calc_pos(0, y, z)] < this->data[calc_pos(i, y, z)]) { result.data[result.calc_pos(0, y, z)] = this->data[calc_pos(i, y, z)]; } } } } return result; } else if (axis == 1) //column direction { Matrix<TYPE> result(this->width, 1, this->channel); for (int x = 0; x < this->height; x++) { for (int z = 0; z < this->channel; z++) { result.data[result.calc_pos(x, 0, z)] = this->data[calc_pos(x, 0, z)]; for (int i = 0; i < this->height; i++) { if (result.data[result.calc_pos(x, 0, z)] < this->data[calc_pos(x, i, z)]) { result.data[result.calc_pos(x, 0, z)] = this->data[calc_pos(x, i, z)]; } } } } return result; } else if (axis == 2) //depth direction { Matrix<TYPE> result(this->width, this->height, 1); for (int x = 0; x < this->height; x++) { for (int y = 0; y < this->channel; y++) { result.data[result.calc_pos(x, y, 0)] = this->data[calc_pos(x, y, 0)]; for (int i = 0; i < this->channel; i++) { if (result.data[result.calc_pos(x, y, 0)] < this->data[calc_pos(x, y, i)]) { result.data[result.calc_pos(x, y, 0)] = this->data[calc_pos(x, y, i)]; } } } } return result; } } } /****************************************************************************************** * Pic up index of max value from matrix * arg * axis direction of pic up line or face, this data dimention is lower 1 this Matrix * * If this matrix's dimention is 1, then,, * result is 1 element matrix; * If this matrix's dimention is 2, then... * if axis is 0, pic up veatrical index array of max values. * else if axis is 1, pic up horizonal index array of max values, * If this matrix's dimention is 3 ,then... * if axis is 0, pic up veatrical index face of max values. * else if axis is 1, pic up horizonal index face of max values. * else if axis is 2, pic up depth index face of max values. * ***************************************************************************************/ Matrix<TYPE> max_arg(int axis) { assert(height != 0 && channel != 0); if ((width == 0 || height == 0) && channel == 1) { Matrix<TYPE> result(1, 1, 1); Matrix<TYPE> result_index(1, 1, 1); result.data[0] = this->data[0]; result_index.data[0] = this->data[0]; for (int i = 0; i < (this->width * this->height * this->channel); i++) { if (result.data[0] < this->data[i]) { result.data[0] = this->data[i]; result_index.data[0] = (double)i; } } return result_index; } else if (channel == 1) { if (axis == 0) //row direction { Matrix<TYPE> result(1, this->height); Matrix<TYPE> result_index(1, this->height); for (int y = 0; y < this->height; y++) { result.data[result.calc_pos(0, y, 0)] = this->data[calc_pos(0, y, 0)]; result_index.data[result_index.calc_pos(0, y, 0)] = 0; for (int i = 0; i < this->width; i++) { if (result.data[result.calc_pos(0, y, 0)] < this->data[calc_pos(i, y, 0)]) { result.data[result.calc_pos(0, y, 0)] = this->data[calc_pos(i, y, 0)]; result_index.data[result_index.calc_pos(0, y, 0)] = (double)i; } } } return result_index; } else if (axis == 1) //colmn direction { Matrix<TYPE> result(this->width, 1); Matrix<TYPE> result_index(this->width, 1); for (int x = 0; x < this->height; x++) { result.data[result.calc_pos(x, 0, 0)] = this->data[calc_pos(x, 0, 0)]; result_index.data[result_index.calc_pos(x, 0, 0)] = 0; for (int i = 0; i < this->height; i++) { if (result.data[result.calc_pos(x, 0, 0)] < this->data[calc_pos(x, i, 0)]) { result.data[result.calc_pos(x, 0, 0)] = this->data[calc_pos(x, i, 0)]; result_index.data[result_index.calc_pos(x, 0, 0)] = (double)i; } } } return result_index; } } else if (1 < channel) { if (axis == 0) //row direction { Matrix<TYPE> result(1, this->height, this->channel); Matrix<TYPE> result_index(1, this->height, this->channel); for (int y = 0; y < this->height; y++) { for (int z = 0; z < this->channel; z++) { result.data[result.calc_pos(0, y, z)] = this->data[calc_pos(0, y, z)]; result_index.data[result_index.calc_pos(0, y, z)] = 0; for (int i = 0; i < this->width; i++) { if (result.data[result.calc_pos(0, y, z)] < this->data[calc_pos(i, y, z)]) { result.data[result.calc_pos(0, y, z)] = this->data[calc_pos(i, y, z)]; result_index.data[result_index.calc_pos(0, y, z)] = (double)i; } } } } return result_index; } else if (axis == 1) //column direction { Matrix<TYPE> result(this->width, 1, this->channel); Matrix<TYPE> result_index(this->width, 1, this->channel); for (int x = 0; x < this->height; x++) { for (int z = 0; z < this->channel; z++) { result.data[result.calc_pos(x, 0, z)] = this->data[calc_pos(x, 0, z)]; result_index.data[result_index.calc_pos(x, 0, z)] = 0; for (int i = 0; i < this->height; i++) { if (result.data[result.calc_pos(x, 0, z)] < this->data[calc_pos(x, i, z)]) { result.data[result.calc_pos(x, 0, z)] = this->data[calc_pos(x, i, z)]; result_index.data[result_index.calc_pos(x, 0, z)] = (double)i; } } } } return result_index; } else if (axis == 2) //depth direction { Matrix<TYPE> result(this->width, this->height, 1); Matrix<TYPE> result_index(this->width, this->height, 1); for (int x = 0; x < this->height; x++) { for (int y = 0; y < this->channel; y++) { result.data[result.calc_pos(x, y, 0)] = this->data[calc_pos(x, y, 0)]; result_index.data[result_index.calc_pos(x, y, 0)] = 0; for (int i = 0; i < this->channel; i++) { if (result.data[result.calc_pos(x, y, 0)] < this->data[calc_pos(x, y, i)]) { result.data[result.calc_pos(x, y, 0)] = this->data[calc_pos(x, y, i)]; result_index.data[result_index.calc_pos(x, y, 0)] = (double)i; } } } } return result_index; } } } /****************************************************************************************** * Calcrate sum of matrix * arg * axis : direction of calcrating sums line or face, this data dimention is lower 1 this Matrix * * If this matrix's dimention is 1, then,, * result is 1 element matrix; * If this matrix's dimention is 2, then... * if axis is 0, calcrate veatrical sum array. * else if axis is 1, calcrate horizonal sum array. * If this matrix's dimention is 3 ,then... * if axis is 0, calcrate veatrical sum face. * else if axis is 1, calcrate horizonal sum face. * else if axis is 2, calcrate depth sum face. * ***************************************************************************************/ Matrix<TYPE> sum(int axis) { assert(height != 0 && channel != 0); if ((width == 0 || height == 0) && channel == 1) { Matrix<TYPE> sum(1, 1, 1); for (int i = 0; i < (this->width * this->height * this->channel); i++) { sum.data[0] = sum.data[0] + this->data[i]; } return sum; } else if (channel == 1) { if (axis == 0) //row direction { Matrix<TYPE> sum(1, this->height); for (int i = 0; i < this->width; i++) { for (int y = 0; y < this->height; y++) { sum.data[sum.calc_pos(0, y, 0)] = sum.data[sum.calc_pos(0, y, 0)] + this->data[calc_pos(i, y, 0)]; } } return sum; } else if (axis == 1) //colmn direction { Matrix<TYPE> sum(this->width, 1); for (int i = 0; i < this->height; i++) { for (int x = 0; x < this->width; x++) { sum.data[sum.calc_pos(x, 0, 0)] = sum.data[sum.calc_pos(x, 0, 0)] + this->data[calc_pos(x, i, 0)]; } } return sum; } } else if (1 < channel) { if (axis == 0) //row direction { Matrix<TYPE> sum(1, this->height, this->channel); for (int i = 0; i < this->width; i++) { for (int y = 0; y < this->height; y++) { for (int z = 0; z < this->channel; z++) { sum.data[sum.calc_pos(0, y, z)] = sum.data[sum.calc_pos(0, y, z)] + this->data[calc_pos(i, y, z)]; } } } return sum; } else if (axis == 1) //column direction { Matrix<TYPE> sum(this->width, 1, this->channel); for (int i = 0; i < this->height; i++) { for (int x = 0; x < this->height; x++) { for (int z = 0; z < this->channel; z++) { sum.data[sum.calc_pos(x, 0, z)] = sum.data[sum.calc_pos(x, 0, z)] + this->data[calc_pos(x, i, z)]; } } } return sum; } else if (axis == 2) //depth direction { Matrix<TYPE> sum(this->width, this->height, 1); for (int i = 0; i < this->channel; i++) { for (int x = 0; x < this->height; x++) { for (int y = 0; y < this->channel; y++) { sum.data[sum.calc_pos(x, y, 0)] = sum.data[sum.calc_pos(x, y, 0)] + this->data[calc_pos(x, y, i)]; } } } return sum; } } } // Operator Over Rodes //assign Matrix<TYPE> operator<<(double x) { this->data[this->insert_index] = x; // std::cout << this->insert_index << ":" << this->data[this->insert_index] << printf("\n\r"); this->insert_index = this->insert_index + 1; return *this; } //matrix vs matrix Matrix<TYPE> operator+(Matrix<TYPE> obj) { if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { assert(this->width == obj.width && this->height == obj.height && this->channel == obj.channel); Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] + obj.data[i]; } return result; } //2d vs vector else if (obj.width != 1 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(w_index, 0, 0)]; } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(0, h_index, 0)]; } } } return result; } else if (obj.channel != 1 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(0, 0, c_index)]; } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(w_index, h_index, 0)]; } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(w_index, 0, c_index)]; } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + obj.data[obj.calc_pos(0, h_index, c_index)]; } } } return result; } assert(0); } Matrix<TYPE> operator-(Matrix<TYPE> obj) { assert(this->width == obj.width || this->height == obj.height || this->channel == obj.channel); if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] - obj.data[i]; } return result; } //2d vs vector else if (obj.width != 1 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(w_index, 0, 0)]; } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(0, h_index, 0)]; } } } return result; } else if (obj.channel != 1 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(0, 0, c_index)]; } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(w_index, h_index, 0)]; } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(w_index, 0, c_index)]; } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] - obj.data[obj.calc_pos(0, h_index, c_index)]; } } } return result; } assert(0); } Matrix<TYPE> operator*(Matrix<TYPE> obj) { assert(this->width == obj.width || this->height == obj.height || this->channel == obj.channel); if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { assert(this->width == obj.width && this->height == obj.height && this->channel == obj.channel); Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] * obj.data[i]; } return result; } //2d vs vector else if (obj.width != 0 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(w_index, 0, 0)]; } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(0, h_index, 0)]; } } } return result; } else if (obj.channel != 0 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(0, 0, c_index)]; } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(w_index, h_index, 0)]; } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(w_index, 0, c_index)]; } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] * obj.data[obj.calc_pos(0, h_index, c_index)]; } } } return result; } assert(0); } Matrix<TYPE> operator/(Matrix<TYPE> obj) { assert(this->width == obj.width || this->height == obj.height || this->channel == obj.channel); if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { assert(this->width == obj.width && this->height == obj.height && this->channel == obj.channel); Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] / obj.data[i]; } return result; } //2d vs vector else if (obj.width != 0 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(w_index, 0, 0)]; } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(0, h_index, 0)]; } } } return result; } else if (obj.channel != 1 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(0, 0, c_index)]; } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(w_index, h_index, 0)]; } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(w_index, 0, c_index)]; } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //X axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] / obj.data[obj.calc_pos(0, h_index, c_index)]; } } } return result; } assert(0); } Matrix<TYPE> compare(Matrix<TYPE> obj) { assert(this->width == obj.width || this->height == obj.height || this->channel == obj.channel); if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { assert(this->width == obj.width && this->height == obj.height && this->channel == obj.channel); Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = (double)(this->data[i] == obj.data[i]); } return result; } //2d vs vector else if (obj.width != 0 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(w_index, 0, 0)]); } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(0, h_index, 0)]); } } } return result; } else if (obj.channel != 1 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(0, 0, c_index)]); } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(w_index, h_index, 0)]); } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(w_index, 0, c_index)]); } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //X axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = (double)(this->data[this->calc_pos(w_index, h_index, c_index)] == obj.data[obj.calc_pos(0, h_index, c_index)]); } } } return result; } assert(0); } //matrix vs double Matrix<TYPE> operator+(double x) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] + x; } return result; } Matrix<TYPE> operator*(double x) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] * x; } return result; } Matrix<TYPE> operator/(double x) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] / x; } return result; } //clone Matrix<TYPE> clone(void) { assert(this->data != NULL); if (height == 0 || channel == 0) { Matrix<TYPE> cloned(this->width); for (int i = 0; i < width; i++) { cloned.data[i] = this->data[i]; } return cloned; } else { Matrix<TYPE> cloned(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { cloned.data[i] = this->data[i]; } return cloned; } //don't copy counter of << } // overwrite by random parameter Matrix<TYPE> random(double ave, double dis) { assert(this->width > 0 && this->height > 0 && this->channel > 0); Matrix<TYPE> result(this->width, this->height, this->channel); std::random_device rd{}; std::mt19937 gen{rd()}; std::random_device seed_gen; std::default_random_engine engine(seed_gen()); std::normal_distribution<double> dist(ave, dis); for (int i = 0; i < width * height * channel; i++) { double tmp = (double)dist(engine); //std::cout << tmp << printf("\n\r"); result.data[i] = (tmp + 0.5); } return result; } /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /************************************************************turatan**************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /***************************************************************************************************************************************************************************************************************************/ /****************************************************************************************** * Calcate Innner Product * args * obj : same type matrix. A.dot(B) is AB * return * Matrix of innner product matrix * ***************************************************************************************/ Matrix<TYPE> dot(mat::ConstMatrix obj) { assert(this->channel == obj.channel); assert(this->width == obj.height); //avoid null assert((0 < this->width && 0 < this->height) || (0 < obj.width && 0 < obj.height)); if ((this->height == 0) || (obj.height == 0)) { //multiplying condition assert(this->width == obj.width); Matrix<TYPE> sum(1); for (int i = 0; i < width; i++) { sum.data[0] = sum.data[0] + this->data[i] * TYPE(obj.data[i]); } return sum; } else { //multiplying condition assert((0 < this->width || 0 < this->height) || (0 < obj.width || 0 < obj.height)); assert(this->width == obj.height); Matrix<TYPE> result(obj.width, this->height, this->channel); for (int i = 0; i < result.channel; i++) //channel { int channel_offset = (result.width * result.height) * i; for (int j = 0; j < result.height; j++) //height { int line_offset = j * result.width; for (int k = 0; k < result.width; k++) //width { //line inner TYPE sum = 0.0; for (int l = 0; l < this->width; l++) { int pt_this = l + j * this->width; int pt_obj = l * obj.width + k; sum = sum + this->data[pt_this] * TYPE(obj.data[pt_obj]); } // std::cout << channel_offset + line_offset + k << "=" << sum << printf("\n\r"); result.data[channel_offset + line_offset + k] = sum; } } } return result; } } /********* + operator**************************************************/ Matrix<TYPE> operator+(mat::ConstMatrix obj) { if (this->width == obj.width && this->height == obj.height && this->channel == obj.channel) //simple adder { assert(this->width == obj.width && this->height == obj.height && this->channel == obj.channel); Matrix<TYPE> result(this->width, this->height, this->channel); for (int i = 0; i < width * height * channel; i++) { result.data[i] = this->data[i] + TYPE(obj.data[i]); } return result; } //2d vs vector else if (obj.width != 1 && this->width == obj.width && obj.height == 1 && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(w_index, 0, 0)]); } } } return result; } else if (obj.height != 1 && obj.width == 1 && obj.height == this->height && obj.channel == 1) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(0, h_index, 0)]); } } } return result; } else if (obj.channel != 1 && obj.width == 1 && obj.height == 1 && obj.channel == this->channel) { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(0, 0, c_index)]); } } } return result; } //3D vs 2D else if (this->width == obj.width && obj.height == this->height && obj.channel == 1) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(w_index, h_index, 0)]); } } } return result; } else if (this->width == obj.width && obj.height == 1 && obj.channel == this->channel) //Y axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(w_index, 0, c_index)]); } } } return result; } else if (this->width == 1 && obj.height == 1 && obj.channel == this->channel) //Z axis face { Matrix<TYPE> result(this->width, this->height, this->channel); for (int c_index = 0; c_index < this->channel; c_index++) { for (int h_index = 0; h_index < this->height; h_index++) { for (int w_index = 0; w_index < this->width; w_index++) { result.data[this->calc_pos(w_index, h_index, c_index)] = this->data[this->calc_pos(w_index, h_index, c_index)] + TYPE(obj.data[obj.calc_pos(0, h_index, c_index)]); } } } return result; } assert(0); } }; } // namespace mat #endif