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 );

};

View Code
#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 )) ;
}

}

我写的一个例子

View Code
#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;
}

posted @ 2011-05-12 09:40  lxgeek  阅读(346)  评论(0编辑  收藏  举报