📄 sclass_change.c
字号:
/********************************************************************************* This file is part of the General Hidden Markov Model Library,* GHMM version 0.8_beta1, see http://ghmm.org** Filename: sclass_change.c* Authors: Benjamin Georgi** Copyright (C) 1998-2004 Alexander Schliep* Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln* Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik,* Berlin** Contact: schliep@ghmm.org** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Library General Public* License as published by the Free Software Foundation; either* version 2 of the License, or (at your option) any later version.** This library 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* Library General Public License for more details.** You should have received a copy of the GNU Library General Public* License along with this library; if not, write to the Free* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*** This file is version $Revision: 1627 $* from $Date: 2006-04-19 12:15:28 +0200 (Wed, 19 Apr 2006) $* last change by $Author: cic99 $.********************************************************************************//* XXX FIXME: breaks out of tree build of ghmmwrapper */#include "../config.h"#include <Python.h>#include <stdio.h>#include <stdlib.h>#include <ghmm/rng.h>#include <ghmm/sequence.h>#include <ghmm/smodel.h>/* smo is a ghmm_cmodel struct seq is a double matrix of observations k is the first current sequence index (corresponding to the rows in seq) t is the second current sequence index (corresponding to seq[k] )*/int cp_class_change( ghmm_cmodel *smo, double* seq, int k, int t) { int res; if((t%2) == 0){ /*if(t < 500){*/ res= 0; } else { res = 1; } printf("cp_class_change with value %d -> return %d\n",t,res); return res;} /* setSwitchingFunction assigns cp_class_change as switching function in ghmm_dmodel smo. Needs to be modified for user defined C switching function.*/void setSwitchingFunction( ghmm_cmodel *smd ) { smd->class_change->get_class = cp_class_change;}/* Implements the Python Callback to the switching function defined in smo->class_change. Arguments ( which are analogue to cp_class_change (s.a.)) are parsed into Python data structures before the call-back.*/int python_class_change( ghmm_cmodel* smo, double *seq, int k, int t ){ char* ModuleName = smo->class_change->python_module; char* FunctionName = smo->class_change->python_function; int class,i; PyObject *pName, *pDict, *pArgs, *pValue, *pList; /* Python module and function are static */ static PyObject *pModule = NULL; static PyObject *pFunc = NULL; /* importing module and function on first function call */ if (pModule == NULL) { printf("C: Importing Python module ... "); pName = PyString_FromString(ModuleName); pModule = PyImport_Import(pName); /* Import module */ if(!pModule) { printf("python_class_change: import error - Module %s.py not found in current paths.\n",ModuleName); return(-1); } pDict = PyModule_GetDict(pModule); printf("done.\n"); /*--- TEST --- printf("Python Module %s.\n",ModuleName); pDict = PyImport_GetModuleDict(); */ /*printf("C: Calling Python with value %d\n",t); */ pFunc = PyDict_GetItemString(pDict, FunctionName); if(!pFunc) { printf("python_class_change: Error - Function %s not found in namespace of module %s.\n",FunctionName,ModuleName); return(-1); } Py_DECREF(pDict); Py_DECREF(pName); } pArgs = PyTuple_New(3); pList = PyList_New(t); for(i=0;i<t;i++){ pValue = PyFloat_FromDouble(seq[i]); PyList_SetItem(pList, i, pValue); } PyTuple_SetItem(pArgs, 0, pList); pValue = PyInt_FromLong((long)k); PyTuple_SetItem(pArgs, 1, pValue); pValue = PyInt_FromLong((long)t); PyTuple_SetItem(pArgs, 2, pValue); pValue = PyObject_CallObject(pFunc, pArgs); // Calling Python /* parsing the result from Python to C data type */ class = PyInt_AsLong(pValue); /*printf("C: The returned class is %d\n",class);*/ /* cleaning up */ Py_DECREF(pArgs); Py_DECREF(pValue); Py_DECREF(pList); return class; }/* Assignment of Python module and function for class change. The values are stored in smo->class_change. smo: ghmm_cmodel struct with multiple transition classes python_module: Name of the module the switching function is defined in python_function: Name of the Python function to be used. IMPORTANT: python_function must have a signature compatible to cp_class_change (that means three arguments: first the sequence (as a Python list), second sequence number, third the time step in the current sequence. See class_change.py in the ghmmwrapper directory for an example.)*/void setPythonSwitching( ghmm_cmodel *smd, char* python_module, char* python_function ){ if(!smd->class_change) { printf("setPythonSwitching ERROR: class_change struct not initialized.\n"); } smd->class_change->python_module = python_module; smd->class_change->python_function = python_function; smd->class_change->get_class = python_class_change ;}/* --------------------------------------------------------------------------------------- *//* The functions below provide an interface to passing arbitrary python objects as class switch functions. Such an object has to fulfill two conditions: 1) it needs to be callable 2) it needs to have the following (or an equivalent) signature: def switchFun(seq,k,t) for a function or def __call__(self,seq,k,t) for a callable object*//* pyCallback holds the global Python callback variable */static PyObject *pyCallback = NULL;/* executePythonCallback carries out the actual function call of the object assigned to pyCallback. Arguments: smo: pointer on the ghmm_cmodel seq: current sequence k: index of current sequence in the sequence set it originated from t: current time step (e.q seq[t] is the current observation) */int executePythonCallback(ghmm_cmodel* smo, double *seq, int k, int t){ int class,i; /*printf("k=%d, t=%d\n",k,t); */ PyObject *pArgs, *pValue, *pList; /* *pDict, *pName, */ pArgs = PyTuple_New(3); pList = PyList_New(t); for(i=0;i<t;i++){ pValue = PyFloat_FromDouble(seq[i]); PyList_SetItem(pList, i, pValue); } PyTuple_SetItem(pArgs, 0, pList); pValue = PyInt_FromLong((long)k); PyTuple_SetItem(pArgs, 1, pValue); pValue = PyInt_FromLong((long)t); PyTuple_SetItem(pArgs, 2, pValue); pValue = PyObject_CallObject(pyCallback, pArgs); // Calling Python /* parsing the result from Python to C data type */ class = PyInt_AsLong(pValue); /*printf("C: The returned class is %d\n",class);*/ if (class == -1) { printf("ERROR: Python exception has been thrown during call-back (class is -1)\n."); abort(); } /* cleaning up */ Py_DECREF(pArgs); Py_DECREF(pValue); Py_DECREF(pList); return class; }/* setPythonCallback assigns the arguement py_cb to the global callback variable and sets the corresponding switching function executePythonCallback in the smodel-class_change context. */void setPythonCallback(ghmm_cmodel *smo, PyObject *py_cb){ pyCallback = py_cb; smo->class_change->get_class = executePythonCallback;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -