I got some memory allocated in a loop - how to free it when I am done with tr_data variable ?
(I am fairly new to C++)
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
struct svm_problem tr_data;
tr_data.l = (int) prm_num_samples_anchored.array[bar];
tr_data.y = Malloc(double, tr_data.l);
tr_data.x = Malloc(struct svm_node*, tr_data.l);
for (int row = 0; row < tr_data.l; row++)
{
tr_data.y[row] = ta0.array[bar-row-1];
//leak
svm_node* tr_data_x_onerow = Malloc(svm_node, num_features+1);
tr_data_x_onerow[0].index = 1; tr_data_x_onerow[0].value = in0.array[bar-row-1]; tr_data_x_onerow[1].index = 2; tr_data_x_onerow[1].value = in1.array[bar-row-1]; tr_data_x_onerow[2].index = 3; tr_data_x_onerow[2].value = in2.array[bar-row-1]; tr_data_x_onerow[3].index = 4; tr_data_x_onerow[3].value = in3.array[bar-row-1]; tr_data_x_onerow[4].index = 5; tr_data_x_onerow[4].value = in4.array[bar-row-1]; tr_data_x_onerow[5].index = 6; tr_data_x_onerow[5].value = in5.array[bar-row-1]; tr_data_x_onerow[6].index = 7; tr_data_x_onerow[6].value = in6.array[bar-row-1]; tr_data_x_onerow[7].index = 8; tr_data_x_onerow[7].value = in7.array[bar-row-1]; tr_data_x_onerow[8].index = 9; tr_data_x_onerow[8].value = in8.array[bar-row-1]; tr_data_x_onerow[9].index = 10;
tr_data_x_onerow[num_features].index = -1; //Each row of properties should be terminated with a -1 according to the readme
tr_data.x[row] = tr_data_x_onerow;
}
... few operation on tr_data
... and this does not work
for (int row = 0; row <tr_data.l; row++)
{
free(tr_data_x_onerow);
}
for (int row = 0; row <tr_data.l; row++)
{
free(tr_data.x[row]);
}
But please, just don't do this. This is C++. Use a vector or some other sane collection.
Related
I try to obtain the adjacency matrix of weights, and then use it in the calculation of the minimum weight path. There is a problem, when I try to display it, I get a wrong result :
By logic, the diagonal must have only 0, and in the places where the vertices are adjacent, must be the weight of the edge
//set the source and destination of each edge
g->edge[0]->src = 0;
g->edge[0]->dest = 1;
g->edge[0]->weight = 9;
g->edge[1]->src = 0;
g->edge[1]->dest = 10;
g->edge[1]->weight = 6;
g->edge[2]->src = 1;
g->edge[2]->dest = 2;
g->edge[2]->weight = 3;
g->edge[3]->src = 1;
g->edge[3]->dest = 10;
g->edge[3]->weight = 2;
g->edge[4]->src = 2;
g->edge[4]->dest = 3;
g->edge[4]->weight = 2;
g->edge[5]->src = 2;
g->edge[5]->dest = 6;
g->edge[5]->weight = 3;
g->edge[6]->src = 2;
g->edge[6]->dest = 5;
g->edge[6]->weight = 3;
g->edge[7]->src = 3;
g->edge[7]->dest = 4;
g->edge[7]->weight = 5;
g->edge[8]->src = 4;
g->edge[8]->dest = 5;
g->edge[8]->weight = 4;
g->edge[9]->src = 6;
g->edge[9]->dest = 10;
g->edge[9]->weight = 2;
g->edge[10]->src = 6;
g->edge[10]->dest = 7;
g->edge[10]->weight = 9;
g->edge[11]->src = 7;
g->edge[11]->dest = 8;
g->edge[11]->weight = 7;
g->edge[12]->src = 7;
g->edge[12]->dest = 9;
g->edge[12]->weight = 2;
g->edge[13]->src = 8;
g->edge[13]->dest = 9;
g->edge[13]->weight = 7;
g->edge[14]->src = 9;
g->edge[14]->dest = 10;
g->edge[14]->weight = 5;
My code :
for (i = 0; i < numberOfVertices; i++)
{
adjacency_matrix[i][i] = 0;
for (j = i + 1; j < numberOfVertices; j++)
{
adjacency_matrix[i][j] = g->edge[i]->weight;
adjacency_matrix[j][i] = g->edge[i]->weight;
}
}
What's wrong?
for (i = 0; i < numberOfVertices; i++)
{
adjacency_matrix[i][i] = 0;
for (j = i + 1; j < numberOfVertices; j++)
{
adjacency_matrix[i][j] = g->edge[i]->weight;
adjacency_matrix[j][i] = g->edge[i]->weight;
}
}
In this code you are setting every edge from vertex i to every other vertex to the same weight. I do not think this is what you want.
( Note: It is hard to know what you do want. When reporting a problem you need to include a description of both what happens AND what you wanted to happen. "It's wrong!" is almost useless as a bug report. )
I am writing a code to find a cluster, I am using "cern root" to plot graphs,
the data is saved in ".root" file, but the code is written in c++. The data is saved as a 2D histogram. The logic of the code is once I find a bin with some signal in it, I find the neighbours around it (8 bins), then I tag the bin and increase the cluster size, and then do the same for the neighbour. I started by making a fiction to find the neighbour (the function returns an array with the x coordinate and another finds the y coordinate)
int* neighbour_function_i(int i){
int* neighbour_i = new int[8]; // Pointer to int, initialize to nothing.
neighbour_i[0] = {i-1}, neighbour_i[1] = {i}, neighbour_i[2] = {i+1}, neighbour_i[3] = {i-1}, neighbour_i[4] = {i+1}, neighbour_i[5] = {i-1}, neighbour_i[6] = {i}, neighbour_i[7] = {i+1};
return neighbour_i; //check if this works
}
the code that finds the cluster is as below
int* temp_neighbour_i = NULL;
int* temp_neightbour_j = NULL;
int uncheckedneighbours, total_neighbours;
int clsize = 0;
int temp_i,temp_j;
for(int i = 0; i < NPIXAX; i++){
for(int j = 0; j < NPIXAY; j++){
clsize = 0;
if(h->GetBinContent(i + 1, j + 1) - ped[i][j] > 0 && pedbf[i][j] == 0){//condition to find a cluster
pedbf[i][j] = 1; //Tag arry
clsize = 1;
uncheckedneighbours = 8;
total_neighbours = uncheckedneighbours;
int* neighbour_i = neighbour_function_i[i];//the error is here
int* neighbour_j = neighbour_function_j[j];//the error is here
while(uncheckedneighbours != 0){
for(int n = 0; n < total_neighbours; n++){
temp_i = neighbour_i[n];//Temp int for coordienate
temp_j = neighbour_j[n];//Temp int for coordinate
if(h->GetBinContent(temp_i, temp_j) - ped[temp_i][temp_j] > 0 && pedbf[temp_i][temp_j] == 0){//condition to find a cluster
pedbf[temp_i][temp_j] = 1;
int* new_neighbour_i = neighbour_function_i[temp_i];//the error is here
int* new_neighbour_j = neighbour_function_j[temp_j];//the error is here
uncheckedneighbours += 8;
total_neighbours += 8;
int* temp_neighbour_i = new int[clsize * 8];
int* temp_neighbour_j = new int[clsize * 8];
clsize++;
temp_neighbour_i[n] = neighbour_i[n];//moving data to chnage the size of neighbour/i array
temp_neighbour_j[n] = neighbour_j[n];//moving data to change the size of neighbour_j array
delete[] neighbour_i;//deallocate neighbour
delete[] neighbour_j;//deallocate neighbour
int *neighbour_i = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
int *neighbour_j = new int[clsize * 8]; //re-allocate the size of neighbour with size = size(clsize *8)
for(int x = 0; x < (clsize - 1) * 8; x++){ //neighbour = temp_neighbour + new_neighbour
neighbour_i[x] = temp_neighbour_i[x];
neighbour_j[x] = temp_neighbour_j[x];
}
for(int x = (clsize - 1)*8; x < clsize * 8; x++){
neighbour_i[x] = new_neighbour_i[x];
neighbour_j[x] = new_neighbour_j[x];
}
delete[]temp_neighbour_i; //dealocate temp and new
delete[]temp_neighbour_j; //dealocate temp and new
delete[]new_neighbour_i; //dealocate temp and new
delete[]new_neighbour_j; //dealocate temp and new
}
uncheckedneighbours--;
}
}
//if(clsize != 0){;//output to file cluseter size, i, j
//}
}
}
}
I am not sure why I am getting this error "subscript of pointer to function type 'int *(int)'"?
Maybe question should be closed as typo, but a function gets called like this:
int* neighbour_i = neighbour_function_i(i);
Not like this:
int* neighbour_i = neighbour_function_i[i];
here is the matlab code i'm trying to convert to c++
where
size(Iorig) == 1334X 2026
%% label checkers
Label = zeros(size(Iorig));
Margins = 11;
[X,Y] = meshgrid(1:size(Iorig,2),1:size(Iorig,1));
k = 1;
for i = 1:4
for j = 1:6
rr = rect{i,j};
x1 = rr(1);
x2 = rr(1) + rr(3);
y1 = rr(2);
y2 = rr(2) + rr(4);
Label(X>=x1+Margins&X<x2-Margins&Y>=y1+Margins&Y<y2-Margins) = k;
k = k+1;
end
end
I understand that we want to label the rectangles which are found in the previous step, there are 24 of those.
but I don't understand how to convert this line into easy c++ code without allocating a huge buffer of X and Y which basically just holds... indices..
thanks for your help here is what i started doing.
//label Checkers
List<List<int>^>^ label = gcnew List<List<int>^>();
int margins = 11;
int k = 1;
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 6; j++)
{
MacbethCheckerBatchesColor^ rect = autoDetectMacbethResult[i * 6 + j];
Point^ r = rect->Points[0];
int x1 = r->X;
int y1 = r->Y;
r = rect->Points[2];
int x2 = r->X;
int y2 = r->Y;
for (int h = 0; h < inputImage->HeightLines; h++)
{
List<int>^ tempRow = gcnew List<int>();
for (int w = 0; w < inputImage->WidthColumns; w++)
{
if ( (w>= x1+margins) & (w<x2-margins) & (h >= y1+margins) & (h<y2-margins) )
{
tempRow->Add(k);
}
else
{
tempRow->Add(0);
}
}
label->Add(tempRow);
}
k= k+100;//i tried here many other numbers... same result
}
}
Here is my result can you please help me find my mistake, the rectangles are the same, I guesss I have some other logical mistake.
I am trying to train an svm for a simple xor problem programmatically using libsvm to understand how the library works. The problem (i think) seems to be that i construct svm_node incorrectly; maybe i have trouble understanding the whole pointers to pointers thing. Could anybody help with this? I first construct a matrix for the xor problem then try to assign values from the matrix to svm_node (i am using 2 steps here because my real data will be in matrix format).
When testing the model i get incorrect values (always -1).
In a previous question i got help with the parameters C and gamma; these should be OK now since i got correct classifications for the xor problem using other code. Thanks again Pedrom!
I have searched in several places for answers, e.g. the Readme and in the SvmToy example; no luck however.
Here is the code that outputs incorrect classifications...
Thanks in advance!
//Parameters---------------------------------------------------------------------
svm_parameter param;
param.svm_type = C_SVC;
param.kernel_type = RBF;
param.degree = 3;
param.gamma = 0.5;
param.coef0 = 0;
param.nu = 0.5;
param.cache_size = 100;
param.C = 1;
param.eps = 1e-3;
param.p = 0.1;
param.shrinking = 1;
param.probability = 0;
param.nr_weight = 0;
param.weight_label = NULL;
param.weight = NULL;
//Problem definition-------------------------------------------------------------
svm_problem prob;
//Length, 4 examples
prob.l = 4;
//x values matrix of xor values
QVector< QVector<double> >matrix;
QVector<double>row(2);
row[0] = 1;row[1] = 1;
matrix.push_back(row);
row[0] = 1;row[1] = 0;
matrix.push_back(row);
row[0] = 0;row[1] = 1;
matrix.push_back(row);
row[0] = 0;row[1] = 0;
matrix.push_back(row);
//This part i have trouble understanding
svm_node* x_space = new svm_node[3];
svm_node** x = new svm_node *[prob.l];
//Trying to assign from matrix to svm_node training examples
for (int row = 0;row < matrix.size(); row++){
for (int col = 0;col < 2;col++){
x_space[col].index = col;
x_space[col].value = matrix[row][col];
}
x_space[2].index = -1; //Each row of properties should be terminated with a -1 according to the readme
x[row] = x_space;
}
prob.x = x;
//yvalues
prob.y = new double[prob.l];
prob.y[0] = -1;
prob.y[1] = 1;
prob.y[2] = 1;
prob.y[3] = -1;
//Train model---------------------------------------------------------------------
svm_model *model = svm_train(&prob,¶m);
//Test model----------------------------------------------------------------------
svm_node* testnode = new svm_node[3];
testnode[0].index = 0;
testnode[0].value = 1;
testnode[1].index = 1;
testnode[1].value = 0;
testnode[2].index = -1;
//Should return 1 but returns -1
double retval = svm_predict(model,testnode);
qDebug()<<retval;
It seems you've been trying to get this example to work for weeks. I followed the style in svm-train.c that comes with libsvm. I used your values for C and gamma. It is working. I tried all points in the XOR example and it is giving correct results.
The summary of the problem you're having is that you're not allocating space for the 4 data points you train with, so you just over-write the data. This is a typical mistake with pointers in C. It may help you brushed up on pointers in C/C++.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "svm.h"
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
struct svm_parameter param; // set by parse_command_line
struct svm_problem prob; // set by read_problem
struct svm_model *model;
struct svm_node *x_space;
int main(int argc, char **argv)
{
char input_file_name[1024];
char model_file_name[1024];
const char *error_msg;
param.svm_type = C_SVC;
param.kernel_type = RBF;
param.degree = 3;
param.gamma = 0.5;
param.coef0 = 0;
param.nu = 0.5;
param.cache_size = 100;
param.C = 1;
param.eps = 1e-3;
param.p = 0.1;
param.shrinking = 1;
param.probability = 0;
param.nr_weight = 0;
param.weight_label = NULL;
param.weight = NULL;
//Problem definition-------------------------------------------------------------
prob.l = 4;
//x values matrix of xor values
double matrix[prob.l][2];
matrix[0][0] = 1;
matrix[0][1] = 1;
matrix[1][0] = 1;
matrix[1][1] = 0;
matrix[2][0] = 0;
matrix[2][1] = 1;
matrix[3][0] = 0;
matrix[3][1] = 0;
//This part i have trouble understanding
svm_node** x = Malloc(svm_node*,prob.l);
//Trying to assign from matrix to svm_node training examples
for (int row = 0;row <prob.l; row++){
svm_node* x_space = Malloc(svm_node,3);
for (int col = 0;col < 2;col++){
x_space[col].index = col;
x_space[col].value = matrix[row][col];
}
x_space[2].index = -1; //Each row of properties should be terminated with a -1 according to the readme
x[row] = x_space;
}
prob.x = x;
//yvalues
prob.y = Malloc(double,prob.l);
prob.y[0] = -1;
prob.y[1] = 1;
prob.y[2] = 1;
prob.y[3] = -1;
//Train model---------------------------------------------------------------------
svm_model *model = svm_train(&prob,¶m);
//Test model----------------------------------------------------------------------
svm_node* testnode = Malloc(svm_node,3);
testnode[0].index = 0;
testnode[0].value = 1;
testnode[1].index = 1;
testnode[1].value = 0;
testnode[2].index = -1;
//This works correctly:
double retval = svm_predict(model,testnode);
printf("retval: %f\n",retval);
svm_destroy_param(¶m);
free(prob.y);
free(prob.x);
free(x_space);
return 0;
}
I have such a code:
QVector<Point> legalMoves = field.getLegalMoves();
QVector<Cell> costs;
costs.reserve(legalMoves.size());
for (QVector<Point>::iterator i = legalMoves.begin(); i < legalMoves.end(); ++i)
costs.push_back(checkCost(field, *i, player, -100, 100));
Cell cost;
if (player) {
QVector<Point>::iterator m1 = legalMoves.begin();
QVector<Cell>::iterator m2 = costs.begin();
QVector<Cell>::iterator j = costs.begin() + 1;
for (QVector<Point>::iterator i = legalMoves.begin() + 1; i < legalMoves.end(); ++i, ++j)
if (j->status > m2->status) {
m1 = i;
m2 = j;
}
cost=*m2;
}
else {
QVector<Point>::iterator m1 = legalMoves.begin();
QVector<Cell>::iterator m2 = costs.begin();
QVector<Cell>::iterator j = costs.begin() + 1;
for (QVector<Point>::iterator i = legalMoves.begin() + 1; i < legalMoves.end(); ++i, ++j)
if (j->status < m2->status) {
m1 = i;
m2 = j;
}
cost=*m2;
}
QVector<Point> moves;
QVector<Cell>::iterator j = costs.begin();
for (QVector<Point>::iterator i = legalMoves.begin(); i < legalMoves.end(); ++i, ++j)
if (j->status == cost.status)
moves.push_back(*i);
short index = qrand()%moves.size();
return moves[index];
}
When i'm debugging it, compiler just skips this parts inside loops:
if (j->status < m2->status) {
m1 = i;
m2 = j;
}
which means the functions returns the very first Point(or any other Point with same Cell value instead of min/max). Why does that happen and how is it possible to fix it?