I have a .mat file which could be easily read by matlab, but I need to convert it a C++ readable .model file. is there a way to do it (by hands, or maybe programmatically)?
You could load the data matrix in MATLAB as any regular MAT-file:
load data.mat
then use the MEX function libsvmwrite which comes with the libsvm MATLAB interface, to write it to the so called "sparse" format:
libsvmwrite('data.txt', label_vector, instance_matrix)
If you are talking about trained models not data, a quick search revealed this page (I haven't personally tested it).
EDIT:
Ok, it appears that the code I mentioned needs some tweaking. Below is my modified version. I tested it using the latest libSVM-3.12, with VS2010 as compiler:
svm_savemodel.c
#include "../svm.h"
#include "mex.h"
#include "svm_model_matlab.h"
static void fake_answer(mxArray *plhs[])
{
plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
struct svm_model *model;
char *filename;
const char *error_msg;
int status;
// check input
if(nrhs != 2) {
mexPrintf("Usage: svm_savemodel(model, 'filename');\n");
fake_answer(plhs);
return;
}
if(!mxIsStruct(prhs[0])) {
mexPrintf("model file should be a struct array\n");
fake_answer(plhs);
return;
}
if(!mxIsChar(prhs[1]) || mxGetM(prhs[1])!=1) {
mexPrintf("filename should be given as char(s)\n");
fake_answer(plhs);
return;
}
// convert MATLAB struct to C struct
model = matlab_matrix_to_model(prhs[0], &error_msg);
if(model == NULL) {
mexPrintf("Error: can't read model: %s\n", error_msg);
fake_answer(plhs);
return;
}
// get filename
filename = mxArrayToString(prhs[1]);
// save model to file
status = svm_save_model(filename,model);
if (status != 0) {
mexWarnMsgTxt("Error occured while writing to file.");
}
// destroy model
svm_free_and_destroy_model(&model);
mxFree(filename);
// return status value (0: success, -1: failure)
plhs[0] = mxCreateDoubleScalar(status);
return;
}
Assuming you compiled the above MEX file, here is an example usage:
[labels, data] = libsvmread('./heart_scale');
model = svmtrain(labels, data, '-c 1 -g 0.07');
svm_savemodel(model, 'mymodel.model');
The text file created looks like:
mymodel.model
svm_type c_svc
kernel_type rbf
gamma 0.07
nr_class 2
total_sv 130
rho 0.426412
label 1 -1
nr_sv 63 67
SV
1 1:0.166667 2:1 3:-0.333333 4:-0.433962 5:-0.383562 6:-1 7:-1 8:0.0687023 9:-1 10:-0.903226 11:-1 12:-1 13:1
0.6646947579781318 1:0.125 2:1 3:0.333333 4:-0.320755 5:-0.406393 6:1 7:1 8:0.0839695 9:1 10:-0.806452 12:-0.333333 13:0.5
.
.
Related
I am trying to include the C++ library PROJ.4 in my C++ project for manipulating map data. So far I have not been able to make any headway.
I am wondering if there is a good samaritan out there with experience integrating PROJ.4 in their projects on Windows. Do you have a step by step knowledge of how to integrate the source code into your project?
The downloaded file has an "src" folder separate from an "include" folder. Their website says to include the header "proj.h" which is located in the "src" folder. I tried that in a Sandbox to no avail.
I am missing the steps to prepare the source code to integrate in my C++ project. If anyone has gone through the steps from the source code and can walk me through it, I would greatly appreciate it.
#include <stdio.h>
#include <C:\PROJ4\src\proj.h>
int main(void) {
PJ_CONTEXT* C;
PJ* P;
PJ* P_for_GIS;
PJ_COORD a, b;
C = proj_context_create();
P = proj_create_crs_to_crs(C,
"EPSG:4326",
"+proj=utm +zone=32 +datum=WGS84", /* or EPSG:32632 */
NULL);
if (0 == P) {
fprintf(stderr, "Oops\n");
return 1;
}
/* This will ensure that the order of coordinates for the input CRS */
/* will be longitude, latitude, whereas EPSG:4326 mandates latitude, */
/* longitude */
P_for_GIS = proj_normalize_for_visualization(C, P);
if (0 == P_for_GIS) {
fprintf(stderr, "Oops\n");
return 1;
}
proj_destroy(P);
P = P_for_GIS;
/* a coordinate union representing Copenhagen: 55d N, 12d E */
/* Given that we have used proj_normalize_for_visualization(), the order of
/* coordinates is longitude, latitude, and values are expressed in degrees. */
a = proj_coord(12, 55, 0, 0);
/* transform to UTM zone 32, then back to geographical */
b = proj_trans(P, PJ_FWD, a);
printf("easting: %.3f, northing: %.3f\n", b.enu.e, b.enu.n);
b = proj_trans(P, PJ_INV, b);
printf("longitude: %g, latitude: %g\n", b.lp.lam, b.lp.phi);
/* Clean up */
proj_destroy(P);
proj_context_destroy(C); /* may be omitted in the single threaded case */
return 0;
}
I am trying to use PWork vectors in a custom S-Function. I am hoping to use them to store a pointer to a DLL that I need to use.
In my mdlInitializeSizes I have:
ssSetNumPWOrk(S,1);
In mdlRTW I have:
static void mdlRTW(SimStruct *S)
{
if(!ssWrteRTWWorkVect(S, "PWork",1,"PworkDLL",1)) {
return; /*An error will be reported by SL*/
}
}
In mdlStart:
#define MDL_START
void mdlStart(SimStruct *S){
real_T *xD = ssGetDiscStates(S);
HINSTANCE dllptr = LoadLibrary("TactorInterface.dll");
void **Pwork = ssGetPWork(S);
Pwork[0] = dllptr;
//ssSetPWorkValue(S,0,dllptr);
WritetoVibrotactor_Start_wrapper(xD,Pwork);
}
I need to also implement this PWork in the .tlc file but I have no idea how to do this correctly. There doesn't seem to be much documentation or examples for how to do this correctly. I do have this so far in the .tlc file:
%%Function: Start ========================================================
%function Start(block, system) Output
/* S-Function "WritetoVibrotactor_wrapper" Block: %<Name> */
%assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0)
%assign pwd = LibBlockPWork(PworkDLL, "", "", 0)
WritetoVibrotactor_Start_wrapper(%<pxd>,%<pwd>);
%%
%endfunction
In my wrapper function:
void WritetoVibrotactor_Start_wrapper(real_T *xD, void *Pwork)
{
HINSTANCE hGetProcIDDLL;
hGetProcIDDLL = (HINSTANCE)Pwork[0];
// void * hGetProcIDDLL = LoadLibrary("TactorInterface.dll");
InitializeFn _InitializeTI =
(InitializeFn)GetProcAddress(hGetProcIDDLL,"InitializeTI");
//other stuff...
}
If I try to build the model I get an undefined identifier PworkDLL in the .tlc file.
I need to get the usertags for a file in c program.
I am aware of "mdls -name kMDItemUserTags FILENAME" command to get this details. But i need to do it in c code. Is there any way from which i can get the values directly instead of running this command and parsing.
You can do it via the NSURL Resource Key NSURLLabelColorKey which uses an NSColor to specify the colour.
Therefore it cannot be done in C per se, however you can write an Objective-C implementation file with a C function entry point so it can be called from C (as noted by #Alex MDC in the comments you can use CoreFoundation and do it in C directly, but I would always favour Foundation where possible as it's easier to use when using ARC).
Given NSColor is used to specify the colour, you'll need to create a struct to hold the RGB values and translate between that struct and NSColor yourself.
Something like (untested):
OSXFileLabelColour.h:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int isSet; // if 0 then no colour set
float r;
float g;
float b;
} LabelColour;
/* Return 1 for success or 0 for failure */
extern int getFileLabelColour(const char *filename, LabelColour *colour);
#ifdef __cplusplus
} // extern "C"
#endif
OSXFileLabelColour.m:
#import <Foundation/Foundation.h>
#import "OSXFileLabelColour"
int getFileLabelColour(const char *filename, LabelColour *colour)
{
int retval = 0;
NSURL *url = [NSURL fileURLWithPath:#(filename)];
if (url) {
NSColor *nscolor = nil;
NSError *error = nil;
if ([url getResourceValue:&nscolor
forKey:NSURLLabelColorKey
error:&error]) {
if (nscolor) {
CGFloat r, g, b, a;
[nscolor getRed:&r green:&g blue:&b alpha:&a];
colour->isSet = 1;
colour->r = r;
colour->g = g;
colour->b = b;
} else {
colour->isSet = 0;
}
retval = 1;
} else {
NSLog(#"Failed to get colour label for file '%s': %#", filename, [error localizedDescription]);
}
} else {
NSLog(#"Failed to create URL for file '%s'", filename);
}
return retval;
}
i am using a GPS reciever that will print GPS message contiuously in terminal using a C++ program like this
Latitude:13.3 Longitude:80.25
Latitude:13.4 Longitude:80.27
Latitude:13.5 Longitude:80.28
I want to take this data inside my c++ program (QT Application)
Below is my full program code
void QgsGpsPlotPluginGui::on_buttonBox_accepted()
{
QString myPluginsDir = "usr/lib/qgis/plugins";
QgsProviderRegistry::instance(myPluginsDir);
QgsVectorLayer * mypLayer = new QgsVectorLayer("/home/mit/Documents/Dwl/GIS DataBase/india_placename.shp","GPS","ogr");
QgsSingleSymbolRenderer *mypRenderer = new
QgsSingleSymbolRenderer(mypLayer->geometryType());
QList <QgsMapCanvasLayer> myLayerSet;
mypLayer->setRenderer(mypRenderer);
if (mypLayer->isValid())
{
qDebug("Layer is valid");
}
else
{
qDebug("Layer is NOT valid");
}
// Add the Vector Layer to the Layer Registry
QgsMapLayerRegistry::instance()->addMapLayer(mypLayer, TRUE);
// Add the Layer to the Layer Set
myLayerSet.append(QgsMapCanvasLayer(mypLayer, TRUE));
QgsMapCanvas * mypMapCanvas = new QgsMapCanvas(0, 0);
mypMapCanvas->setExtent(mypLayer->extent());
mypMapCanvas->enableAntiAliasing(true);
mypMapCanvas->setCanvasColor(QColor(255, 255, 255));
mypMapCanvas->freeze(false);
QgsFeature * mFeature = new QgsFeature();
QgsGeometry * geom = QgsGeometry::fromPoint(*p);
QGis::GeometryType geometryType=QGis::Point;
QgsRubberBand * mrub = new QgsRubberBand (mypMapCanvas,geometryType);
QgsPoint * p = new QgsPoint();
double latitude =13.3;
double longitude = 80.25;
p->setX(latitude);
p->setY(longitude);
mrub->setToGeometry(geom,mypLayer);
mrub->show()
}
In the above code i have manually entered the value for Latitude and Longitude like this,
double latitude =13.3;
double longitude = 80.25;
p->setX(latitude);
p->setY(longitude);
but i need to get these value from terminal.
Both program are written in c++ but they belong to different framework.
I assume that your library doesn't have an API you can use.
Then one fairly straight forward way to integrate them would be to use pipes.
You can quickly do something like
gps_program | qt_program
And now you get the coordinates via stdin.
The more complex way to set it up is using exec and fork. You create pipe objects, then fork and run using exec the gps_programon one of the branches. This you can do entirely in your code without depending on bash or something like it. You still have to parse the data coming from the pipe the same way.
Just create a pipe:
#include <cstdio>
#include <iostream>
#define WWRITER 0
#if WWRITER
int main() {
while (true) {
std::cout << "Latitude:13.3 Longitude:80.25";
}
return 0;
}
#else
int main() {
FILE* fp = popen("Debug/Writer", "r");
if(fp == 0) perror(0);
else {
const std::size_t LatitudeLength = 9;
const std::size_t LongitudeLength = 10;
char latitude_name[LatitudeLength+1];
char longitude_name[LongitudeLength+1];
double latitude;
double longitude;
while(fscanf(fp, "%9s%lf%10s%lf",
latitude_name,
&latitude,
longitude_name,
&longitude) == 4)
{
std::cout << "Values: " << latitude << ", " << longitude << std::endl;
}
pclose(fp);
}
return 0;
}
#endif
Note: The example runs endlessly.
+1 to Sorin's answer, makes this nice and easy passing stdout to stdin :) but assuming you are running in linux / cigwin?
But if you have access to both program codes then a nicer solution is to use UdpSockets (or maybe Tcp, but Udp is simpler) and pass the data between programs in this way... not sure how big/long-term your solution needs to be but if you want to integrate them in a "long-term" and more maintainable way this would be a better approach.
Well I am attempting to make my way through developing an Excel Add-in. I am trying small functions with the sample code in Excel 2007 SDK as as a guide. I am having difficulty with attempting to display a double type data in Excel. Assuming the UDF is called DisplayDouble() when the sample code is executed and a call is placed with an argument of real type data such as DisplayDouble(12.3) the sample code works yet if I attempt to use an argument that references a real type data from cell such as DisplayDouble(A1) where cell A1 in the Excel worksheet has the value 12.3 the sample code does not work
You can see the sample code below this paragraph. Any hints will help me move along the learning ladder
_declspec(dllexport) LPXLOPER12 WINAPI DisplayDouble (LPXLOPER12 n)
{
static XLOPER12 xResult;
XLOPER12 xlt;
int error = -1;
double d;
switch (n->xltype)
{
case xltypeNum:
d = (double)n->val.num;
if (max < 0)
error = xlerrValue;
xResult.xltype = xltypeNum;
xResult.val.num = d;
break;
case xltypeSRef:
error = Excel12f(xlCoerce, &xlt, 2, n, TempNum12(xltypeNum));
if (!error)
{
error = -1;
d = xlt.val.w;
xResult.xltype = xltypeNum;
xResult.val.num = d;
}
Excel12f(xlFree, 0, 1, &xlt);
break;
default:
error = xlerrValue;
break;
}
if ( error != - 1 )
{
xResult.xltype = xltypeErr;
xResult.val.err = error;
}
//Word of caution - returning static XLOPERs/XLOPER12s is not thread safe
//for UDFs declared as thread safe, use alternate memory allocation mechanisms
return(LPXLOPER12) &xResult;
}
looks like you coerced the value to xltypeNum but are then taking the integer value, with d = xlt.val.w rather than d = xlt.val.num