Skip to content

Instantly share code, notes, and snippets.

@sdkfz181tiger
Last active May 17, 2024 22:17
Show Gist options
  • Save sdkfz181tiger/38d4256df0e028a2be31f07c2e5675a2 to your computer and use it in GitHub Desktop.
Save sdkfz181tiger/38d4256df0e028a2be31f07c2e5675a2 to your computer and use it in GitHub Desktop.
C/C++課題ネタ08_マトリクス演算クラス(演算子オーバーロード)
//==========
// マトリクス演算クラス
// 1, Compile
// g++ -std=c++17 -Wall -Wextra main.cpp
// 2, Run
// ./a.out
#include <math.h>
#include <stdio.h>
#include "Mtx3xX.cpp"
void test1(){
// Test
const Mtx3x1 mtxA;
const Mtx3x1 mtxB({0.1f, 0.1f, 0.1f});
const Mtx3x1 mtxC = {0.2f, 0.2f, 0.2f};
mtxA.trace();
mtxB.trace();
mtxC.trace();
const Mtx3x3 mtxD;
const Mtx3x3 mtxE({
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f
});
const Mtx3x3 mtxF = {
0.2f, 0.2f, 0.2f,
0.2f, 0.2f, 0.2f,
0.2f, 0.2f, 0.2f
};
mtxD.trace();
mtxE.trace();
mtxF.trace();
if(mtxE == mtxF){
printf("mtxE == mtxF\n");
}else{
printf("mtxE /= mtxF\n");
}
const Mtx3x3 mtxG({
0.3f, 0.3f, 0.3f,
0.3f, 0.3f, 0.3f,
0.3f, 0.3f, 0.3f
});
Mtx3x3 mtxH = mtxG * 2.0f;
mtxH += mtxE;
mtxH.trace();
mtxH -= mtxE;
mtxH.trace();
mtxH *= 3.0f;
mtxH.trace();
mtxH /= 3.0f;
mtxH.trace();
const Mtx3x3 mtxI = mtxG.multiply(mtxG);
mtxI.trace();
const Mtx3x1 mtxJ = mtxG.multiply(mtxB);
mtxJ.trace();
}
void test2(){
// 三元連立一次方程式を解く
// 左辺
const Mtx3x3 mtxA({
1, -2, 3,
2, -1, 1,
1, 3,-5
});
// 右辺
const Mtx3x1 mtxB({
5, 6, 2
});
// 逆行列
const Mtx3x3 rev = mtxA.reverse();
rev.trace();
// 解答
const Mtx3x1 ans = rev.multiply(mtxB);
ans.trace();
}
int main(){
printf("Hello, Mtx3xX!!\n");
test1();
test2();
return 0;
}
#include "Mtx3xX.h"
bool Mtx3x3::operator==(const Mtx3x3 &rhs) const{
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
if(mtx[r][c] != rhs.mtx[r][c]) return false;
}
}
return true;
}
Mtx3x3 Mtx3x3::operator+(const Mtx3x3 &rhs) const{
Mtx3x3 result;
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
result.mtx[r][c] = mtx[r][c] + rhs.mtx[r][c];
}
}
return result;
}
Mtx3x3 Mtx3x3::operator-(const Mtx3x3 &rhs) const{
Mtx3x3 result;
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
result.mtx[r][c] = mtx[r][c] - rhs.mtx[r][c];
}
}
return result;
}
Mtx3x3 Mtx3x3::operator*(const float mul) const{
Mtx3x3 result;
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
result.mtx[r][c] = mtx[r][c] * mul;
}
}
return result;
}
Mtx3x3 Mtx3x3::operator/(const float div) const{
Mtx3x3 result;
if(div == 0.0f) return result;// Infinity
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
result.mtx[r][c] = mtx[r][c] / div;
}
}
return result;
}
Mtx3x3 &Mtx3x3::operator+=(const Mtx3x3 &rhs){
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
mtx[r][c] += rhs.mtx[r][c];
}
}
return *this;
}
Mtx3x3 &Mtx3x3::operator-=(const Mtx3x3 &rhs){
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
mtx[r][c] -= rhs.mtx[r][c];
}
}
return *this;
}
Mtx3x3 &Mtx3x3::operator*=(const float mul){
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
mtx[r][c] *= mul;
}
}
return *this;
}
Mtx3x3 &Mtx3x3::operator/=(const float div){
if(div == 0.0f) return *this;// Infinity
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
mtx[r][c] /= div;
}
}
return *this;
}
Mtx3x3 Mtx3x3::reverse() const{
const float n1 = mtx[0][0]*mtx[1][1]*mtx[2][2];
const float n2 = mtx[0][1]*mtx[1][2]*mtx[2][0];
const float n3 = mtx[0][2]*mtx[1][0]*mtx[2][1];
const float n4 = mtx[0][2]*mtx[1][1]*mtx[2][0];
const float n5 = mtx[0][1]*mtx[1][0]*mtx[2][2];
const float n6 = mtx[0][0]*mtx[1][2]*mtx[2][1];
const float num = n1+n2+n3-n4-n5-n6;
const float m00 = (mtx[1][1]*mtx[2][2]-mtx[1][2]*mtx[2][1]) / num;
const float m01 = -(mtx[0][1]*mtx[2][2]-mtx[0][2]*mtx[2][1]) / num;
const float m02 = (mtx[0][1]*mtx[1][2]-mtx[0][2]*mtx[1][1]) / num;
const float m10 = -(mtx[1][0]*mtx[2][2]-mtx[1][2]*mtx[2][0]) / num;
const float m11 = (mtx[0][0]*mtx[2][2]-mtx[0][2]*mtx[2][0]) / num;
const float m12 = -(mtx[0][0]*mtx[1][2]-mtx[0][2]*mtx[1][0]) / num;
const float m20 = (mtx[1][0]*mtx[2][1]-mtx[1][1]*mtx[2][0]) / num;
const float m21 = -(mtx[0][0]*mtx[2][1]-mtx[0][1]*mtx[2][0]) / num;
const float m22 = (mtx[0][0]*mtx[1][1]-mtx[0][1]*mtx[1][0]) / num;
Mtx3x3 result({
m00, m01, m02,
m10, m11, m12,
m20, m21, m22
});
return result;
}
Mtx3x3 Mtx3x3::multiply(const Mtx3x3 &rhs) const{
Mtx3x3 result;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
for(int k=0; k<3; k++){
result.mtx[i][j] += mtx[i][k] * rhs.mtx[k][j];
}
}
}
return result;
}
Mtx3x1 Mtx3x3::multiply(const Mtx3x1 &rhs) const{
Mtx3x1 result;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
result.mtx[i][0] += mtx[i][j] * rhs.mtx[j][0];
}
}
return result;
}
#ifndef _MTX3XX_H_
#define _MTX3XX_H_
//==========
// C++
#include <initializer_list>
using namespace std;
class Mtx3x1 {
public:
const size_t size;
float mtx[3][1];
Mtx3x1(): size(3){
//printf("Mtx3x1\n");
for(size_t i=0; i<size; i++){
mtx[i][0] = 0.0f;
}
}
Mtx3x1(initializer_list<float> arr): size(3){
//printf("Mtx3x1\n");
auto it = arr.begin();
for(size_t i=0; i<size; i++){
mtx[i][0] = *(it + i);
}
}
~Mtx3x1(){};
void trace() const{
printf("=== mtx3x1 ===\n");
for(size_t r=0; r<size; r++){
printf("%.2f\n", mtx[r][0]);
}
printf("==============\n");
}
void operator=(const float* rhs){
for(size_t i=0; i<size; i++){
mtx[i][0] = rhs[i];
}
}
};
class Mtx3x3 {
public:
const size_t size;
float mtx[3][3];
Mtx3x3(): size(3){
//printf("Mtx3x3\n");
for(size_t i=0; i<size*size; i++){
const size_t r = i / size;
const size_t c = i % size;
mtx[r][c] = 0.0f;
}
}
Mtx3x3(initializer_list<float> arr): size(3){
//printf("Mtx3x3\n");
auto it = arr.begin();
for(size_t i=0; i<size*size; i++){
const size_t r = i / size;
const size_t c = i % size;
mtx[r][c] = *(it + i);
}
}
~Mtx3x3(){};
void trace() const{
printf("=== mtx3x3 ===\n");
for(size_t r=0; r<size; r++){
for(size_t c=0; c<size; c++){
printf("%.2f", mtx[r][c]);
if(c<size-1) printf(",");
else printf("\n");
}
}
printf("==============\n");
}
void operator=(const float* rhs){
for(size_t i=0; i<size*size; i++){
const size_t r = i / size;
const size_t c = i % size;
mtx[r][c] = rhs[i];
}
}
bool operator==(const Mtx3x3 &rhs) const;
Mtx3x3 operator+(const Mtx3x3 &rhs) const;
Mtx3x3 operator-(const Mtx3x3 &rhs) const;
Mtx3x3 operator*(const float mul) const;
Mtx3x3 operator/(const float div) const;
Mtx3x3 &operator+=(const Mtx3x3 &rhs);
Mtx3x3 &operator-=(const Mtx3x3 &rhs);
Mtx3x3 &operator*=(const float mul);
Mtx3x3 &operator/=(const float div);
Mtx3x3 reverse() const;
Mtx3x3 multiply(const Mtx3x3 &rhs) const;
Mtx3x1 multiply(const Mtx3x1 &rhs) const;
};
#endif // _MTX3XX_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment