/* * mp_MLR * * Author: Andrew Salamon * Date: Tue Jan 30 2007 * * Copyright (c) 2007 Machine Perception Laboratory * University of California San Diego. * */ //#include //#include #include #include #include #include #include #ifdef WIN32 extern "C" { #ifdef INTELMKL #include "mkl_cblas.h" #else #include "cblas.h" #endif } #else #include #endif #include "mp_MLR.h" /** Load the BHAT weights, which could throw an exception. */ mp_MLR::mp_MLR( const std::string &BHAT_Filename, inputAUVector &_inputs ) : bhat(BHAT_Filename), inputs(_inputs) { assert( inputs.size() == bhat.getCount() ); } mp_MLR::~mp_MLR() { } /* The MLR calculation. * Get the 72 frequency data points for each AU (as determined by the inputs member), * place them in a single flat vector one after the other. * Multiply the frequencies by BHAT (a (72*#AU's+1) x 2 matrix). * Take the exponent of each of the resulting values. */ double mp_MLR::MLR( std::map< std::string, mp_AUResults > &AUResults ) { std::vector freqs; for( inputAUVector::const_iterator iter = inputs.begin(), last = inputs.end(); iter != last; ++iter ) { // Make sure the category we need is in the results map. if( AUResults.find( iter->first ) != AUResults.end() ) { mp_AUResults &oneCat = AUResults[ iter->first ]; std::vector aFreq = oneCat.frequenciesForAUIndex( iter->second ); freqs.insert( freqs.end(), aFreq.begin(), aFreq.end() ); } else { // Otherwise there's nothing we can do std::string msg = "Missing required category data: " + iter->first; throw std::logic_error(msg); } } double *freqAccess = &(freqs[0]); std::vector res = multiplyBhat_X( bhat.getWeights(), freqAccess, inputs.size() ); // res[0] /= 72; // The typedef is needed to get this to compile under Windows. // typedef double (*expType) (double); // std::transform( res.begin(), res.end(), res.begin(), static_cast(std::exp) ); // calculate the exponent of each element return res[0]; } std::vector mp_MLR::multiplyBhat_X( const double *bhat, const double *X, inputAUVector::size_type auCount ) { const unsigned int count = 1; double tmpYhat[count]; for( unsigned int i=0; i < count; ++i ) { tmpYhat[i] = 0.0; } double alpha = 1.0; double beta = 0.0; int n = count; int m = (auCount * 72); // 217; ///< Number of AU's times 72 frequencies each (ni*mu) plus one extra int lda = n; int incX = 1; // No idea what this is for int incY = 1; // No idea what this is for // see http://www.netlib.org/clapack/cblas/dgemm.c for details cblas_dgemv( CblasRowMajor, CblasTrans, m, n, alpha, bhat, lda, X, incX, beta, tmpYhat, incY); return std::vector( tmpYhat, tmpYhat+count ); } /* * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */