I have a small problem, which I think it will be easy for you to figure out. But still I'm not a good programmer. Anyway, the problem is that I need to access the matrix element (20*2), this matrix is representing x,y locations for 20 features in image. I need to have a parameter that can give me the value of all them as x and another one for y; for example P = (all x values) and q= (all y values) in order to use them to draw on the image.
The function for creating the matrix is an opencv function.
CvMat* mat = cvCreateMat(20,2,CV_32FC1);
which this matrix has the values of frame features in x,y. I have used this code to print it out:
float t[20][2];
for (int k1=0; k1<20; k1++) {
for (int k2=0; k2<2; k2++) {
t[k1][k2] = cvmGet(mat,k1,k2);
std::cout<< t[k1][k2]<<"\t";
}
}
std::cout <<" "<< std::endl;
std::cout <<" "<< std::endl;
std::cout <<" "<< std::endl;
This code work out well, but as I mentioned above guys, that I want to sign the values to a parameters in order to use them?
Do you want something like this:
void GetMatrixElem( float t [][2] ,int x ,int y ,float** val )
{
if (val) // && (x >= 0) && (x < 20) && (y>=0) && (y<2)
*val = &t[x][y];
}
// ...
float t [20][2];
float* pElem = NULL;
GetMatrixElem( t ,10 ,1 ,&pElem );
for Columns and Rows you can use something like this:
void GetClmn( float t[][2] ,int y ,float* pClmn[] )
{
for( int x = 0; x < 20; x++ )
{
pClmn[x] = &t[x][y];
}
}
void GetRow( float t[][2] ,int x ,float* pRow[] )
{
for( int y = 0; y < 2; y++ )
{
pRow[y] = &t[x][y];
}
}
Usage:
float* pClm[20];
GetClmn( t ,1 ,pClm);
float* pRow[2];
GetRow( t ,19 ,pRow );
Related
I send array int Vetor[33]; by parameter for the function MontaVetorVerticalOtimizado(x, y, Vetor), inside this the array is filled, the problem is that after filling the array all the variables of the function OtimizaVerticalDentina() are signed with the value of the array, it seems confusing, so I added images while debugging to make it more understandable:
First function:
void OtimizaVerticalDentina() {
int Vetor[33];
int x, y;
for (x = 1; x < NewImage.SizeX() - 1; x++)
{
for (y = 10; y < NewImage.SizeY() - 10; y++)
{
MontaVetorVerticalOtimizado(x, y, Vetor);
VerificaIntensidadeVetorVerticalOtimizado(Vetor);
if (bPreenche) {
NewImage.DrawPixel(x, y, 255, 255, 255);
} else {
NewImage.DrawPixel(x, y, 0, 0, 0);
bPreenche = true;
}
}
}
}
Second function:
void MontaVetorVerticalOtimizado(int Px, int Py, int Vetor[33])
{
int x, y;
int i = 0;
unsigned char r, g, b;
for(x = Px - 1; x <= Px + 1; x++)
{
for(y = Py - 10; y <= Py + 10; y++)
{
NewImage.ReadPixel(x, y, r, g, b);
Vetor[i] = r;
i++;
}
}
}
Note:
ImageClass NewImage; // global
Before filling the array variables are with their normal value
After populating the array the variables are with another value (the value that was added in the vector)
*I have created other variables in the first method to test and they have also changed, does anyone have any idea what might be happening?
The only explanation I can find is that you have a buffer overrun. That is is you are writing to this array (Vetor) which is not big enough and happen to overwrite unrelated memory in the process. In this case specifically you are overwriting the value of the variables x and y of the calling function.
I have demo here:
#include <iostream>
void bar(int* arr)
{
for (int i = 0; i <= 35; i++) arr[i] = 255;
}
void foo()
{
int arr[33];
int x;
for (x = 0; x < 5; x++)
{
std::cout << x << '\n';
bar(arr);
std::cout << x << '\n';
}
}
int main()
{
foo();
return 0;
}
This produces: 0 255 and immediately terminates because the loop variable got overwritten and the subsequent x < 5 check fails. You either have to increase the size of the array (if it turns out it was too small) or make sure you index within its bounds.
I have two grey scale images in txt files, one being a smaller block of the Main image. I have read the images into two different 2d vector matrices.
The Rows and the Columns of the images are:
Main: M = 768 N = 1024
SubImg: R = 49 C = 36
int R = 49; int C = 36; //Sub Image Rows / Columns
int M = 768; int N = 1024; //Main Image Rows / Columns
I have looped through the Main image by blocks of width: 49 and height: 36 and I want to put each block into an array, so I can compare the array with the Sub image (using Nearest Neighbor Search) to see which block has the closest result to the Sub image.
This is the code for loop of the Main image:
for (double bx = 0; bx < M; bx += R)
for (double by = 0; by < N; by += C)
{
for (int x = 0; ((x < R) && ((bx + x) < M)); ++x)
{
for (int y = 0; ((y < C) && ((by + y) < N)); ++y)
{
if ((bx + x) >= M)
{
std::cout << (bx + x) << (by + y) << " ";
}
cout << MainIMG_2DVector[bx + x][by + y] << " ";
}
}
cout << "\n\n\n" << endl;
}
This loop displays all the blocks in one go. The problem I'm having is that I don't know how to put each block into an array, so I can compare the data.
Also is it better to use a pointer instead of an array to do this?
Thanks
I'm not sure exactly how you want to compare the blocks, but as far as storing the blocks, you can make a simple Block object like this:
const double R = 49, C = 36;
// Block object (takes in your image 2D vector and x/y coordinates)
class Block {
public:
Block(std::vector<std::vector<int>> *img_vector, int bx, int by);
int compare(const Block &block) const;
private:
std::vector<std::vector<int>> *img_vector;
int bx, by;
};
Block::Block(std::vector<std::vector<int>> *img_vector, int bx, int by) {
this->img_vector = img_vector;
this->bx = bx;
this->by = by;
}
// Compare any two blocks
int Block::compare(const Block &block) const {
for (int x = bx; x < bx + R; x++) {
for (int y = by; y < by + C; y++) {
// Do some comparing
std::cout << "Compare " << (*img_vector)[x][y]
<< " with " << (*block.img_vector)[x][y] << std::endl;
}
}
return 0; // Return some value that indicates how they compare
}
And then add the image blocks to a vector:
// Add main image blocks to vector
std::vector<Block> main_img_blocks;
for (double bx = 0; bx < M; bx += R) {
for (double by = 0; by < N; by += C)
main_img_blocks.push_back(Block(&MainIMG_2DVector, bx, by));
}
// Do the same for sub image blocks...
// Invoke the compare function between 2 blocks at a time
int comp_value = main_img_blocks[0].compare(main_img_blocks[1]);
Hope that helps :)
I'm writing a code in C++ for a 2D Ising model. Here's what the code should do:
Generate random NxN lattice, with each site either +1 or -1 value.
Select a site at random
If site when flipped (+1 to -1 or -1 to +1) is a state of lower energy, flip state ie. if dE < 0, flip state. If flipped state is of higher energy, flip with acceptance rate w = e^{-b(dE)}. Where dE is the change in energy if state is flipped.
4.Do this for all NxN sites, without repetition. This is considered one sweep.
Do like 100 sweeps.
I'm having trouble with steps 1, 2 and 3, would appreciate any help! For step 1, I managed to create and display a lattice, but I can't seem to extract the value of a site at location (x, y). Steps 2 and 3, how do I use a boolean expression of some sort to flip according to acceptance probability?
#include <cstdlib>
#include <ctime>
using namespace std;
#include <iostream>
int main() //random generation of spin configuration
{
int L; //Total number of spins L = NxN
int N = 30 //A square lattice of length 30
double B=1; //magnetic field
double M; //Total Magnetization = Sum Si
double E; //Total Energy
int T = 1.0;
int nsweeps = 100; //number of sweeps
int de; //change in energy when flipped
double Boltzmann; //Boltzmann factor
int x,y; //randomly chosen lattice site
int i,j,a,c; //counters
int ROWS = 5;
int COLS = 5;
int matrix[ROWS][COLS];
srand ( static_cast<unsigned> ( time ( 0 ) ) );
for ( int i = 0; i < ROWS; i++ )
{
for ( int j = 0; j < COLS; j++ )
{
matrix[i][j] = rand () % 2 *2-1;
}
}
// showing the matrix on the screen
for(int i=0;i<ROWS;i++) // loop 3 times for three lines
{
for(int j=0;j<COLS;j++) // loop for the three elements on the line
{
cout<<matrix[i][j]; // display the current element out of the array
}
cout<<endl; // when the inner loop is done, go to a new line
}
return 0; // return 0 to the OS.
//boundary conditions and range
if(x<0) x += N;
if(x>=L) x -= N;
if(y<0) y += N;
if(y>=L) y -= N;
//counting total energy of configuration
{ int neighbour = 0; // nearest neighbour count
for(int i=0; i<L; i++)
for(int j=0; j<L; j++)
{ if(spin(i,j)==spin(i+1, j)) // count from each spin to the right and above
neighbour++;
else
neighbour--;
if(spin(i, j)==spin(i, j+1))
neighbour++;
else
neighbour--;
}
E = -J*neighbour - B*M;
//flipping spin
int x = int(srand48()*L); //retrieves spin from randomly choosen site
int y = int(srand48()*L);
int delta_M = -2*spin(x, y); //calculate change in Magnetization M
int delta_neighbour = spin(spinx-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
int delta_neighbour = -2*spin(x,y)* int delta_neighbour;
double delta_E = -J*delta_neighbour -B*delta_M;
//flip or not
if (delta_E<=0)
{ (x, y) *= -1; // flip spin and update values
M += delta_M;
E += delta_E;
}
}
To follow up on my comment:
There are too many issues with your code for a single answer. Try to
build your program step by step. Use functions which perform one
thing, and this they do well. Test each function individually and if
necessary try to find out why it does not work. Then post specific
questions again.
To get you started:
Store your lattice as a std::vector<int> lattice(N*N)
Access element (x,y) with data[x+N*y].
Example:
#include <vector>
struct IsingModel
{
unsigned size_;
std::vector<int> lattice_;
// access element (x,y)
int& at(int x, int y) {
return lattice_[x + y*size_];
}
int at(int x, int y) const {
return lattice_[x + y*size_];
}
// generate size x size lattice
IsingModel(unsigned size)
: size_(size), lattice_(size*size, +1) {
}
static int BoolToSpin(bool v) {
return v ? +1 : -1;
}
// initialize spin randomly
void initializeRandom() {
for(int y=0; y<size_; y++) {
for(int x=0; x<size_; x++) {
at(x,y) = BoolToSpin(rand()%2);
}
}
}
static int Energy(int a, int b) {
return (a == b) ? +1 : -1;
}
// compute total energy
unsigned computeTotalEnergy() const {
unsigned energy = 0;
for(int y=1; y<size_-1; y++) {
for(int x=1; x<size_-1; x++) {
energy += Energy(at(x,y), at(x+1,y));
energy += Energy(at(x,y), at(x,y+1));
}
}
return energy ;
}
};
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
srand(static_cast<unsigned>(time(0))); // intialize random number generator
IsingModel im(10);
im.initializeRandom();
unsigned energy = im.computeTotalEnergy();
std::cout << energy << std::endl; // print energy
}
I have this equation
and
then find the polynomial from
I am trying to implement it like this:
for (int n=0;n<order;n++){
df[n][0]=y[n];
for (int i=0;i<N;i++){ //N number of points
df[n][i]+=factorial(n,i)*y[i+n-1];
}
}
for (int i=0;i<N;i++){
term=factorial(s,i);
result*=df[0][i]*term;
sum+=result;
}
return sum;
1) I am not sure how to implement the sign of every argument in the function.As you can see it goes 'positive' , 'negative', 'positive' ...
2) I am not sure for any mistakes...
Thanks!
----------------------factorial-----------------------------
int fact(int n){
//3!=1*2*3
if (n==0) return 1;
else
return n*fact(n-1);
}
double factorial(double s,int n){
//(s 3)=s*(s-1)*(s-2)/6
if ((n==0) &&(s==0)) return 1;
else
return fact(s)/fact(n);
}
The simplest solution is probably to just keep the sign in
a variable, and multiply it in each time through the loop.
Something like:
sign = 1.0;
for ( int i = 0; i < N; ++ i ) {
term = factorial( s, i );
result *= df[0][i] * term;
sum += sign * result;
sign = - sign;
}
You cannot do pow( -1, m ).
You can write your own:
inline int minusOnePower( unsigned int m )
{
return (m & 1) ? -1 : 1;
}
You may want to build up some tables of calculated values.
Well, I understand you want to approximately calculate the value f(x) for a given x=X, using Newton Interpolation polynomial with equidistant points (more specifically Newton-Gregory forward difference interpolation polynomial).
Assuming s=(X-x0)/h, where x0 is the first x, and h the step to obtain the rest of the x for which you know the exact value of f :
Considere:
double coef (double s, int k)
{
double c(1);
for (int i=1; i<=k ; ++i)
c *= (s-i+1)/i ;
return c;
}
double P_interp_value(double s, int Num_of_intervals , double f[] /* values of f in these points */) // P_n_s
{
int N=Num_of_intervals ;
double *df0= new double[N+1]; // calculing df only for point 0
for (int n=0 ; n<=N ; ++n) // n here is the order
{
df0[n]=0;
for (int k=0, sig=-1; k<=n; ++k, sig=-sig) // k here is the "x point"
{
df0[n] += sig * coef(n,k) * f[n-k];
}
}
double P_n_s = 0;
for (int k=0; k<=N ; ++k ) // here k is the order
{
P_n_s += coef(s,k)* df0[k];
}
delete []df0;
return P_n_s;
}
int main()
{
double s=0.415, f[]={0.0 , 1.0986 , 1.6094 , 1.9459 , 2.1972 };
int n=1; // Num of interval to use during aproximacion. Max = 4 in these example
while (true)
{
std::cin >> n;
std::cout << std::endl << "P(n=" << n <<", s=" << s << ")= " << P_interp_value(s, n, f) << std::endl ;
}
}
it print:
1
P(n=1, s=0.415)= 0.455919
2
P(n=2, s=0.415)= 0.527271
3
P(n=3, s=0.415)= 0.55379
4
P(n=4, s=0.415)= 0.567235
compare with:
http://ecourses.vtu.ac.in/nptel/courses/Webcourse-contents/IIT-KANPUR/Numerical%20Analysis/numerical-analysis/Rathish-kumar/rathish-oct31/fratnode8.html
It works. Now we can start to optimize these code.
just for the sign ;-)
inline signed int minusOnePower( unsigned int m )
{
return 1-( (m & 1)<<1 );
}
Here's my code.
#include <iostream>
using namespace std;
enum Direction { EAST, NORTH, WEST, SOUTH };
const int size = 12;
int xStart = 2; int yStart = 0;
char *maze2[ ] = {
"############",
"#...#......#",
"..#.#.####.#",
"###.#....#.#",
"#....###.#..",
"####.#.#.#.#",
"#..#.#.#.#.#",
"##.#.#.#.#.#",
"#........#.#",
"######.###.#",
"#......#...#",
"############",
};
void printMaze ( char maze[][ size ] );
void mazeTraverse( char maze[][ size ], int x, int y, int direction );
int main()
{
char maze[ size ][ size ];
for (int x = 0; x < size; x++ )
for (int y = 0; y < size; y++)
maze[ x ][ y ] = maze2[ x ][ y ];
printMaze( maze );
mazeTraverse( maze, xStart, yStart, EAST);
}
void printMaze ( char maze[][ size ] )
{
for ( int x = 0; x < size; x++)
{
for ( int y = 0; y < size; y++)
cout << maze[ x ][ y ];
cout << endl;
}
cout << endl;
cout << "\nHit return to see next move\n";
cin.get();
}
bool validMove( char maze[][ size ], int x, int y )
{
return x >= 0 && x < size && y >= 0 && y < size && maze[x][y] != '#';
}
bool coordsAreEdge( int x, int y )
{
return x== 0 || x== size - 1 || y == 0 || y== size - 1;
}
void mazeTraverse( char maze[][ size ], int x, int y, int direction )
{
maze[ x ][ y ] = 'x';
printMaze( maze );
if (coordsAreEdge(x, y) && (x != xStart || y!= yStart ))
{
cout <<"\nMaze successfully exited!\n\n";
return;
}else{
for ( int move = direction, count = 0; count < 4;
count++, move++, move %=4 )
{
int nextX; int nextY;
switch ( move )
{
case SOUTH: nextX = x + 1; nextY = y; break;
case EAST: nextX = x; nextY = y + 1; break;
case NORTH: nextX = x - 1; nextY = y; break;
case WEST: nextX = x; nextY = y - 1; break;
default: ;
}
if (validMove( maze, nextX, nextY ))
{
//Recursion move part 1
//mazeTraverse ( maze, nextX , nextY, (move + 3)%4 );
return;
}
}
}
}
I'm trying to make my void mazeTraverse function a while loop, instead of the recursion and I'm stuck.
Create a struct to hold X, Y and direction (the three things that change between calls). We'll call that struct State;
Create a std::stack<State> object. Push the current values of X,Y, direction onto the stack before you change them, pop them after you do your work.
hence
while(.....)
{
push state
Do work of mazeTraverse
pop state
}
It would've been nice if you described how the traversal works. If I'm not reading the code wrong, you are basically moving south/east/north/west on any position that doesn't contain a # and is within the bounds of the matrix.
You can do this iteratively by using a BF search: http://en.wikipedia.org/wiki/Breadth-first_search or, applied to a matrix, the Lee algorithm: http://en.wikipedia.org/wiki/Lee_algorithm which can be efficiently implemented using a FIFO queue, which I describe how to do here: Change FloodFill-Algorithm to get Voronoi Territory for two data points?
Your validMove function will stay the same: you add a position to the queue only if that position is valid. Basically all checks stay the same, just that you use a FIFO queue to hold your states instead of an implicit stack.
You could use a breadth-first search instead using a standard queue and while loop.
typedef pair<int, int> Point;
queue<Point> path;
Point start(xStart, yStart);
path.push(start);
const int move_x[] = {-1, 0, 1, 0};
const int move_y[] = {0, -1, 0, 1};
while (!path.empty())
{
Point p = path.front();
int x = p.first, y = p.second;
maze[x][y] = 'x';
path.pop();
if (coordsAreEdge(x,y) && p != start)
{
// Finished
break;
}
for (int i = 0; i < 4; ++i)
{
int newx = x + move_x[i];
int newy = y + move_y[i];
if (validMove(maze, newx, newy))
path.push(Point(newx, newy));
}
}
That should do the trick. Note that it's untested though.
You can improve its performance by using A* instead, but that's a little more complex. Let me know if you need to find the shortest path from this code as well.
EDIT: Note that if you change the queue to a stack (and change path.front() to path.top()) then you'll get a depth-first search (DFS) instead, which is what your code does. The DFS, however, doesn't find the shortest path (if that is necessary).