/*
* NativeTreeLikelihood.java
*
* Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard
*
* This file is part of BEAST.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* BEAST is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* BEAST 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. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BEAST; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package dr.oldevomodel.indel;
/**
* NativeTreeLikelihood - calls an implementation of HomologyRecursion.treeRecursion in C.
*
* @author Gerton Lunter
*
* 10/9/2003
*
*/
public class NativeTreeLikelihood {
private static boolean isNativeAvailable = false;
private int[][] iSequences; // rest are references to existing arrays
private int iNN;
private int iMUD;
private long iStaticDataHandle;
static {
try {
System.loadLibrary("NativeTreeLikelihood");
System.err.println("Fast TKF91 homology integrator code found");
isNativeAvailable = true;
} catch (UnsatisfiedLinkError e) {
System.err.println("Using Java TKF91 homology integrator code");
}
}
/**
* Constructor
*
*/
public NativeTreeLikelihood() { }
/**
* Hello, anybody?
*
*/
public boolean isAvailable() {
return isNativeAvailable;
}
/**
* Initialisation. Returns with 'handle' (actually a pointer) to static data.
*
*/
private native long nativeInit(int[] iParent, double[] iEquil, double[] iTrans,
double[] iH, double[] iN, double[] iE, double[] iB);
/**
* The actual recursion. 'iSD' is the handle returned by nativeInit.
*
*/
private native double nativeTreeRecursion(int[] iSignature, int[] iColumn, int iNumNucs, int iMUD, long iSD);
/**
* Relinquishes handle.
*
*/
private native void nativeDestruct(long iSD);
/**
* Initialiser
*
*/
public void init(int iNumNucs, int iMaxUnalignDimension, int[] iParent, double[] iEquil, double[][][] iTrans,
int[][] iSequences0,
double[] iN, double[] iH, double[] iE, double[] iB)
{
if (!isNativeAvailable)
return;
// copy data into local variables
iNN = iNumNucs;
iMUD = iMaxUnalignDimension;
iSequences = iSequences0;
// translate iTrans[][][] array into flat array
int iNumNodes = iTrans.length;
double[] iFlatTrans = new double[ iNN*iNN*iNumNodes ];
for (int i=0; i<iNumNodes; i++) {
for (int j=0; j<iNN; j++) {
for (int k=0; k<iNN; k++) {
iFlatTrans[ k + iNN*( j + iNN*i ) ] = iTrans[i][j][k];
}
}
}
// store data someplace where the C code has fast access
iStaticDataHandle = nativeInit(iParent, iEquil, iFlatTrans, iH, iN, iE, iB);
}
/**
* Make sure that memory is released when this object is garbage collected
*
*/
protected void finalize() throws Throwable {
if (iStaticDataHandle != 0) {
nativeDestruct( iStaticDataHandle );
}
super.finalize();
}
/**
* Actual front-end for HomologyRecursion
*
*/
public double treeRecursion(IntMathVec iSignature, IntMathVec iPos)
{
int[] iColumn = new int[ iSignature.iV.length ];
for (int i=0; i<iSignature.iV.length; i++) {
if (iSignature.iV[i] != 0)
iColumn[i] = iSequences[i][iPos.iV[i]];
}
return nativeTreeRecursion(iSignature.iV,
iColumn,
iNN,
iMUD,
iStaticDataHandle);
}
}