I have a matrix
and I should write code using Gauss-Seidel and coupled gradient methods taking the structure of the matrix.
Ax = e where A is matrix and e is vector with values of 1
I don't know how to write code using coupled gradient methods and my Gauss-Seidel algorithm don't have main part where I add this all thinks
//part of gauss-seidel method
const int N = 128; //size of array
const int no_of_iter = 128; //iterations
int main() {
double result[N]; //array for result
double result_pom[N]; //temporary result array
double sum = 0.0;
int x, y;
for (int i = 0; i < no_of_iter; i++) {
for (y = 0; y < N; y++) {
result_pom[y] = result[y]; //set values of result to result_pom
}
for (x = 0; x < N; x++) {
sum = 0.0;
//for functions where I add (x,y) el
result[x] = 0.25 * (1 - sum); //because 4 is dominant el of matrix and
//1 is value of vector e
}
}
}
Related
I'm trying to do a normalization of data for a polinomial interpolation with perceptron, I'm using the following formula:
Where:
xi is a data point (x1, x2…xn).
x̄ is the sample mean.
s is the sample standard deviation.
and Z is my new value of input for the perceptron.
I'm programming in C ++, and plotting graph with freeglut.
My function for normalize:
vector<double> Perceptron::normalizar(double x) {
vector<double> aux;
aux.push_back(1.0);
for (unsigned i = 1; i < pesos.size(); i++) {
double t = (pow(x,i) - means[i]) / devianation[i];
aux.push_back(t);
}
return aux;
}
The problem is: before I did the normalization, the polynomial was converging to the points.
But after normalization, the polynomial is converging to other points, and I do not know where it is converging.
The formula for the polynomial would be as follows (with W being the weights of the perceptron):
So I used a mean formula for each value of x.
See the code:
void Perceptron::mean(Points P) { //P is a struct with all x and y values of the points.
means.clear(); //vector that stores the means
for (unsigned i = 0; i < weights.size(); i++) {
double m = 0;
for (unsigned j = 0; j < P.size(); j++) {
m += pow(P[i].x, i);
}
means.push_back(m / P.size());
}
}
void Perceptron::deviation(Points P) {
deviations.clear(); //vector that stores the deviations
for (unsigned i = 0; i < weights.size(); i++) {
double sd = 0;
for (unsigned j = 0; j < P.size(); j++) {
sd += pow(pow(P[j].x, i) - means[i], 2);
}
deviations.push_back(sqrt(sd / P.size()));
}
}
The code inside the for loop is for the x and y (j and i) "coordinates" from a 2d array. How could I implement this neighbor/index finding in a 1d array?
I think I could implement it for the first four equations. But i'm confused as how to implement up-left etc.
for(int i=0; i<cols*rows; i++){
//Counts current index's 8 neigbour int values
int count=0;
int x = i%cols;
int y = i/rows;
//rows y i
//cols x j
count+= [grid][i][(j-1+cols)%cols] //left
+[grid][i][(j+1+cols)%cols] //right
+[grid][(i-1+rows)%rows][j] //up
+[grid][(i+1+rows)%rows][j] //down
+[grid][(i-1+rows)%rows][ (j-1+cols)%cols] //up-left
+[grid][(i+1+rows)%rows][ (j+1+cols)%cols] //down-right
+[grid][(i+1+rows)%rows][ (j-1+cols)%cols] //down-left
+[grid][(i-1+rows)%rows][ (j+1+cols)%cols] ;//up-right
}
Starting with a 1-D vector:
int rows = 10;
int cols = 10;
vector<int> grid(rows * cols);
You can manage this in different ways, example
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < cols; x++)
{
int point = grid[y * rows + x];
}
}
Where you can access any point at any given x and y in a 2-dimensional plane.
Top-left is:
x = 0;
y = 0;
bottom-right is
x = cols - 1;
y = rows - 1;
And so on.
Use a function like this
inline int idx(const int i, const int j, const int rows) const
{
return i * rows + j;
}
to convert the 2d indices to 1d indices.
This way you don't have to change your algorithm.
Usage would be grid[idx(i, (j-1+cols)%cols, rows)].
The basic formula for computing the 1d coordinate from the 2d index pattern is usually one of the following:
row_index * row_length + column_index
column_index * column_length + row_index
Which one applies to your case depends on whether you would like to have a row-based or column-based memory layout for your 2d array. It makes sense to factor out the computation of this index into a separate function, as suggested in the other answer.
Then you just need to fill in the values somehow.
You could do it like this, for example:
// iterate big picture
// TODO: make sure to handle the edge cases appropriately
for (int i_row = 1; i_row < n_rows - 1; i_row++) {
for (int i_col = 1; i_col < n_cols -1; i_col++) {
// compute values
dst[i_row*n_cols+i_col] = 0;
for (int r = i_row-1; r < i_row+2; r++) {
for (int c = i_col-1; c < i_col+2; c++) {
dst[i_row*n_cols+i_col] += src[r*n_cols + c];
}
}
}
}
Assuming src and dst are distinct 1d vectors of size n_rows*n_cols...
I want to assign value to a 3 dimensional array in opencv but don't know how to do it.
here is the code in matlab that I want to write in opencv
vv = zeros(800,600,2);
for j1=1:m1
for j2=1:m2
w=[-k;vv(j1,j2,1);vv(j1,j2,2)];
w=w/norm(w);
end
end
and this is what I did in opencv, but did not work
int dim2[3] = {800,600,2};
Mat vv(3,dim2,CV_32F,Scalar::all(0));
for(int j1 = 0; j1 < 800; j1++)
{ for(int j2 = 0; j2 < 600; j2++)
{
Mat w(3,dim2,CV_32F, Scalar(1,vv(j1,j2,1),vv(j1,j2,2)));
}
}
use the following syntax:
//initizlizes a matrix zeros, of size 800x600x2
cv::Mat vv = cv::Mat::zeros(cv::Size(600, 800), CV_32FC2);
//do some calculations on vv
//opencv version of the for loop
for (int y = 0; y < vv.rows; y++)
{
for (int x = 0; x < vv.cols; x++)
{
//access indices (y,x,1) and (y,x,2)
cv::Vec2f wVec = vv.at<cv::Vec2f>(cv::Point(x, y));
//calculates the norm
cv::Point3f w(3, wVec[0], wVec[1]);
double normW = cv::norm(w);
//divides w by it's norm. don't forget to verify that normW is not 0
w = w / normW;
//do something with the calculated w vector
}
}
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 am trying to get all x,y within ANY polygon shape in c++
for e.g I have a rectangle that has the following cordinates,
Point 1:
X = 5
Y = 10
Point 2:
X = 5
Y = 8
Point 3:
X = 9
Y = 8
Point 4:
X = 9
Y = 10
so the cordinates within polygon base on the 4 points given will be
X = 6 Y = 9
X = 7 Y = 9
X = 8 Y = 9
I found this from http://alienryderflex.com/polygon/
bool pointInPolygon() {
int i, j=polySides-1;
bool oddNodes=NO;
for (i=0; i<polySides; i++) {
if (polyY[i]<y && polyY[j]>=y
|| polyY[j]<y && polyY[i]>=y) {
if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
oddNodes=!oddNodes; }}
j=i;
}
return oddNodes;
}
and even this http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) {
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
In fact most of my search results I found will have something similar to the codes(shown above). from what I understand, the code(shown above) will only return you a true/false if the point is within the polygon and does not return any cords that is found within the polygon.
Run a flood fill on your polygon and record all of the points with integer coordinates as you go along.
This works for a general polygon.
If you have a function bool pointInPolygon(polygon *pol, int point_x, int point_y), you can do:
int x_min, x_max; // determines x min and max of your polygon
int y_min, y_max; // determines y min and max of your polygon
int i, j;
...
for(i = x_min; i < x_max; i++) {
for(j = y_min; j < y_max; j++) {
if(pointInPolygon(pol, i, j)) {
// add the point (i, j) in an array
}
}
}
It works well while you work with 2D.