I'm trying to build a C mex file in Matlab. The C compiler is Microsoft Visual C++ 2012, and I'm using Matlab R2014a. Here's the exact command I used:
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c'
Here's the error message:
Building with 'Microsoft Visual C++ 2012 (C)'.
> Building with 'Microsoft Visual C++ 2012 (C)'. Error using mex
> Creating library DynamicProgrammingQ2.lib and object
> DynamicProgrammingQ2.exp DynamicProgrammingQ2.obj : error LNK2019:
> unresolved external symbol dp_costs referenced in function mexFunction
> DynamicProgrammingQ2.obj : error LNK2019: unresolved external symbol
> dp_build_gamma referenced in function mexFunction
> DynamicProgrammingQ2.obj : error LNK2019: unresolved external symbol
> dp_all_indexes referenced in function mexFunction
> DynamicProgrammingQ2.mexw64 : fatal error LNK1120: 3 unresolved
> externals
Here's the C code:
#include "mex.h"
#include <math.h>
#include "dp_grid.h"
/* Signature:
* function [G T] = dp_mex( Q1, T1, Q2, T2, tv1, tv2 )
* Arguments are checked in dp.m, not here. */
void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]){
double *Q1 = 0;
double *T1 = 0;
double *Q2 = 0;
double *T2 = 0;
double *lam1 = 0;
double lam;
int nsamps1;
int nsamps2;
double *tv1 = 0;
double *tv2 = 0;
int *idxv1 = 0;
int *idxv2 = 0;
int ntv1;
int ntv2;
double *G = 0;
double *T = 0;
int Gsize;
int dim = 0;
double *E = 0; /* E[ntv1*j+i] = cost of best path to (tv1[i],tv2[j]) */
int *P = 0; /* P[ntv1*j+i] = predecessor of (tv1[i],tv2[j]) along best path */
double m, rootm;
int sr, sc; /* source row and column index */
int tr, tc; /* target row and column index */
int Galloc_size;
double *pres;
/* [G T dist] = dp_mex( Q1, T1, Q2, T2, tv1, tv2 ); */
Q1 = mxGetPr( prhs[0] );
T1 = mxGetPr( prhs[1] );
Q2 = mxGetPr( prhs[2] );
T2 = mxGetPr( prhs[3] );
tv1 = mxGetPr( prhs[4] );
tv2 = mxGetPr( prhs[5] );
lam1 = mxGetPr( prhs[6] );
lam = *lam1;
dim = mxGetM( prhs[0] );
nsamps1 = mxGetN( prhs[1] ); /* = columns(T1) = columns(Q1)+1 */
nsamps2 = mxGetN( prhs[3] ); /* = columns(T2) = columns(Q2)+1 */
ntv1 = mxGetN( prhs[4] );
ntv2 = mxGetN( prhs[5] );
Galloc_size = ntv1>ntv2 ? ntv1 : ntv2;
if ( !(idxv1=(int*)mxMalloc(ntv1*sizeof(int))) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate idxv1" );
goto cleanup;
}
if ( !(idxv2=(int*)mxMalloc(ntv2*sizeof(int))) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate idxv2" );
goto cleanup;
}
if ( !(E=(double*)mxMalloc(ntv1*ntv2*sizeof(double))) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate E" );
goto cleanup;
}
if ( !(P=(int*)mxCalloc(ntv1*ntv2,sizeof(int))) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate P" );
goto cleanup;
}
if ( !(plhs[0]=mxCreateDoubleMatrix(1,Galloc_size,mxREAL)) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleMatrix failed" );
goto cleanup;
}
if ( !(plhs[1]=mxCreateDoubleMatrix(1,Galloc_size,mxREAL)) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleMatrix failed" );
goto cleanup;
}
if ( !(plhs[2]=mxCreateDoubleScalar(0.0)) )
{
mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleScalar failed" );
goto cleanup;
}
G = mxGetPr( plhs[0] );
T = mxGetPr( plhs[1] );
pres = mxGetPr( plhs[2] );
/* dp_costs() needs indexes for gridpoints precomputed */
dp_all_indexes( T1, nsamps1, tv1, ntv1, idxv1 );
dp_all_indexes( T2, nsamps2, tv2, ntv2, idxv2 );
/* Compute cost of best path from (0,0) to every other grid point */
*pres = dp_costs( Q1, T1, nsamps1, Q2, T2, nsamps2,
dim, tv1, idxv1, ntv1, tv2, idxv2, ntv2, E, P, lam );
/* Reconstruct best path from (0,0) to (1,1) */
Gsize = dp_build_gamma( P, tv1, ntv1, tv2, ntv2, G, T );
mxSetN( plhs[0], Gsize );
mxSetN( plhs[1], Gsize );
cleanup:
if ( idxv1 ) mxFree( idxv1 );
if ( idxv2 ) mxFree( idxv2 );
if ( E ) mxFree( E );
if ( P ) mxFree( P );
}
Here's the header files:
#ifndef DP_GRID_H
#define DP_GRID_H 1
/**
* Computes weights of all edges in the DP matching graph,
* which is needed for the Floyd-Warshall all-pairs shortest-path
* algorithm.
*
* The matrix of edge weights E must be allocated ahead of time by
* the caller. E is an ntv1 x ntv2 x ntv1 x ntv2 matrix. If i and k
* are column indices and j and l are row indices, then the weight of the
* edge from gridpoint (tv1[i],tv2[j]) to gridpoint (tv1[k],tv2[l]) is
* stored in E(j,i,l,k) when this function returns.
* Mapping:
* (j,i,l,k) :--> j*ntv1*ntv2*ntv1 +
* i*ntv2*ntv1 +
* l*ntv1 +
* k
*
* \param Q1 values of the first SRVF
* \param T1 changepoint parameters of the first SRVF
* \param nsamps1 the length of T1
* \param Q2 values of the second SRVF
* \param T2 changepoint parameters of the second SRVF
* \param nsamps2 the length of T2
* \param dim dimension of the ambient space
* \param tv1 the Q1 (column) parameter values for the DP grid
* \param idxv1 Q1 indexes for tv1, as computed by \c dp_all_indexes()
* \param ntv1 the length of tv1
* \param tv2 the Q2 (row) parameter values for the DP grid
* \param idxv2 Q2 indexes for tv2, as computed by \c dp_all_indexes()
* \param ntv2 the length of tv2
* \param E [output] pointer to the edge weight matrix. Must already be
* allocated, with size (ntv1*ntv2)^2.
*/
void dp_all_edge_weights(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double *tv1, int *idxv1, int ntv1,
double *tv2, int *idxv2, int ntv2,
double *W, double lam );
/**
* Computes cost of best path from (0,0) to all other gridpoints.
*
* \param Q1 values of the first SRVF
* \param T1 changepoint parameters of the first SRVF
* \param nsamps1 the length of T1
* \param Q2 values of the second SRVF
* \param T2 changepoint parameters of the second SRVF
* \param nsamps2 the length of T2
* \param dim dimension of the ambient space
* \param tv1 the Q1 (column) parameter values for the DP grid
* \param idxv1 Q1 indexes for tv1, as computed by \c dp_all_indexes()
* \param ntv1 the length of tv1
* \param tv2 the Q2 (row) parameter values for the DP grid
* \param idxv2 Q2 indexes for tv2, as computed by \c dp_all_indexes()
* \param ntv2 the length of tv2
* \param E [output] on return, E[ntv2*i+j] holds the cost of the best
* path from (0,0) to (tv1[i],tv2[j]) in the grid.
* \param P [output] on return, P[ntv2*i+j] holds the predecessor of
* (tv1[i],tv2[j]). If predecessor is (tv1[k],tv2[l]), then
* P[ntv2*i+j] = k*ntv2+l.
* \return E[ntv1*ntv2-1], the cost of the best path from (tv1[0],tv2[0])
* to (tv1[ntv1-1],tv2[ntv2-1]).
*/
double dp_costs(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double *tv1, int *idxv1, int ntv1,
double *tv2, int *idxv2, int ntv2,
double *E, int *P, double lam );
/**
* Computes the weight of the edge from (a,c) to (b,d) in the DP grid.
*
* \param Q1 values of the first SRVF
* \param T1 changepoint parameters of the first SRVF
* \param nsamps1 the length of T1
* \param Q2 values of the second SRVF
* \param T2 changepoint parameters of the second SRVF
* \param nsamps2 the length of T2
* \param dim dimension of the ambient space
* \param a source Q1 parameter
* \param b target Q1 parameter
* \param c source Q2 parameter
* \param d target Q2 parameter
* \param aidx index such that Q1[aidx] <= a < Q1[aidx+1]
* \param cidx index such that Q2[cidx] <= c < Q2[cidx+1]
*/
double dp_edge_weight(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double a, double b,
double c, double d,
int aidx, int cidx, double lam );
/**
* Given predecessor table P, builds the piecewise-linear reparametrization
* function gamma.
*
* G and T must already be allocated with size max(ntv1,ntv2). The actual
* number of points on gamma will be the return value.
*
* \param P P[ntv2*i+j] holds the predecessor of (tv1[i],tv2[j]). If
* predecessor is (tv1[k],tv2[l]), then P[ntv2*i+j] = k*ntv2+l.
* \param tv1 the Q1 (column) parameter values for the DP grid
* \param ntv1 the length of tv1
* \param tv2 the Q2 (row) parameter values for the DP grid
* \param ntv2 the length of tv2
* \param G [output] reparametrization function values
* \param T [output] reparametrization changepoint parameters
* \return the length of G (same as length of T).
*/
int dp_build_gamma(
int *P,
double *tv1, int ntv1,
double *tv2, int ntv2,
double *G, double *T );
/**
* Given t in [0,1], return the integer i such that t lies in the interval
* [T[i],T[i+1]) (or returns n-2 if t==T[n-1]).
*
* \param T an increasing sequence
* \param n the length of T
* \param t the parameter value to lookup ( T[0] <= t <= T[n-1] ).
* \return the integer i such that t lies in the interval [T[i],T[i+1])
* (or n-2 if t==T[n-1]).
*/
int dp_lookup( double *T, int n, double t );
/**
* 1-D table lookup for a sorted array of query points.
*
* Given a partition p and an increasing sequence of numbers tv between
* p[0] and p[np-1], computes the sequence of indexes idxv such that for
* i=0,...,ntv-1, p[idxv[i]] <= tv[i] < p[idxv[i]+1]. If tv[i]==p[np-1],
* then idxv[i] will be set to np-2.
*
* \param p an increasing sequence (the table)
* \param np the length of \a p
* \param tv an increasing sequence (the query points)
* \param ntv the length of \a tv
* \param idxv [output] pre-allocated array of \a ntv ints to hold result
*/
void dp_all_indexes( double *p, int np, double *tv, int ntv, int *idxv );
#endif /* DP_GRID_H */
and
#ifndef DP_NBHD_H
#define DP_NBHD_H 1
#ifndef DP_NBHD_DIM
#define DP_NBHD_DIM 7
#endif
#if DP_NBHD_DIM == 17
int dp_nbhd[][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 },
{ 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, { 1, 15 }, { 1, 16 }, { 1, 17 }, { 2, 1 }, { 2, 3 }, { 2, 5 },
{ 2, 7 }, { 2, 9 }, { 2, 11 }, { 2, 13 }, { 2, 15 }, { 2, 17 }, { 3, 1 }, { 3, 2 }, { 3, 4 }, { 3, 5 },
{ 3, 7 }, { 3, 8 }, { 3, 10 }, { 3, 11 }, { 3, 13 }, { 3, 14 }, { 3, 16 }, { 3, 17 }, { 4, 1 }, { 4, 3 },
{ 4, 5 }, { 4, 7 }, { 4, 9 }, { 4, 11 }, { 4, 13 }, { 4, 15 }, { 4, 17 }, { 5, 1 }, { 5, 2 }, { 5, 3 },
{ 5, 4 }, { 5, 6 }, { 5, 7 }, { 5, 8 }, { 5, 9 }, { 5, 11 }, { 5, 12 }, { 5, 13 }, { 5, 14 }, { 5, 16 },
{ 5, 17 }, { 6, 1 }, { 6, 5 }, { 6, 7 }, { 6, 11 }, { 6, 13 }, { 6, 17 }, { 7, 1 }, { 7, 2 }, { 7, 3 },
{ 7, 4 }, { 7, 5 }, { 7, 6 }, { 7, 8 }, { 7, 9 }, { 7, 10 }, { 7, 11 }, { 7, 12 }, { 7, 13 }, { 7, 15 },
{ 7, 16 }, { 7, 17 }, { 8, 1 }, { 8, 3 }, { 8, 5 }, { 8, 7 }, { 8, 9 }, { 8, 11 }, { 8, 13 }, { 8, 15 },
{ 8, 17 }, { 9, 1 }, { 9, 2 }, { 9, 4 }, { 9, 5 }, { 9, 7 }, { 9, 8 }, { 9, 10 }, { 9, 11 }, { 9, 13 },
{ 9, 14 }, { 9, 16 }, { 9, 17 }, { 10, 1 }, { 10, 3 }, { 10, 7 }, { 10, 9 }, { 10, 11 }, { 10, 13 }, { 10, 17 },
{ 11, 1 }, { 11, 2 }, { 11, 3 }, { 11, 4 }, { 11, 5 }, { 11, 6 }, { 11, 7 }, { 11, 8 }, { 11, 9 }, { 11, 10 },
{ 11, 12 }, { 11, 13 }, { 11, 14 }, { 11, 15 }, { 11, 16 }, { 11, 17 }, { 12, 1 }, { 12, 5 }, { 12, 7 }, { 12, 11 },
{ 12, 13 }, { 12, 17 }, { 13, 1 }, { 13, 2 }, { 13, 3 }, { 13, 4 }, { 13, 5 }, { 13, 6 }, { 13, 7 }, { 13, 8 },
{ 13, 9 }, { 13, 10 }, { 13, 11 }, { 13, 12 }, { 13, 14 }, { 13, 15 }, { 13, 16 }, { 13, 17 }, { 14, 1 }, { 14, 3 },
{ 14, 5 }, { 14, 9 }, { 14, 11 }, { 14, 13 }, { 14, 15 }, { 14, 17 }, { 15, 1 }, { 15, 2 }, { 15, 4 }, { 15, 7 },
{ 15, 8 }, { 15, 11 }, { 15, 13 }, { 15, 14 }, { 15, 16 }, { 15, 17 }, { 16, 1 }, { 16, 3 }, { 16, 5 }, { 16, 7 },
{ 16, 9 }, { 16, 11 }, { 16, 13 }, { 16, 15 }, { 16, 17 }, { 17, 1 }, { 17, 2 }, { 17, 3 }, { 17, 4 }, { 17, 5 },
{ 17, 6 }, { 17, 7 }, { 17, 8 }, { 17, 9 }, { 17, 10 }, { 17, 11 }, { 17, 12 }, { 17, 13 }, { 17, 14 }, { 17, 15 },
{ 17, 16 }, };
#define DP_NBHD_COUNT 191
#elif DP_NBHD_DIM == 12
int dp_nbhd[][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 },
{ 1, 11 }, { 1, 12 }, { 2, 1 }, { 2, 3 }, { 2, 5 }, { 2, 7 }, { 2, 9 }, { 2, 11 }, { 3, 1 }, { 3, 2 },
{ 3, 4 }, { 3, 5 }, { 3, 7 }, { 3, 8 }, { 3, 10 }, { 3, 11 }, { 4, 1 }, { 4, 3 }, { 4, 5 }, { 4, 7 },
{ 4, 9 }, { 4, 11 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 6 }, { 5, 7 }, { 5, 8 }, { 5, 9 },
{ 5, 11 }, { 5, 12 }, { 6, 1 }, { 6, 5 }, { 6, 7 }, { 6, 11 }, { 7, 1 }, { 7, 2 }, { 7, 3 }, { 7, 4 },
{ 7, 5 }, { 7, 6 }, { 7, 8 }, { 7, 9 }, { 7, 10 }, { 7, 11 }, { 7, 12 }, { 8, 1 }, { 8, 3 }, { 8, 5 },
{ 8, 7 }, { 8, 9 }, { 8, 11 }, { 9, 1 }, { 9, 2 }, { 9, 4 }, { 9, 5 }, { 9, 7 }, { 9, 8 }, { 9, 10 },
{ 9, 11 }, { 10, 1 }, { 10, 3 }, { 10, 7 }, { 10, 9 }, { 10, 11 }, { 11, 1 }, { 11, 2 }, { 11, 3 }, { 11, 4 },
{ 11, 5 }, { 11, 6 }, { 11, 7 }, { 11, 8 }, { 11, 9 }, { 11, 10 }, { 11, 12 }, { 12, 1 }, { 12, 5 }, { 12, 7 },
{ 12, 11 } };
#define DP_NBHD_COUNT 91
#elif DP_NBHD_DIM == 10
int dp_nbhd[][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 },
{ 2, 1 }, { 2, 3 }, { 2, 5 }, { 2, 7 }, { 2, 9 }, { 3, 1 }, { 3, 2 }, { 3, 4 }, { 3, 5 }, { 3, 7 },
{ 3, 8 }, { 3, 10 }, { 4, 1 }, { 4, 3 }, { 4, 5 }, { 4, 7 }, { 4, 9 }, { 5, 1 }, { 5, 2 }, { 5, 3 },
{ 5, 4 }, { 5, 6 }, { 5, 7 }, { 5, 8 }, { 5, 9 }, { 6, 1 }, { 6, 5 }, { 6, 7 }, { 7, 1 }, { 7, 2 },
{ 7, 3 }, { 7, 4 }, { 7, 5 }, { 7, 6 }, { 7, 8 }, { 7, 9 }, { 7, 10 }, { 8, 1 }, { 8, 3 }, { 8, 5 },
{ 8, 7 }, { 8, 9 }, { 9, 1 }, { 9, 2 }, { 9, 4 }, { 9, 5 }, { 9, 7 }, { 9, 8 }, { 9, 10 }, { 10, 1 },
{ 10, 3 }, { 10, 7 }, { 10, 9 } };
#define DP_NBHD_COUNT 63
#elif DP_NBHD_DIM == 7
int dp_nbhd[][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 2, 1 }, { 2, 3 }, { 2, 5 },
{ 2, 7 }, { 3, 1 }, { 3, 2 }, { 3, 4 }, { 3, 5 }, { 3, 7 }, { 4, 1 }, { 4, 3 }, { 4, 5 }, { 4, 7 },
{ 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 6 }, { 5, 7 }, { 6, 1 }, { 6, 5 }, { 6, 7 }, { 7, 1 },
{ 7, 2 }, { 7, 3 }, { 7, 4 }, { 7, 5 }, { 7, 6 }, };
#define DP_NBHD_COUNT 35
#else
int dp_nbhd[][2] = {
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 2, 1 }, { 2, 3 }, { 2, 5 }, { 3, 1 },
{ 3, 2 }, { 3, 4 }, { 3, 5 }, { 4, 1 }, { 4, 3 }, { 4, 5 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 },
{ 5, 6 }, { 6, 1 }, { 6, 5 }, };
#define DP_NBHD_COUNT 23
#endif /* DP_NBHD_DIM */
#endif /* DP_NBHD_H */
Also here is one more C file:
#include <stdio.h>
#include <math.h>
#include "dp_nbhd.h"
#include "dp_grid.h"
void dp_all_edge_weights(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double *tv1, int *idxv1, int ntv1,
double *tv2, int *idxv2, int ntv2,
double *W, double lam )
{
int sr, sc; /* source row and column */
int tr, tc; /* target row and column */
int l1, l2, l3; /* for multidimensional array mapping */
int i;
for ( i=0; i<ntv1*ntv2*ntv1*ntv2; W[i++]=1e6 );
/* W is a ntv2 x ntv1 x ntv2 x ntv1 array.
* Weight of edge from (tv1[i],tv2[j]) to (tv1[k],tv2[l])
* (Cartesian coordinates) is in grid(j,i,l,k).
* Mapping:
* (j,i,l,k) :--> j*ntv1*ntv2*ntv1 +
* i*ntv2*ntv1 +
* l*ntv1 +
* k
*/
l1 = ntv1 * ntv2 * ntv1;
l2 = ntv2 * ntv1;
l3 = ntv1;
for ( tr=1; tr<ntv2; ++tr )
{
for ( tc=1; tc<ntv1; ++tc )
{
for ( i=0; i<DP_NBHD_COUNT; ++i )
{
sr = tr - dp_nbhd[i][0];
sc = tc - dp_nbhd[i][1];
if ( sr < 0 || sc < 0 ) continue;
/* grid(sr,sc,tr,tc) */
W[sr*l1+sc*l2+tr*l3+tc] =
dp_edge_weight( Q1, T1, nsamps1, Q2, T2, nsamps2, dim,
tv1[sc], tv1[tc], tv2[sr], tv2[tr], idxv1[sc], idxv2[sr], lam );
/*
printf( "(%0.2f,%0.2f) --> (%0.2f,%0.2f) = %0.2f\n",
a, c, b, d, grid[sr*l1+sc*l2+tr*l3+tc] );
*/
}
}
}
}
double dp_costs(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double *tv1, int *idxv1, int ntv1,
double *tv2, int *idxv2, int ntv2,
double *E, int *P, double lam )
{
int sr, sc; /* source row and column */
int tr, tc; /* target row and column */
double w, cand_cost;
int i;
E[0] = 0.0;
for ( i=1; i<ntv1; E[i++]=1e9 );
for ( i=1; i<ntv2; E[ntv1*i++]=1e9 );
for ( tr=1; tr<ntv2; ++tr )
{
for ( tc=1; tc<ntv1; ++tc )
{
E[ntv1*tr + tc] = 1e9;
for ( i=0; i<DP_NBHD_COUNT; ++i )
{
sr = tr - dp_nbhd[i][0];
sc = tc - dp_nbhd[i][1];
if ( sr < 0 || sc < 0 ) continue;
w = dp_edge_weight( Q1, T1, nsamps1, Q2, T2, nsamps2, dim,
tv1[sc], tv1[tc], tv2[sr], tv2[tr], idxv1[sc], idxv2[sr], lam );
cand_cost = E[ntv1*sr+sc] + w;
if ( cand_cost < E[ntv1*tr+tc] )
{
E[ntv1*tr+tc] = cand_cost;
P[ntv1*tr+tc] = ntv1*sr + sc;
}
}
}
}
/*
for ( tr=1; tr<ntv2; ++tr )
{
for ( tc=1; tc<ntv1; ++tc )
{
printf( "E[%d,%d]=%0.3f, ", tr, tc, E[ntv1*tr+tc] );
printf( "P[%d,%d]=(%d,%d)\n", tr, tc, P[ntv1*tr+tc]/ntv1,
P[ntv1*tr+tc]%ntv1 );
}
}
*/
return E[ntv1*ntv2-1];
}
double dp_edge_weight(
double *Q1, double *T1, int nsamps1,
double *Q2, double *T2, int nsamps2,
int dim,
double a, double b,
double c, double d,
int aidx, int cidx, double lam )
{
double res = 0.0;
int Q1idx, Q2idx;
int Q1idxnext, Q2idxnext;
double t1, t2;
double t1next, t2next;
double t1nextcand1, t1nextcand2;
double slope, rslope;
double dq, dqi;
int i;
Q1idx = aidx; /*dp_lookup( T1, nsamps1, a );*/
Q2idx = cidx; /*dp_lookup( T2, nsamps2, c );*/
t1 = a;
t2 = c;
slope = (d-c)/(b-a);
rslope = sqrt( slope );
while( t1 < b && t2 < d )
{
if ( Q1idx > nsamps1-2 || Q2idx > nsamps2-2 ) break;
/* Find endpoint of current interval */
t1nextcand1 = T1[Q1idx+1];
t1nextcand2 = a + (T2[Q2idx+1]-c) / slope;
if ( fabs(t1nextcand1-t1nextcand2) < 1e-6 )
{
t1next = T1[Q1idx+1];
t2next = T2[Q2idx+1];
Q1idxnext = Q1idx+1;
Q2idxnext = Q2idx+1;
} else if ( t1nextcand1 < t1nextcand2 ) {
t1next = t1nextcand1;
t2next = c + slope * (t1next - a);
Q1idxnext = Q1idx+1;
Q2idxnext = Q2idx;
} else {
t1next = t1nextcand2;
t2next = T2[Q2idx+1];
Q1idxnext = Q1idx;
Q2idxnext = Q2idx+1;
}
if ( t1next > b ) t1next = b;
if ( t2next > d ) t2next = d;
/* Get contribution for current interval */
dq = 0.0;
for ( i=0; i<dim; ++i )
{
/* Q1 and Q2 are column-major arrays! */
dqi = Q1[Q1idx*dim+i] - rslope * Q2[Q2idx*dim+i];
dq += dqi*dqi + lam*(1-rslope)*(1-rslope);
}
res += (t1next - t1) * dq;
t1 = t1next;
t2 = t2next;
Q1idx = Q1idxnext;
Q2idx = Q2idxnext;
}
return res;
}
int dp_build_gamma(
int *P,
double *tv1, int ntv1,
double *tv2, int ntv2,
double *G, double *T )
{
int sr, sc;
int tr, tc;
int p, i;
int npts; /* result = length of Tg */
/* Dry run first, to determine length of Tg */
npts = 1;
tr = ntv2-1;
tc = ntv1-1;
while( tr > 0 && tc > 0 )
{
p = P[tr*ntv1+tc];
tr = p / ntv1;
tc = p % ntv1;
++npts;
}
G[npts-1] = tv2[ntv2-1];
T[npts-1] = tv1[ntv1-1];
tr = ntv2-1;
tc = ntv1-1;
i = npts-2;
while( tr > 0 && tc > 0 )
{
p = P[tr*ntv1+tc];
sr = p / ntv1;
sc = p % ntv1;
G[i] = tv2[sr];
T[i] = tv1[sc];
tr = sr;
tc = sc;
--i;
}
return npts;
}
int dp_lookup( double *T, int n, double t )
{
int l, m, r;
if ( t < T[n-1] )
{
l=0;
r=n;
m=(l+r)/2;
/* TODO: are these comparisons OK??? */
while( 1 )
{
if ( t >= T[m+1] )
l = m;
else if ( t < T[m] )
r = m;
else
break;
m = (r+l)/2;
}
return m;
} else {
return n-2;
}
}
void dp_all_indexes( double *p, int np, double *tv, int ntv, int *idxv )
{
int pi;
int i;
pi=0;
for ( i=0; i<ntv; ++i )
{
while ( pi < np-2 && tv[i] >= p[pi+1] ) ++pi;
idxv[i] = pi;
}
}
The directory that contains the files is on the search path. How can I get past this error and build the C mex file?
looks like that the problem is that you're only compiling only file1 which has calls to function from file2. So, you need them both in the compiling order.
what about
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c' **SECOND FILE**?