Multi-way arrays
In many situations when designing statistical software, the number of variables a dis-crete distribution will have is not known in advance (at compilation time). There existsa need to generate discrete multidimensional distributions on the fly.
Multi-way arraysOne obvious way to store these multidimensional probabilities is to put them in a multi-way array. Let us say that we want to create a one-dimensional array with four elementsof type double using Java. This is easily done asdouble[] X = new double[4];To declare and create a 2x3-matrix and a 4x3x3-dimensional array with elements of typedouble one can writedouble[][]X = new double[2][3];double[][][] Y = new double[4][3][3];In Java, which has zero-based indices on arrays, Y[1][0][2] refers to the elementwith at position(one-based) in the multi-way array .This is no problem at all, but these examples deals with situations when the rank (num-ber of dimensions) of an array is known at compilation time. But what if one wants tocreate an array with rankat run-time? In programming languages such as Java, Cand Pascal, there is no easy way to do it. Just think about it and consider the followingdesperate attempt§ ¦double[][]...[] X = new double[2][4]...[6];
An easy way around this problem is to use the vec-operator. The vec-operator is anoperator that takes a multi-way array, e.g. a matrix, and puts the elements in a columnvector. In the case of a matrix the columns are stacked on top of each other creating acolumn vector.
这里我只在类里实现了两种数据结构间坐标的转换
#pragma once using namespace std; class multi_array { protected: int rank; int *base; int *shape; int *node_i; //coordinate of each node int value; public: multi_array( int new_rank, int *new_shape ); multi_array( int new_value ); ~multi_array( void ); int get_rank(); int *get_shape(); int *get_base(); int *get_node_i(); int get_index_vector( int *node_index ); void get_i( int index ); };
#include "multi_array.h"
#include <iostream>
using namespace std;
multi_array::multi_array( int new_rank, int *new_shape )
{
rank = new_rank;
shape = new int[rank];
base = new int[rank];
node_i = new int[rank];
int i;
for ( i = 0; i < rank; ++i )
{
*( shape + i ) = *( new_shape + i );
}
for ( i = 0; i < rank; ++i )
{
if ( 0 == i )
*base = 1;
else
*( base + i ) = *( base + i - 1 ) * (*( shape + i - 1 ));
}
for ( i = 0; i < rank; ++i )
{
*( node_i + i ) = 0;
}
}
multi_array::multi_array( int new_value )
{
value = new_value;
}
multi_array::~multi_array( void )
{
delete[] shape;
delete[] base;
}
/* get the rank */
int multi_array::get_rank()
{
return rank;
}
/* get the shape */
int* multi_array::get_shape()
{
return shape;
}
/* get the base */
int* multi_array::get_base()
{
return base;
}
/* get the i */
int *multi_array::get_node_i()
{
return node_i;
}
/* get the index_vector */
int multi_array::get_index_vector( int *node_index )
{
//node_i = new int[ rank ];
int i, temp = 1;
for ( i = 0; i < rank; ++i )
{
*( node_i + i ) = *( node_index + i );
}
for ( i = 0; i < rank; ++i )
{
temp += (*( node_i + i ) - 1) * (*( base + i ));
}
delete[] node_i;
return temp;
}
/* get the i of each rank */
void multi_array::get_i( int index )
{
for ( int i = 0; i < rank; ++i )
{
if ( i == (rank - 1) )
{
*( base + i + 1 ) = ( *( base + i ) ) * ( *( shape + i ) );
}
/* just for debug */
//cout << *( base + i ) << " " << *( base + i + 1 ) << endl;
*( node_i + i ) = 1 + ( ( index - 1 ) % (*( base + i + 1)) ) / (*(base + i )) ;
}
}
我写的一个例子
#include "multi_array.h"
#include <iostream>
using namespace std;
int main( void )
{
int a[] = { 4, 3, 3 };
//multi_array newarray = new multi_array;
multi_array newarray( 3, a );
/*for ( int i = 0 ; i < 3; ++i )
{
cout << *( newarray.get_base() + i ) << endl;
}*/
/*int b[] = { 1, 3, 2 };
cout << newarray.get_index_vector( b ) << endl;*/
newarray.get_i( 21 );
for ( int i = 0; i < 3; i++ )
cout << *( newarray.get_node_i() + i ) << endl;
return 0;
}