error LNK 2019: unresolved external symbol (Matlab) - c
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**?
Related
arrange elements in vertical order
Found some answers, but all are implemented on multi dimension array. I have a scenario, where I need to render the array elements in the vertical order. Expected Behavior: Get the length of given array and split the array into four columns. Each column should have max of 6 items in it. Expected Output: 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 17 23 6 12 18 24 Sample Array: { "items": [ { "val": "1" }, { "val": "2" }, { "val": "3" }, { "val": "4" }, { "val": "5" }, { "val": "6" }, { "val": "7" }, { "val": "8" }, { "val": "9" } ] } This is what I tried, not able to achieve the expected output. createList(list, index) { const max = Math.max.apply(null, list.items.map((x, i) => (i + 1) / 4)); return Array.from({ length: max }, function(item, index) { return <div className="row" key={index}> {list.items.slice(0, max).map((x, i) => ( <div className="col-3" key={i}> {x.val} </div> ))} </div>; }); }
There's probably tons of way to do this but i came up with this solution using lodash: renderColumn(row) { // map through columns const columns = row.map(column => ( <td key={column}>{column}</td> )); return columns; } render() { // Create an array of length 50 let items = []; for (let i=0; i<50; i++) { items.push({val:i}); } /** Transform the array in something like this: * items: [ * [1, 7, 13, 19], * [2, 8, 14, 20], * [3, 9, 15, 21], * [4, 10, 16, 22], * [5, 11, 17, 23], * [6, 12, 18, 24], * ] */ // Get only 24 first items as it is a 4x6 matrix items = items.slice(0, 24); const res = _.reduce(items, (result, value, key) => { const index = key % 6; (result[index] || (result[index] = [])).push(value.val); return result; }, {}); // map through the rows of the arrays const rows = _.map(res, row => { const column = this.renderColumn(row); return <tr>{column}</tr>; }); return ( <table> <tbody> {rows} </tbody> </table> ); } I hope you get the point :) Here is a sandbox with the code
printing items in an array won't print the items
#include <stdio.h> #include <string.h> #define MAX_LENGTH 20 struct Item { int SKU; char name[MAX_LENGTH+1]; }; int contains(void) { int compare; return 0; } void displayItemWith(struct Item item[], int count) { int i; char alphabet; i = 0; for(i=0; i<count; i++){ //char inventory[ ] = {item->SKU}; printf("%d", item[i].SKU); } int main(void) { int compare; char count; //prints the title printf("=== TEST ===\n"); // hard-coded inventory 21 items - room for 0 more struct Item inventory[21] = { // price sku txd qty min name { .SKU = 275, "Royal Gala Apples" }, { .SKU = 386, "Honeydew Melon" }, { .SKU = 240, "Blueberries" }, { .SKU = 916, "Seedless Grapes" }, { .SKU = 385, "Pomegranate" }, { .SKU = 495, "Banana" }, { .SKU = 316, "Kiwifruit" }, { .SKU = 355, "Chicken Alfredo" }, { .SKU = 846, "Veal Parmigiana" }, { .SKU = 359, "Beefsteak Pie" }, { .SKU = 127, "Curry Chicken" }, { .SKU = 238, "Tide Detergent" }, { .SKU = 324, "Tide Liq. Pods" }, { .SKU = 491, "Tide Powder Det." }, { .SKU = 538, "Lays Chips S&V" }, { .SKU = 649, "Joe Org Chips" }, { .SKU = 731, "Allen's Apple Juice" }, { .SKU = 984, "Coke 12 Pack" }, { .SKU = 350, "Nestea 12 Pack" }, { .SKU = 835, "7up 12 Pack" } }; printf("*** NO MATCHES ***\n"); printf("=== END ===\n"); return 0; } Hello, users, I am trying to print out the list of items in output with such format; SKU: 275 - Royal Gala Apples SKU: 386 - Honeydew Melon but the only thing that would print is the ===TEST===, NO MATCHES, ===END===. Any reason why?
Because no matter what you do, the "NO MATCHES" will show because you printf it without no conditions. Also, in order to print the list you need to call the method you made which is "displayItemWith(struct Item item[], int count)" and please declare the struct first for a better approach.example: struct Books { char title[50]; char author[50]; char subject[100]; int book_id; };
How to send midi pitch bend messages correctly in c?
I'm trying to make a custom midi player, to do so I'm using an array that has already memorized correctly the midi messages data like this: int array[3000][4]={{time,status,data1,data2},{...},...} when I want my program to send the midi message (so that it can be played) I call this array and do the needed distinctions between noteon/off, pitch-bend and such. At first I thought I was doing the division in two 7 bits variables wrong, because I never worked with this procedure and I just copied the code from another question on stackoverflow, I posted my own question about it (here) and as it turns out the copied code works just fine. And yet the sound output isn't the right one, it barely has any change in pitch and when it has, it is so small I'm not even sure I'm hearing it (it should sound like a half tone bend with a vibrato in the end). So here's the code: union { unsigned long word; unsigned char data[4]; } message; int main(int argc, char** argv) { int midiport; // select which MIDI output port to open uint16_t bend; int flag,u; // monitor the status of returning functions uint16_t mask = 0x007F; HMIDIOUT device; // MIDI device interface for sending MIDI output message.data[0] = 0x90; message.data[1] = 60; message.data[2] = 100; message.data[3] = 0; // Unused parameter // Assign the MIDI output port number (from input or default to 0) if (!midiOutGetNumDevs()){ printf("non ci sono devices"); } if (argc < 2) { midiport = 0; } else { midiport = 0; } printf("MIDI output port set to %d.\n", midiport); // Open the MIDI output port flag = midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL); if (flag != MMSYSERR_NOERROR) { printf("Error opening MIDI Output.\n"); return 1; }i = 0; message.data[0] = 0xC0; message.data[1] = 25; message.data[2] = 0; flag = midiOutShortMsg(device, message.word); //program change to steel guitar if (flag != MMSYSERR_NOERROR) { printf("Warning: MIDI Output is not open.\n"); } while (1){ if (array[i][1] == 1) { //note on this_works();i++; } else if (array[i][1] == 0){//note off this_also_works();i++; } else if (array[i][1] == 2){//pitch bend while (array[i][1] == 2){ Sleep(10); message.data[0] = 0xE0; bend = (uint16_t) array[i][2]; message.data[1] = bend & mask; message.data[2] = (bend & (mask << 7)) >> 7; printf("bending %d, %d\n", message.data[1],message.data[2]); flag = midiOutShortMsg(device, message.word); if (flag != MMSYSERR_NOERROR) { printf("Warning: MIDI Output is not open.\n"); }i++; } } }} here's the pitch-bend array[][] values for a half tone bend with vibrato: { 6560, 2, 8192 }, { 6576, 2, 8320 }, { 6592, 2, 8448 }, { 6608, 2, 8704 }, { 6624, 2, 8832 }, { 6720, 2, 8832 }, { 6729, 2, 8832 }, { 6739, 2, 8832 }, { 6748, 2, 8832 }, { 6757, 2, 8832 }, { 6766, 2, 8832 }, { 6776, 2, 8704 }, { 6785, 2, 8704 }, { 6794, 2, 8704 }, { 6804, 2, 8704 }, { 6813, 2, 8704 }, { 6822, 2, 8832 }, { 6831, 2, 8832 }, { 6841, 2, 8832 }, { 6850, 2, 8832 }, { 6859, 2, 8832 }, { 6868, 2, 8832 }, { 6878, 2, 8832 }, { 6887, 2, 8832 }, { 6896, 2, 8832 }, { 6906, 2, 8832 }, { 6915, 2, 8832 }, { 6924, 2, 8960 }, { 6933, 2, 8960 }, { 6943, 2, 8960 }, { 6952, 2, 8960 }, { 6961, 2, 8960 }, { 6971, 2, 8832 }, { 6980, 2, 8832 }, { 6989, 2, 8832 }, { 6998, 2, 8832 }, { 7008, 2, 8832 }, { 7017, 2, 8832 }, { 7026, 2, 8832 }, { 7036, 2, 8960 }, { 7045, 2, 8960 }, { 7054, 2, 8960 }, { 7063, 2, 8960 }, { 7073, 2, 8960 }, { 7082, 2, 8960 }, { 7091, 2, 8960 }, { 7101, 2, 8960 }, { 7110, 2, 8960 }, { 7119, 2, 8960 }, { 7128, 2, 8960 }, { 7138, 2, 8960 }, { 7147, 2, 8960 }, { 7156, 2, 8832 }, { 7165, 2, 8832 }, { 7175, 2, 8832 }, { 7184, 2, 8704 }, { 7193, 2, 8704 }, { 7203, 2, 8704 }, { 7212, 2, 8704 }, { 7221, 2, 8704 }, { 7230, 2, 8704 }, { 7240, 2, 8704 }, { 7249, 2, 8704 }, { 7258, 2, 8704 }, { 7268, 2, 8704 }, { 7277, 2, 8704 }, { 7286, 2, 8704 }, { 7295, 2, 8704 }, { 7305, 2, 8832 }, { 7314, 2, 8832 }, { 7323, 2, 8832 }, { 7333, 2, 8960 }, { 7342, 2, 8960 }, { 7351, 2, 9088 }, { 7360, 2, 9088 }, { 7370, 2, 9088 }, { 7379, 2, 9088 }, { 7388, 2, 9088 }, { 7398, 2, 9088 }, { 7407, 2, 9088 }, { 7416, 2, 9088 }, { 7425, 2, 9088 }, { 7435, 2, 8960 }, { 7444, 2, 8960 }, { 7453, 2, 8832 }, { 7462, 2, 8832 }, { 7472, 2, 8832 }, { 7481, 2, 8704 }, { 7490, 2, 8704 }, { 7500, 2, 8576 }, { 7509, 2, 8576 }, { 7518, 2, 8576 }, { 7527, 2, 8576 }, { 7537, 2, 8576 }, { 7546, 2, 8576 }, { 7555, 2, 8576 }, { 7565, 2, 8576 }, { 7574, 2, 8576 }, { 7583, 2, 8704 }, { 7592, 2, 8704 }, { 7602, 2, 8832 }, { 7611, 2, 8832 }, { 7620, 2, 8832 }, { 7630, 2, 8832 }, { 7639, 2, 8832 }, { 7648, 2, 8832 }, { 7657, 2, 8832 }, { 7667, 2, 8832 }, { 7676, 2, 8832 }, and here's the printf output: I really don't know what I'm doing wrong, any help will be appreciated.
The message.data[] values are correctly computed; the code does nothing wrong. The problem is that the bend values do not correspond to a half tone. The default pitch bend range maps the 0..16383 control values to ±2 halftones; to get a half tone up, the values would have to go up to 12288.
creating 4D lookup table
I need to create fast 4D lookup table according to the following: 1- it will receive 4 input variables (u,v,i,j) each one range from 0 to 15 2- the lookup table returns a precalculated value of 8 bit how can I implement this 4D lookup table in very fast code in C Language
Just make a 4-dimensional array on the stack. 16^4 bytes is a size that should fit on the stack on most platforms, otherwise make it static or global. It gives the compiler full knowledge about the layout, it is a well known and commonly used language construct, it should optimize well: uint8_t lookup[16][16][16][16]; // global table about 64KB int main(int, char **) { ... Of course you can make one dimensional array uint8_t lookup[16*16*16*16] and multiply your values lookup[u*16*16*16 + v*16*16 + i*16 + j] but I massively doubt that you will be able to make this more performant than the 4-dim array (where the compiler does this kind of multiplication internally anyway) Since you are asking about the initialization, here is an example of how to init a 4-dim array. for simplicity it is just [4][4][4][4], so you have to increase that to 16 (16 blocks of 16 rows, of 16 series of 16 numbers. uint8_t test[4][4][4][4]= { { // [0][x][y][z] { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } }, { // [1][x][y][z] { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 } }, { // [2][x][y][z] { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 } }, { // [3][x][y][z] { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 } } };
how to initialize members of an array of struct in C
I have the following struct: typedef struct { int someArray[3][2]; int someVar; } myStruct; If I create an array of this struct in my main (like the following), how would I initialize it? int main() { myStruct foo[5]; } I want to initialize the above array of struct in a way similar to initilazing a normal array (see below): int main() { int someArray[5] = {1,4,0,8,2}; }
Work from the outside in. You know you have an array of 5 things to initialize: mystruct foo[5] = { X, X, X, X, X }; where X is a stand-in for initializers of type mystruct. So now we need to figure out what each X looks like. Each instance of mystruct has two elements, somearray and somevar, so you know your initializer for X will be structured like X = { Y, Z } Substituting back into the original declaration, we now get mystruct foo[5] = { { Y, Z }, { Y, Z }, { Y, Z }, { Y, Z }, { Y, Z } }; Now we need to figure out what each Y looks like. Y corresponds to an initializer for a 3x2 array of int. Again, we can work from the outside in. You have an initializer for a 3-element array: Y = { A, A, A } where each array element is a 2-element array of int: A = { I, I } Subsituting back into Y, we get Y = { { I, I }, { I, I }, { I, I } } Substituting that back into X, we get X = { { { I, I }, { I, I }, { I, I } }, Z } which now gives us mystruct foo[5] = { { { { I, I }, { I, I }, { I, I } }, Z }, { { { I, I }, { I, I }, { I, I } }, Z }, { { { I, I }, { I, I }, { I, I } }, Z }, { { { I, I }, { I, I }, { I, I } }, Z }, { { { I, I }, { I, I }, { I, I } }, Z } }; Since Z is a stand-in for an integer, we don't need to break it down any further. Just replace the Is and Zs with actual integer values, and you're done: mystruct foo[5] = { {{{101, 102}, {201, 202}, {301, 302}}, 41}, {{{111, 112}, {211, 212}, {311, 312}}, 42}, {{{121, 122}, {221, 222}, {321, 322}}, 43}, {{{131, 132}, {231, 232}, {331, 332}}, 44}, {{{141, 142}, {241, 242}, {341, 342}}, 45} };
Wrap the initializer for each structure element of the array in a set of braces: myStruct foo[5] = { { { { 11, 12 }, { 13, 14 }, { 55, 56 }, }, 70 }, { { { 21, 22 }, { 23, 24 }, { 45, 66 }, }, 71 }, { { { 31, 32 }, { 33, 34 }, { 35, 76 }, }, 72 }, { { { 41, 42 }, { 43, 44 }, { 25, 86 }, }, 73 }, { { { 51, 52 }, { 53, 54 }, { 15, 96 }, }, 74 }, };
Like that: int main() { // someArr initialization | someVar initialization mystruct foo[5] = { { { {1, 2}, {1,2}, {1, 2} }, 1 }, // foo[0] initialization //... }; }