<commit_before>/****************************************************************************************************************************
**
**         MIST ( Media Integration Standard Toolkit )
**
**         matrix template class implementation using teqnique of an expression template.
**
**
**           All matrix operations are described in row order.
**           All matrix elements are allocated as one dimensional array on the memory space.
**
**             ex) The order of 3x3 matrix are
**
**                   1  4  7
**                   2  5  8
**                   3  6  9
**
**
**         use atrix( row, col ) accesses operation. 
**
**
**
**         We developed these programs since 2003/09/05.
**
**             $LastChangedDate$
**             $LastChangedRevision$
**             $LastChangedBy$
**             $HeadURL$
**
**              Copyright ***********************.
**                    All Rights Reserved.
**
****************************************************************************************************************************/



#ifndef __INCLUDE_MIST_MATRIX__
#define __INCLUDE_MIST_MATRIX__

#include "mist.h"
#include <cmath>

// mistOԂ̎n܂
_MIST_BEGIN

#if _USE_EXPRESSION_TEMPLATE_ != 0

template < class T > struct matrix_minus;
template < class T > struct matrix_transpose;

template< class T, class Allocator, class Derive >
struct matrix_expression
{
	typedef T value_type;
	typedef Allocator allocator_type;
	typedef typename Allocator::size_type size_type;

	const Derive &get_ref( ) const { return( static_cast< const Derive & >( *this ) ); }
	value_type operator()( size_type r, size_type c ) const { return( get_ref( ).operator()( r, c ) ); }
	size_type rows( ) const { return( get_ref( ).rows( ) ); };
	size_type cols( ) const { return( get_ref( ).cols( ) ); };

	matrix_minus< matrix_expression< T, Allocator, Derive > > operator -() const { return( matrix_minus< matrix_expression< T, Allocator, Derive > >( *this ) ); }
	matrix_transpose< matrix_expression< T, Allocator, Derive > > t( ) const { return( matrix_transpose< matrix_expression< T, Allocator, Derive > >( *this ) ); }
};

// PZq
template< class T, class Derive >
struct matrix_single_operation : public matrix_expression< typename T::value_type, typename T::allocator_type, Derive > 
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	const T &middle_;

	matrix_single_operation( const T &mhs ) : middle_( mhs ){}
};

// QZq
template< class T1, class T2, class Derive >
struct matrix_bind_operation : public matrix_expression< typename T1::value_type, typename T1::allocator_type, Derive > 
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	const T1 &left_;
	const T2 &right_;

	matrix_bind_operation( const T1 &lhs, const T2 &rhs ) : left_( lhs ), right_( rhs ){}
};


// ̕Iy[^
template< class T >
struct matrix_minus : public matrix_single_operation< T, matrix_minus< T > >
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	matrix_minus( const T &mhs ) : matrix_single_operation< T, matrix_minus< T > >( mhs ){}
	size_type rows( ) const { return( middle_.rows( ) ); }
	size_type cols( ) const { return( middle_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( - middle_( r, c ) ); }
};


// ]uIy[^
template< class T >
struct matrix_transpose : public matrix_single_operation< T, matrix_transpose< T > >
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	matrix_transpose( const T &mhs ) : matrix_single_operation< T, matrix_transpose< T > >( mhs ){}
	size_type rows( ) const { return( middle_.cols( ) ); }
	size_type cols( ) const { return( middle_.rows( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( middle_( c, r ) ); }
};


// ZIy[^
template< class T1, class T2 >
struct matrix_add : public matrix_bind_operation< T1, T2, matrix_add< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_add( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_add< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.rows( ) != rhs.rows( ) || lhs.cols( ) != rhs.cols( ) )
		{
			// Zł܂O
			::std::cout << "ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) + right_( r, c ) ); }
};


// ZIy[^
template< class T1, class T2 >
struct matrix_sub : public matrix_bind_operation< T1, T2, matrix_sub< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_sub( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_sub< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.rows( ) != rhs.rows( ) || lhs.cols( ) != rhs.cols( ) )
		{
			// Zł܂O
			::std::cout << "ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) - right_( r, c ) ); }
};


//|ZIy[^
template< class T1, class T2 >
struct matrix_mul : public matrix_bind_operation< T1, T2, matrix_mul< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_mul( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_mul< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.cols( ) != rhs.rows( ) )
		{
			// |Zł܂O
			::std::cout << "|ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( right_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const
	{
		value_type v = 0;
		size_type size = left_.cols( );
		for( size_type t = 0 ; t < size ; ++t )
		{
			v += left_( r, t ) * right_( t, c );
		}
		return( v );
	}
};


// 萔̑ZIy[^
template< class T1, class T2 >
struct matrix_add_const : public matrix_bind_operation< T1, T2, matrix_add_const< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_add_const( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_add_const< T1, T2 > >( lhs, rhs ){}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) + ( r == c ? right_ : 0 ) ); }
};

// 萔̑ZIy[^iE萔j
template< class T1, class T2 >
struct matrix_sub_const1 : public matrix_bind_operation< T1, T2, matrix_sub_const1< T1, T2 > ><commit_msg>日付等の自動埋め込みキーワードを設定．<commit_after>/****************************************************************************************************************************
**
**         MIST ( Media Integration Standard Toolkit )
**
**         matrix template class implementation using teqnique of an expression template.
**
**
**           All matrix operations are described in row order.
**           All matrix elements are allocated as one dimensional array on the memory space.
**
**             ex) The order of 3x3 matrix are
**
**                   1  4  7
**                   2  5  8
**                   3  6  9
**
**
**         use atrix( row, col ) accesses operation. 
**
**
**
**         We developed these programs since 2003/09/05.
**
**             $LastChangedDate$
**             $LastChangedRevision$
**             $LastChangedBy$
**             $HeadURL$
**
**              Copyright ***********************.
**                    All Rights Reserved.
**
****************************************************************************************************************************/



#ifndef __INCLUDE_MIST_MATRIX__
#define __INCLUDE_MIST_MATRIX__

#include "mist.h"
#include <cmath>

// mistOԂ̎n܂
_MIST_BEGIN

#if _USE_EXPRESSION_TEMPLATE_ != 0

template < class T > struct matrix_minus;
template < class T > struct matrix_transpose;

template< class T, class Allocator, class Derive >
struct matrix_expression
{
	typedef T value_type;
	typedef Allocator allocator_type;
	typedef typename Allocator::size_type size_type;

	const Derive &get_ref( ) const { return( static_cast< const Derive & >( *this ) ); }
	value_type operator()( size_type r, size_type c ) const { return( get_ref( ).operator()( r, c ) ); }
	size_type rows( ) const { return( get_ref( ).rows( ) ); };
	size_type cols( ) const { return( get_ref( ).cols( ) ); };

	matrix_minus< matrix_expression< T, Allocator, Derive > > operator -() const { return( matrix_minus< matrix_expression< T, Allocator, Derive > >( *this ) ); }
	matrix_transpose< matrix_expression< T, Allocator, Derive > > t( ) const { return( matrix_transpose< matrix_expression< T, Allocator, Derive > >( *this ) ); }
};

// PZq
template< class T, class Derive >
struct matrix_single_operation : public matrix_expression< typename T::value_type, typename T::allocator_type, Derive > 
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	const T &middle_;

	matrix_single_operation( const T &mhs ) : middle_( mhs ){}
};

// QZq
template< class T1, class T2, class Derive >
struct matrix_bind_operation : public matrix_expression< typename T1::value_type, typename T1::allocator_type, Derive > 
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	const T1 &left_;
	const T2 &right_;

	matrix_bind_operation( const T1 &lhs, const T2 &rhs ) : left_( lhs ), right_( rhs ){}
};


// ̕Iy[^
template< class T >
struct matrix_minus : public matrix_single_operation< T, matrix_minus< T > >
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	matrix_minus( const T &mhs ) : matrix_single_operation< T, matrix_minus< T > >( mhs ){}
	size_type rows( ) const { return( middle_.rows( ) ); }
	size_type cols( ) const { return( middle_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( - middle_( r, c ) ); }
};


// ]uIy[^
template< class T >
struct matrix_transpose : public matrix_single_operation< T, matrix_transpose< T > >
{
	typedef typename T::value_type value_type;
	typedef typename T::size_type size_type;

	matrix_transpose( const T &mhs ) : matrix_single_operation< T, matrix_transpose< T > >( mhs ){}
	size_type rows( ) const { return( middle_.cols( ) ); }
	size_type cols( ) const { return( middle_.rows( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( middle_( c, r ) ); }
};


// ZIy[^
template< class T1, class T2 >
struct matrix_add : public matrix_bind_operation< T1, T2, matrix_add< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_add( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_add< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.rows( ) != rhs.rows( ) || lhs.cols( ) != rhs.cols( ) )
		{
			// Zł܂O
			::std::cout << "ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) + right_( r, c ) ); }
};


// ZIy[^
template< class T1, class T2 >
struct matrix_sub : public matrix_bind_operation< T1, T2, matrix_sub< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_sub( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_sub< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.rows( ) != rhs.rows( ) || lhs.cols( ) != rhs.cols( ) )
		{
			// Zł܂O
			::std::cout << "ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) - right_( r, c ) ); }
};


//|ZIy[^
template< class T1, class T2 >
struct matrix_mul : public matrix_bind_operation< T1, T2, matrix_mul< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_mul( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_mul< T1, T2 > >( lhs, rhs )
	{
#ifdef _CHECK_MATRIX_OPERATION_
		if( lhs.cols( ) != rhs.rows( ) )
		{
			// |Zł܂O
			::std::cout << "|ZsƂs̍sƗ̐v܂D" << ::std::endl;
		}
#endif
	}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( right_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const
	{
		value_type v = 0;
		size_type size = left_.cols( );
		for( size_type t = 0 ; t < size ; ++t )
		{
			v += right_( t, c ) * left_( r, t );
//			v += left_( r, t ) * right_( t, c );
		}
		return( v );
	}
};


// 萔̑ZIy[^
template< class T1, class T2 >
struct matrix_add_const : public matrix_bind_operation< T1, T2, matrix_add_const< T1, T2 > >
{
	typedef typename T1::value_type value_type;
	typedef typename T1::size_type size_type;

	matrix_add_const( const T1 &lhs, const T2 &rhs ) : matrix_bind_operation< T1, T2, matrix_add_const< T1, T2 > >( lhs, rhs ){}
	size_type rows( ) const { return( left_.rows( ) ); }
	size_type cols( ) const { return( left_.cols( ) ); }
	value_type operator()( size_type r, size_type c ) const { return( left_( r, c ) + ( r == c ? right_ : 0 ) ); }
};

// 萔̑ZIy[^iE萔j
template< class T1, class T2 >
struct matrix_sub_const1 : public matrix_bind_operation< T1, T2, matrix_sub_const1< T1, T2 > >
{'fraction_non_alphanumeric': 0.1742832193276088, 'fraction_numerical': 0.014117304613593364, 'mean_word_length': 3.8237978237978236, 'pattern_counts': {'":': 0, '<': 129, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5471394', 'n_tokens_mistral': 5169, 'n_tokens_neox': 4885, 'n_words': 1329}