错误 LNK2019:无法解析的外部符号 (Matlab)
error LNK 2019: unresolved external symbol (Matlab)
我正在尝试在 Matlab 中构建一个 C mex 文件。 C 编译器是 Microsoft Visual C++ 2012,我使用的是 Matlab R2014a。这是我使用的确切命令:
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c'
错误信息如下:
使用 '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
这是 C 代码:
#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 );
}
这是头文件:
#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 */
和
#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 */
另外还有一个C文件:
#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;
}
}
包含文件的目录在搜索路径上。我怎样才能克服这个错误并构建 C mex 文件?
看起来问题在于您只编译了 file1,它调用了 file2 的函数。因此,您在编译顺序中都需要它们。
怎么样
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c' **SECOND FILE**?
我正在尝试在 Matlab 中构建一个 C mex 文件。 C 编译器是 Microsoft Visual C++ 2012,我使用的是 Matlab R2014a。这是我使用的确切命令:
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c'
错误信息如下: 使用 '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
这是 C 代码:
#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 );
}
这是头文件:
#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 */
和
#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 */
另外还有一个C文件:
#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;
}
}
包含文件的目录在搜索路径上。我怎样才能克服这个错误并构建 C mex 文件?
看起来问题在于您只编译了 file1,它调用了 file2 的函数。因此,您在编译顺序中都需要它们。
怎么样
mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c' **SECOND FILE**?