scalaで配列のランダムシャッフル c++の関数の利用

JNAを使ってc++のシャッフル関数と連携.
c_shuff_test.scala

import com.sun.jna.Library;
import com.sun.jna.Native;

import com.sun.jna.NativeLibrary;


object c_shuff_test{



        def main(args: Array[String]): Unit={

                val lib=NativeLibrary.getInstance("shuffle.dll");
                val func=lib.getFunction("shuff_array");
                var a=Array(1.0,2.0,3.0);

 
                var f12=func.invoke(Array(a,a.length.asInstanceOf[java.lang.Integer]));
                a.foreach{println;}


        }





}

shuffle.cpp

#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class Random
{
public:
  
        Random()
        {
               // 初期化しすぎるとおかしくなる 1秒に一度しかシードかわらないので
               // srand( static_cast<unsigned int>( time(NULL) ) );
        }


        unsigned int operator()(unsigned int max)
        {
                double tmp = static_cast<double>( rand() ) / static_cast<double>( RAND_MAX );
                return static_cast<unsigned int>( tmp * max );
        }
};

extern "C" void* shuff_array(double* v,int n)
{      
        int i;

        Random r;
        random_shuffle(&v[0],  &v[n], r );  // ランダムシャッフル

};


shuffle.h

#ifndef shuffle
#define shuffle


#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stdio.h>
using namespace std;

        extern "C" void shuff_array(double* v,int n);


#endif
compile.sh

コンパイルスクリプトc++

filename=$1;
filename=`basename $filename .cpp`
filename2=`basename $2 .cpp`

echo $filename;
echo $filename2;

x86_64-w64-mingw32-g++ -c $filename.cpp -static-libstdc++ -static-libgcc
echo "test"
x86_64-w64-mingw32-g++ -shared -o $filename.dll $filename.o -static-libstdc++ -static-libgcc

echo "test2";
x86_64-w64-mingw32-g++ $filename2.cpp -o $filename2.out -L. -l$filename -static-libstdc++ -static-libgcc

コンパイル c++

sh compile.sh shuffle.cpp random_shuffle.cpp

コンパイル scala

scalac -cp jna.jar c_shuff_test.scala

実行 (コンソールで)

scala c_shuff_test

実行結果

2.0
3.0
1.0


メルセンヌツイタ版 mainの部分は実験用,消す。
また,mt19937ar.cのメインの部分も消しておく

wget http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c

#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <time.h>
#include "mt19937ar.c"

using namespace std;

class Random
{
public:
        // コンストラクタ
        Random()
        {
//              srand((unsigned)( time(NULL) ) );
//              init_genrand((unsigned)time(NULL));
//              printf("%ld\n",(unsigned)(time(NULL)));
//              cout << time(NULL) << "\n";
        }

        // 関数オブジェクト
        unsigned int operator()(unsigned int max)
        {
//              double tmp = static_cast<double>( rand() ) / static_cast<double>( RAND_MAX );
//              printf("%d\n",max);
//
                double tmp = static_cast<double>( genrand_real2() );
                return static_cast<unsigned int>( tmp * max );
        }
};

extern "C" void* shuff_array(double* v,int n)
{       //int n;
        int i;

        Random r;
        random_shuffle(&v[0],  &v[n], r );  // ランダムシャッフル

//      random_shuffle(&v[0],  &v[n] );  // ランダムシャッフル
//      double *a= &nums[0];
};

int main(){
        double a[4]={1.0,2.0,3.0,4.0};
        int i;
        int t;
        for(t=0;t<=10000;t++){

//              srand( static_cast<unsigned int>( time(NULL) ) );
                a[0]=1.0;
                a[1]=2.0;
                a[2]=3.0;
                a[3]=4.0;
                shuff_array(a,4);
                for(i=0;i<4;i++){
                        cout << a[i] <<"," ;
                }

                cout<<"\n";
        }
        return 0;
}