/**********************************************************************
 
	Copyright (C) 2005- Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/

#include	"memory_debug.h"
#include	"xl.h"
#include	"matrix.h"
#include	"change_endian.h"

#define BASE_TYPE 	int

int mxt_int32_get_size(MATRIX_DATA_TYPE *,void * d);
void * mxt_int32_sexp2md(int * cpy,struct matrix_data_type*,XL_SEXP * s);
XL_SEXP * mxt_int32_md2sexp(struct matrix_data_type*,void * d);
int mxt_int32_cmp(struct matrix_data_type*,void*,void*);
int mxt_int32v_cmp(struct matrix_data_type*,void*,void*);
int mxt_int32_thined_rep(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int * rep,int,void * dest,void * src);
int mxt_int32_thined_avg(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int,void * dest,void * src);
int mxt_int32_add(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int parent,void * ,void * dest,void * src1,void * src2);
int mxt_int32_sub(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int parent,void * ,void * dest,void * src1,void * src2);
void mxt_endian_int32(void *);
void *  mxt_add_vv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c);
void *  mxt_sub_vv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c);
void *  mxt_mul_mm_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c);
void *  mxt_mul_sv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c);
void *	mxt_trans_m_int32(MATRIX_DATA_TYPE * tp,void *,MX_CACHE * c);
void mxt_get_zero_int32(MATRIX_DATA_TYPE * tp,void *);
void mxt_get_el_int32(MATRIX_DATA_TYPE * tp,void *);
void
mxt_print_int32(MATRIX_DATA_TYPE*tp,MATRIX_STRING_BUFFER*b,void*d,char*fmt);


MATRIX_DATA_TYPE mx_type_int32 = {
	MDT_INT32,
	0,
	mxt_int32_get_size,
	mxt_int32_sexp2md,
	mxt_int32_md2sexp,
	mxt_int32_cmp,
	mxt_vector_copy,
	mxt_alloc_copy,
	xx_mxt_alloc_data,
	mxt_free_data,
	0,
	0,
	0,
	0,
	mxt_endian_int32,
	mxt_endian_int32,
	mxt_convert_basic_to_net,
	mxt_convert_basic_to_host,
	0,0,0,0,0,
	mxt_get_zero_int32,
	mxt_get_el_int32,
	mxt_print_int32
};

MATRIX_DATA_TYPE mx_type_int32_v = {
	MDT_INT32|MDT_VECTOR,
	&mx_type_int32,
	mxt_vector_get_size,
	mxt_vector_sexp2md,
	mxt_vector_md2sexp,
	mxt_int32v_cmp,
	mxt_vector_copy,
	mxt_alloc_copy,
	xx_mxt_alloc_vector,
	mxt_free_data,
	mxt_int32_thined_rep,
	mxt_int32_thined_avg,
	mxt_int32_add,
	mxt_int32_sub,
	mxt_endian_vector_to_net,
	mxt_endian_vector_to_host,
	mxt_convert_basic_to_net,
	mxt_convert_basic_to_host,
	mxt_add_vv_int32,
	mxt_sub_vv_int32,
	mxt_mul_mm_int32,
	mxt_mul_sv_int32,
	mxt_trans_m_int32,
	0,0,
	mxt_print_vector
};


void mxt_endian_int32(void * d)
{
BASE_TYPE * dp;
	dp = (BASE_TYPE*)d;
	change_endian((*dp));
}


int
mxt_int32_get_size(MATRIX_DATA_TYPE * tp,void * d)
{
	return sizeof(BASE_TYPE);
}


void * 
mxt_int32_sexp2md(int * cpy,struct matrix_data_type* tp,XL_SEXP * s)
{
BASE_TYPE * ret;
	if ( get_type(s) != XLT_INTEGER )
		return 0;
	ret = d_alloc(sizeof(BASE_TYPE));
	*ret = s->integer.data;
	if ( cpy )
		*cpy = 1;
	return (void*)ret;
}

XL_SEXP * 
mxt_int32_md2sexp(struct matrix_data_type* tp,void * d)
{
BASE_TYPE * _d;
	_d = d;
	return get_integer(*_d,0);
}

int 
mxt_int32_cmp(struct matrix_data_type* tp,void* d1,void* d2)
{
BASE_TYPE * _d1, * _d2;
	_d1 = (BASE_TYPE*)d1;
	_d2 = (BASE_TYPE*)d2;
	if ( (*_d1) < (*_d2) )
		return -1;
	if ( (*_d1) > (*_d2) )
		return 1;
	return 0; 
}



int 
mxt_int32v_cmp(struct matrix_data_type* tp,void* d1,void* d2)
{
MATRIX_DH_SET h1;
MATRIX_DH_SET h2;
int ret;
BASE_TYPE * p1, * p2;
int i;
	get_matrix_dh_set(&h1,d1);
	get_matrix_dh_set(&h2,d2);
	ret = cmp_dh_set(&h1,&h2);
	if ( ret )
		return ret;
	i = h1.total_element;
	for ( p1 = h1.offset , p2 = h2.offset ; i > 0 ; i -- ) {
		if ( *p1 > *p2 )
			return 1;
		if ( *p1 < *p2 )
			return -1;
		p1 ++;
		p2 ++;
	}
	return 0;
}

int
mxt_int32_thined_rep(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int * rep,int parent,void * dest,void * src)
{
MATRIX_DH_SET h_src;
MATRIX_DH_SET h_dest;
INTEGER64 lev;
int i;
int _ofs;
int * ofs;
int * src_ix,* dest_ix;
int * src_inc;
BASE_TYPE * p1, * p2;
int dim;
int _p;
	get_matrix_dh_set(&h_src,src);
	get_matrix_dh_set(&h_dest,dest);
	if ( h_src.hd->dim != m->p.dim )
		return -1;
	if ( h_dest.hd->dim != m->p.dim )
		return -2;
	lev = dim_code[0];
	ofs = d_alloc(sizeof(int)*m->p.dim);
	for ( i = 0 ; i < m->p.dim ; i ++ ) {
		_p = m->dim_divide[i]*parent;
		if ( m->block_size[i] > _p ) {
			_ofs = 1<<(m->block_size[i] - _p);
			ofs[i] = _ofs * ((dim_code[i+1] >> 
					(lev * m->dim_divide[i] + m->block_size[i]))
				& ((1<<m->dim_divide[i]*parent)-1));
		}
		else	ofs[i] = 0;
	}
	dim = m->p.dim;
	src_ix = d_alloc(sizeof(int)*dim);
	dest_ix = d_alloc(sizeof(int)*dim);
	src_inc = d_alloc(sizeof(int)*dim);
	memcpy(src_ix,rep,sizeof(int)*dim);
	for ( i = 0 ; i < dim ; i ++ ) {
		src_inc[i] = 1<<(m->dim_divide[i]*parent);
	}
	for ( ; ; ) {
		for (  i = 0 ; i < dim ; i ++ )
			dest_ix[i] = (src_ix[i]>>(parent*m->dim_divide[i])) + ofs[i];
		p1 = &((BASE_TYPE*)h_src.offset)[get_seq_from_ix(src_ix,h_src.ix,dim)];
		p2 = &((BASE_TYPE*)h_dest.offset)[get_seq_from_ix(dest_ix,h_dest.ix,dim)];
		*p2 = *p1;
		if ( inc_ix(src_ix,rep,src_inc,h_src.ix,dim) )
			break;
	}
	d_f_ree(src_ix);
	d_f_ree(dest_ix);
	d_f_ree(src_inc);
	d_f_ree(ofs);
	return 0;
}




int
mxt_int32_thined_avg(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int parent,void * dest,void * src)
{
MATRIX_DH_SET h_src;
MATRIX_DH_SET h_dest;
INTEGER64 lev;
int i;
int _ofs;
int * ofs;
int * src_ix,* dest_ix, * avg_ix,* avg_size;
int * src_inc,* dest_inc;
BASE_TYPE * p1, * p2;
int dim;
int avg;
int n_size;
int _p;
	get_matrix_dh_set(&h_src,src);
	get_matrix_dh_set(&h_dest,dest);
	if ( h_src.hd->dim != m->p.dim )
		return -1;
	if ( h_dest.hd->dim != m->p.dim )
		return -1;
	lev = dim_code[0];
	if ( lev <= 0 )
		return -1;
	ofs = d_alloc(sizeof(int)*m->p.dim);
	for ( i = 0 ; i < m->p.dim ; i ++ ) {
		_p = m->dim_divide[i]*parent;
		if ( m->block_size[i] > _p ) {
			_ofs = 1<<(m->block_size[i] - _p);
			ofs[i] = _ofs * ((dim_code[i+1] >> 
					(lev * m->dim_divide[i] + m->block_size[i]))
				& ((1<<m->dim_divide[i]*parent)-1));
		}
	}
	dim = m->p.dim;
	src_ix = d_alloc(sizeof(int)*dim);
	dest_ix = d_alloc(sizeof(int)*dim);
	src_inc = d_alloc(sizeof(int)*dim);
	dest_inc = d_alloc(sizeof(int)*dim);
	avg_ix = d_alloc(sizeof(int)*dim);
	avg_size = d_alloc(sizeof(int)*dim);
	n_size = 1;
	for ( i = 0 ; i < dim ; i ++ ) {
		src_ix[i] = 0;
		src_inc[i] = 1<<(m->dim_divide[i]*parent);
		n_size *= src_inc[i];
		dest_inc[i] = 1;
		dest_ix[i] = ofs[i];
	}
	for ( ; ; ) {
		memcpy(avg_ix,src_ix,sizeof(int)*dim);
		avg = 0;
		for ( i = 0 ; i < dim ; i ++ ) {
			avg_size[i] = src_ix[i] + src_inc[i];
			dest_ix[i] = src_ix[i]>>(m->dim_divide[i]*parent);
		}
		for ( ; ; ) {
			p1 = &((BASE_TYPE*)h_src.offset)[get_seq_from_ix(avg_ix,h_src.ix,dim)];
			avg += *p1;
			if ( inc_ix(avg_ix,src_ix,dest_inc,avg_size,dim) )
				break;
		}
		p2 = &((BASE_TYPE*)h_dest.offset)[get_seq_from_ix(dest_ix,h_dest.ix,dim)];
		*p2 = avg/n_size;
		if ( inc_ix(src_ix,0,src_inc,h_src.ix,dim) )
			break;
	}
	d_f_ree(src_ix);
	d_f_ree(dest_ix);
	d_f_ree(src_inc);
	d_f_ree(dest_inc);
	d_f_ree(ofs);
	d_f_ree(avg_ix);
	d_f_ree(avg_size);
	return 0;
}


int
mxt_int32_add(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int parent,void *a ,void * dest,void * src1,void * src2)
{
MATRIX_DH_SET h_src1,h_src2;
MATRIX_DH_SET h_dest;
INTEGER64 lev;
int i;
int _ofs;
int * ofs;
int * src1_ix, * src2_ix;
int * src1_inc,* src2_inc;
int * target_ix,* target_size;
BASE_TYPE * p1, * p2, * dest_p;
int dim;
int _p;
INTEGER64 result;
char hd_type;
	get_matrix_dh_set(&h_src1,src1);
	get_matrix_dh_set(&h_src2,src2);
	get_matrix_dh_set(&h_dest,dest);
	if ( h_src1.hd->dim != m->p.dim )
		return -1;
	if ( h_src2.hd->dim != m->p.dim )
		return -1;
	if ( h_dest.hd->dim != m->p.dim )
		return -1;
	lev = dim_code[0];
	if ( lev <= 0 )
		return -1;
	ofs = d_alloc(sizeof(int)*m->p.dim);
	for ( i = 0 ; i < m->p.dim ; i ++ ) {
		_p = m->dim_divide[i]*parent;
		if ( m->block_size[i] > _p ) {
			_ofs = 1<<(m->block_size[i] - _p);
			ofs[i] = _ofs * ((dim_code[i+1] >> 
					(lev * m->dim_divide[i] + m->block_size[i]))
				& ((1<<m->dim_divide[i]*parent)-1));
		}
	}
	dim = m->p.dim;
	src1_ix = d_alloc(sizeof(int)*dim);
	src2_ix = d_alloc(sizeof(int)*dim);
	src1_inc = d_alloc(sizeof(int)*dim);
	src2_inc = d_alloc(sizeof(int)*dim);
	target_ix = d_alloc(sizeof(int)*dim);
	target_size = d_alloc(sizeof(int)*dim);
	for ( i = 0 ; i < dim ; i ++ ) {
		src2_ix[i] = 0;
		src2_inc[i] = 1<<(m->dim_divide[i]*parent);
		src1_inc[i] = 1;
		src1_ix[i] = ofs[i];
	}
	hd_type = h_dest.hd->type;
	for ( ; ; ) {
		p1 = &((BASE_TYPE*)h_src1.offset)[get_seq_from_ix(src1_ix,h_src1.ix,dim)];

		memcpy(target_ix,src2_ix,sizeof(int)*dim);
		for ( i = 0 ; i < dim ; i ++ )
			target_size[i] = src2_ix[i] + src2_inc[i];
		for ( ; ; ) {
			p2 = &((BASE_TYPE*)h_src2.offset)
				[get_seq_from_ix(target_ix,h_src2.ix,dim)];
			dest_p = &((BASE_TYPE*)h_dest.offset)
				[get_seq_from_ix(target_ix,h_dest.ix,dim)];
			result = (*p1) + (*p2);
			round_int(hd_type,dest,result,0);
			if ( inc_ix(target_ix,src2_ix,src1_inc,target_size,dim) )
				break;
		}
		if ( inc_ix(src2_ix,0,src2_inc,h_src2.ix,dim) )
			break;
		inc_ix(src1_ix,ofs,src1_inc,h_src1.ix,dim);
	}
	d_f_ree(src1_ix);
	d_f_ree(src2_ix);
	d_f_ree(src1_inc);
	d_f_ree(src2_inc);
	d_f_ree(ofs);
	d_f_ree(target_ix);
	d_f_ree(target_size);
	return 0;
}



int
mxt_int32_sub(struct matrix_data_type * tp,
	MATRIX *m,INTEGER64* dim_code,int parent,void * a,void * dest,void * src1,void * src2)
{
MATRIX_DH_SET h_src1,h_src2;
MATRIX_DH_SET h_dest;
INTEGER64 lev;
int i;
int _ofs;
int * ofs;
int * src1_ix, * src2_ix;
int * src1_inc,* src2_inc;
int * target_ix,* target_size;
BASE_TYPE * p1, * p2, * dest_p;
int dim;
int _p;
INTEGER64 result;
char hd_type;
	get_matrix_dh_set(&h_src1,src1);
	get_matrix_dh_set(&h_src2,src2);
	get_matrix_dh_set(&h_dest,dest);
	if ( h_src1.hd->dim != m->p.dim )
		return -1;
	if ( h_src2.hd->dim != m->p.dim )
		return -1;
	if ( h_dest.hd->dim != m->p.dim )
		return -1;
	lev = dim_code[0];
	if ( lev <= 0 )
		return -1;
	ofs = d_alloc(sizeof(int)*m->p.dim);
	for ( i = 0 ; i < m->p.dim ; i ++ ) {
		_p = m->dim_divide[i]*parent;
		if ( m->block_size[i] > _p ) {
			_ofs = 1<<(m->block_size[i] - _p);
			ofs[i] = _ofs * ((dim_code[i+1] >> 
					(lev * m->dim_divide[i] + m->block_size[i]))
				& ((1<<m->dim_divide[i]*parent)-1));
		}
	}
	dim = m->p.dim;
	src1_ix = d_alloc(sizeof(int)*dim);
	src2_ix = d_alloc(sizeof(int)*dim);
	src1_inc = d_alloc(sizeof(int)*dim);
	src2_inc = d_alloc(sizeof(int)*dim);
	target_ix = d_alloc(sizeof(int)*dim);
	target_size = d_alloc(sizeof(int)*dim);
	for ( i = 0 ; i < dim ; i ++ ) {
		src2_ix[i] = 0;
		src2_inc[i] = 1<<(m->dim_divide[i]*parent);
		src1_inc[i] = 1;
		src1_ix[i] = ofs[i];
	}
	hd_type = h_dest.hd->type;
	for ( ; ; ) {
		p1 = &((BASE_TYPE*)h_src1.offset)[get_seq_from_ix(src1_ix,h_src1.ix,dim)];

		memcpy(target_ix,src2_ix,sizeof(int)*dim);
		for ( i = 0 ; i < dim ; i ++ )
			target_size[i] = src2_ix[i] + src2_inc[i];
		for ( ; ; ) {
			p2 = &((BASE_TYPE*)h_src2.offset)
				[get_seq_from_ix(target_ix,h_src2.ix,dim)];
			dest_p = &((BASE_TYPE*)h_dest.offset)
				[get_seq_from_ix(target_ix,h_dest.ix,dim)];
			result = (*p1) - (*p2);
			round_int(hd_type,dest,result,0);
			if ( inc_ix(target_ix,src2_ix,src1_inc,target_size,dim) )
				break;
		}
		if ( inc_ix(src2_ix,0,src2_inc,h_src2.ix,dim) )
			break;
		inc_ix(src1_ix,ofs,src1_inc,h_src1.ix,dim);
	}
	d_f_ree(src1_ix);
	d_f_ree(src2_ix);
	d_f_ree(src1_inc);
	d_f_ree(src2_inc);
	d_f_ree(ofs);
	d_f_ree(target_ix);
	d_f_ree(target_size);
	return 0;
}





void * 
mxt_add_vv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c)
{
void * ret;
MATRIX_DH_SET ds1,ds2,ret_ds;
BASE_TYPE * p1,* p2, * ret_p;
int i;
MATRIX_ALLOC_VECTOR_PARAM p;
	get_matrix_dh_set(&ds1,d1);
	get_matrix_dh_set(&ds2,d2);
	if ( ds1.tp != tp )
		return 0;
	if ( ds2.tp != tp )
		return 0;
	if ( ds1.hd->dim != ds2.hd->dim )
		return 0;
	for ( i = 0 ; i < ds1.hd->dim ; i ++ )
		if( ds1.ix[i] != ds2.ix[i] )
			return 0;
	p.dim = ds1.hd->dim;
	p.ix_size = ds1.ix;
	p.default_data = 0;
	p.mxc = c;
	ret = mxt_alloc_vector(tp,MD_CALLOC,&p,0);
	get_matrix_dh_set(&ret_ds,ret);

	p1 = ds1.offset;
	p2 = ds2.offset;
	ret_p = ret_ds.offset;
	for ( i = 0 ; i < ds1.total_element ; i ++ )
		ret_p[i] = p1[i] + p2[i];
	return ret;
}


void * 
mxt_sub_vv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c)
{
void * ret;
MATRIX_DH_SET ds1,ds2,ret_ds;
BASE_TYPE * p1,* p2, * ret_p;
int i;
MATRIX_ALLOC_VECTOR_PARAM p;
	get_matrix_dh_set(&ds1,d1);
	get_matrix_dh_set(&ds2,d2);
	if ( ds1.tp != tp )
		return 0;
	if ( ds2.tp != tp )
		return 0;
	if ( ds1.hd->dim != ds2.hd->dim )
		return 0;
	for ( i = 0 ; i < ds1.hd->dim ; i ++ )
		if( ds1.ix[i] != ds2.ix[i] )
			return 0;
	p.dim = ds1.hd->dim;
	p.ix_size = ds1.ix;
	p.default_data = 0;
	p.mxc = c;
	ret = mxt_alloc_vector(tp,MD_CALLOC,&p,0);
	get_matrix_dh_set(&ret_ds,ret);

	p1 = ds1.offset;
	p2 = ds2.offset;
	ret_p = ret_ds.offset;
	for ( i = 0 ; i < ds1.total_element ; i ++ )
		ret_p[i] = p1[i] - p2[i];
	return ret;
}




void * 
mxt_mul_sv_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c)
{
void * ret;
MATRIX_DH_SET ds2,ret_ds;
BASE_TYPE * p2, * ret_p;
int i;
MATRIX_ALLOC_VECTOR_PARAM p;
BASE_TYPE m;

	get_matrix_dh_set(&ds2,d2);
	if ( ds2.tp != tp )
		return 0;
	p.dim = ds2.hd->dim;
	p.ix_size = ds2.ix;
	p.default_data = 0;
	p.mxc = c;
	ret = mxt_alloc_vector(tp,MD_CALLOC,&p,0);
	get_matrix_dh_set(&ret_ds,ret);

	m = *(BASE_TYPE*)d1;

	p2 = ds2.offset;
	ret_p = ret_ds.offset;
	for ( i = 0 ; i < ds2.total_element ; i ++ )
		ret_p[i] = m * p2[i];
	return ret;
}



void * 
mxt_mul_mm_int32(MATRIX_DATA_TYPE * tp,
	void * d1,void *d2,MX_CACHE * c)
{
void * ret;
MATRIX_DH_SET ds1,ds2,ret_ds;
BASE_TYPE * p1,* p2, * ret_p;
int i,j,k;
int dim[2];
MATRIX_ALLOC_VECTOR_PARAM p;
BASE_TYPE acc;
	get_matrix_dh_set(&ds1,d1);
	get_matrix_dh_set(&ds2,d2);
	if ( ds1.tp != tp )
		return 0;
	if ( ds2.tp != tp )
		return 0;
	if ( ds1.hd->dim != ds2.hd->dim )
		return 0;
	if ( ds1.hd->dim != 2 )
		return 0;
	if ( ds1.ix[0] != ds2.ix[1] )
		return 0;

	dim[0] = ds2.ix[0];
	dim[1] = ds1.ix[1];
	p.dim = 2;
	p.ix_size = &dim[0];
	p.default_data = 0;
	p.mxc = c;
	ret = mxt_alloc_vector(tp,MD_CALLOC,&p,0);
	get_matrix_dh_set(&ret_ds,ret);

	p1 = ds1.offset;
	p2 = ds2.offset;
	ret_p = ret_ds.offset;
	for ( i = 0 ; i < dim[0] ; i ++ )
		for ( j = 0 ; j < dim[1] ; j ++ ) {
			acc = 0;
			for ( k = 0 ; k < ds1.ix[0] ; k ++ )
				acc += p1[k + j*ds1.ix[0]] *
					p2[i + k*ds2.ix[0]];
			ret_p[i + j*ret_ds.ix[0]] = acc;
		}

	return ret;
}


void *
mxt_trans_m_int32(MATRIX_DATA_TYPE * tp,void * d1,MX_CACHE * c)
{
void * ret;
MATRIX_DH_SET ds1,ret_ds;
BASE_TYPE * p1, * ret_p;
int i,j;
MATRIX_ALLOC_VECTOR_PARAM p;
int dim[2];
	get_matrix_dh_set(&ds1,d1);
	if ( ds1.tp != tp )
		return 0;
	if ( ds1.hd->dim != 2 )
		return 0;

	dim[0] = ds1.ix[1];
	dim[1] = ds1.ix[0];
	p.dim = 2;
	p.ix_size = &dim[0];
	p.default_data = 0;
	p.mxc = c;
	ret = mxt_alloc_vector(tp,MD_CALLOC,&p,0);
	get_matrix_dh_set(&ret_ds,ret);

	p1 = ds1.offset;
	ret_p = ret_ds.offset;
	for ( i = 0 ; i < dim[0] ; i ++ )
		for ( j = 0 ; j < dim[1] ; j ++ ) {
			ret_p[i + j*ret_ds.ix[0]] =
				p1[j + i*ds1.ix[0]];
		}

	return ret;
}




void
mxt_get_zero_int32(
	MATRIX_DATA_TYPE * tp,
	void * buf)
{
	*(BASE_TYPE*)buf = 0;
}

void
mxt_get_el_int32(
	MATRIX_DATA_TYPE * tp,
	void * buf)
{
	*(BASE_TYPE*)buf = 1;
}


void
mxt_print_int32(MATRIX_DATA_TYPE*tp,MATRIX_STRING_BUFFER*b,void*d,char*fmt)
{
char buffer[1000];
	if ( fmt == 0 ) {
		sprintf(buffer,"%i",*(BASE_TYPE*)d);
	}
	else {
		sprintf(buffer,fmt,*(BASE_TYPE*)d);
	}
	out_matrix_string_buffer(b,buffer);
}


