Ok I have a little problem with my code. This error disp when I try run it.
Unhandled exception at 0x012D4CBF in Dywan.exe: 0xC0000005: Access violation reading location 0x015E2348.
When ROZMIAR=257 or less then code works properly. But i need set higher value like 500. Error stucked at double odcien = dane[x][y] + dane[x + dlboku][y] + dane[x][y + dlboku] + dane[x + dlboku][y + dlboku];
Should i use dynamic arrays to this ?
double dane[ROZMIAR][ROZMIAR];
double wartoscinit = 0.0;
dane[0][0] = dane[0][ROZMIAR - 1] = dane[ROZMIAR - 1][0] = dane[ROZMIAR -1][ROZMIAR - 1] = wartoscinit;`
void comp_Fractal(){
for (int dlboku = ROZMIAR - 1; dlboku >= 2; dlboku /= 2, h /= 2.0) {
int polboku = dlboku / 2;
for (int x = 0; x<ROZMIAR - 1; x += dlboku) {
for (int y = 0; y<ROZMIAR - 1; y += dlboku) {
double odcien = dane[x][y] + dane[x + dlboku][y] + dane[x][y + dlboku] + dane[x + dlboku][y + dlboku];
odcien /= 4.0;
double wzor = (-h) + rand() * (2*h) / RAND_MAX;
dane[x + polboku][y + polboku] = odcien + wzor;
}
}
for (int x = 0; x<ROZMIAR - 1; x += polboku) {
for (int y = (x + polboku) % dlboku; y<ROZMIAR - 1; y += dlboku) {
double odcien =
dane[(x - polboku + ROZMIAR) % ROZMIAR][y] +
dane[(x + polboku) % ROZMIAR][y] +
dane[x][(y + polboku) % ROZMIAR] +
dane[x][(y - polboku + ROZMIAR) % ROZMIAR];
odcien /= 4.0;
double wzor = (-h) + rand() * (2*h) / RAND_MAX;
odcien = odcien + wzor;
dane[x][y] = odcien;
if (x == 0) dane[ROZMIAR - 1][y] = odcien;
if (y == 0) dane[x][ROZMIAR - 1] = odcien;
}
}
}
for (int i = 0; i<ROZMIAR - 1; i++)
for (int j = 0; j<ROZMIAR - 1; j++) {
if (dane[i][j] > maxY)
maxY = dane[i][j];
if (dane[i][j] < minY)
minY = dane[i][j];
}
}
When both dlboku, y and x are something like ROZMIAR - 2, following
dane[x + dlboku][y + dlboku];
will make you to access dane[ROZMIAR + ROZMIAR - 4][ROZMIAR + ROZMIAR - 4] which is out of bounds. You alvays had a problem with your code. It just large values of ROZMIAR which made it access out of allocated memory and crash.
Related
Hello I have tried to entering n division number by a number or a constant.
Here is the code:
}
int main()
{
//The main problem in below
int n_temp;
std::cout << "Please enter the division number";
std::cin >> n_temp;
const unsigned int n = n_temp;
int const iter_n = 10;
double const dx = L / (n - 1);
double T[n];
double P[n], Q[n];
double kP, kE, kW, ke, kw, Sp, Sc;
double a[n], b[n], c[n], d[n];
T[0] = 300; T[n - 1] = 1000;
for (int i = 1; i < n - 1; i++) { T[i] = 500; }
std::cout << "T= ["; for (double T_i : T) { std::cout << T_i << ","; } std::cout << "]\n";
for (int iter = 0; iter < iter_n; iter++) {
a[0] = 1; b[0] = 0; c[0] = 0; d[0] = T[0];
a[n - 1] = 1; b[n - 1] = 0; c[n - 1] = 0; d[n - 1] = T[n - 1];
for (int i = 1; i < n - 1; i++) {
float x = i * dx;
Sp = Spv(T[i], x);
Sc = Scv(T[i], x);
kP = kv(T[i], x);
kE = kv(T[i + 1], x + dx);
kW = kv(T[i - 1], x - dx);
ke = 2 * kP * kE / (kP + kE);
kw = 2 * kP * kW / (kP + kW);
b[i] = ke / dx;
c[i] = kw / dx;
a[i] = b[i] + c[i] + Sp * dx;
d[i] = Sc * dx;
}
P[0] = 0;
Q[0] = d[0];
for (int i = 1; i < n; i++) {
P[i] = b[i] / (a[i] - c[i] * P[i - 1]);
Q[i] = (c[i] * Q[i - 1] + d[i]) / (a[i] - c[i] * P[i - 1]);
}
for (int i = n - 2; i > 0; i--) {
T[i] = P[i] * T[i + 1] + Q[i];
}
std::cout << "T =["; for (double T_i : T) { std::cout << T_i << ","; } std::cout << "]\n";
}
return 0;
}
Here is the revised version which is after reviewing comments. There are some errors that appear in the T. For example E2291,C3536, C2893, C2784, C2672,C2100 Thanks.
int main()
{
int n_temp;
std::cout << "Please enter the division number";
std::cin >> n_temp;
const unsigned int n = n_temp;
int const iter_n = 10;
double const dx = L / (n - 1);
double*T= new double[n];
double*P = new double[n];
double*Q= new double[n];
double kP, kE, kW, ke, kw, Sp, Sc;
double*a= new double[n];
double*b = new double[n];
double* c = new double[n];
double* d = new double[n];
T[0] = 300; T[n - 1] = 1000;
for (int i = 1; i < n - 1; i++) { T[i] = 500; }
std::cout << "T= ["; for (double T_i : T) { std::cout << T_i << ","; } std::cout << "]\n";
for (int iter = 0; iter < iter_n; iter++) {
a[0] = 1; b[0] = 0; c[0] = 0; d[0] = T[0];
a[n - 1] = 1; b[n - 1] = 0; c[n - 1] = 0; d[n - 1] = T[n - 1];
for (int i = 1; i < n - 1; i++) {
float x = i * dx;
Sp = Spv(T[i], x);
Sc = Scv(T[i], x);
kP = kv(T[i], x);
kE = kv(T[i + 1], x + dx);
kW = kv(T[i - 1], x - dx);
ke = 2 * kP * kE / (kP + kE);
kw = 2 * kP * kW / (kP + kW);
b[i] = ke / dx;
c[i] = kw / dx;
a[i] = b[i] + c[i] + Sp * dx;
d[i] = Sc * dx;
}
P[0] = 0;
Q[0] = d[0];
for (int i = 1; i < n; i++) {
P[i] = b[i] / (a[i] - c[i] * P[i - 1]);
Q[i] = (c[i] * Q[i - 1] + d[i]) / (a[i] - c[i] * P[i - 1]);
}
for (int i = n - 2; i > 0; i--) {
T[i] = P[i] * T[i + 1] + Q[i];
}
std::cout << "T =["; for (double T_i : T) { std::cout << T_i << ","; } std::cout << "]\n";
delete[]T;
}
return 0;
}
test_euclid_ask.h (only need to read 2 functions: euclid_slow, euclid_fast)
#pragma once
#include "included.h"
double
euclid_slow(int n, double* data1, double* data2, int* mask1, int* mask2, const double weight[])
{
double result = 0.0;
double totalWeight = 0;
for (int i = 0; i < n; i++) {
if (mask1[i] && mask2[i]) {
double term = data1[i] - data2[i];
result += weight[i] * term * term;
totalWeight += weight[i];
}
}
if (totalWeight==0) return 0;
return result / totalWeight;
}
double
euclid_fast(int n, double* data1, double* data2, int* mask1, int* mask2, const double weight[])
{
double result = 0.0;
double totalWeight = 0;
double subResult[4] = { 0. };
double subTweight[4] = { 0. };
double subDiff[4] = { 0. };
double subWeight[4] = { 0. };
double subMask[4] = { 0. };
int nstep4 = n - n % 4;
for (int i = 0; i < nstep4; i += 4) {
subMask[0] = mask1[i] && mask2[i];
subMask[1] = mask1[i + 1] && mask2[i + 1];
subMask[2] = mask1[i + 2] && mask2[i + 2];
subMask[3] = mask1[i + 3] && mask2[i + 3];
if (!(subMask[0] || subMask[1] || subMask[2] || subMask[3])) continue;
subDiff[0] = data1[i] - data2[i];
subDiff[1] = data1[i + 1] - data2[i + 1];
subDiff[2] = data1[i + 2] - data2[i + 2];
subDiff[3] = data1[i + 3] - data2[i + 3];
subDiff[0] *= subDiff[0];
subDiff[1] *= subDiff[1];
subDiff[2] *= subDiff[2];
subDiff[3] *= subDiff[3];
subWeight[0] = weight[i] * subMask[0];
subWeight[1] = weight[i + 1] * subMask[1];
subWeight[2] = weight[i + 2] * subMask[2];
subWeight[3] = weight[i + 3] * subMask[3];
subTweight[0] += subWeight[0];
subTweight[1] += subWeight[1];
subTweight[2] += subWeight[2];
subTweight[3] += subWeight[3];
subResult[0] += subWeight[0] * subDiff[0];
subResult[1] += subWeight[1] * subDiff[1];
subResult[2] += subWeight[2] * subDiff[2];
subResult[3] += subWeight[3] * subDiff[3];
}
for (int i = nstep4; i < n; i++) {
if (mask1[i] && mask2[i]) {
double term = data1[i] - data2[i];
result += weight[i] * term * term;
totalWeight += weight[i];
}
}
result += subResult[0] + subResult[1] + subResult[2] + subResult[3];
totalWeight += subTweight[0] + subTweight[1] + subTweight[2] + subTweight[3];
//cout << "end fast\n";
if (!totalWeight) return 0;
return result / totalWeight;
}
void test_euclid_ask()
{
const int MAXN = 10000000, MINN = 1000000;
double* data1, * data2;
int* mask1, * mask2;
double* dataPro1, * dataPro2;
int* maskPro1, * maskPro2;
double *weight, * weightPro;
//***********
data1 = new double[MAXN + MINN + 1];
data2 = new double[MAXN + MINN + 1];
mask1 = new int[MAXN + MINN + 1];
mask2 = new int[MAXN + MINN + 1];
dataPro1 = new double[MAXN + MINN + 1];
dataPro2 = new double[MAXN + MINN + 1];
maskPro1 = new int[MAXN + MINN + 1];
maskPro2 = new int[MAXN + MINN + 1];
// ******
weight = new double[MAXN + MINN + 1];
weightPro = new double[MAXN + MINN + 1];
MyTimer timer;
int n;
double guess1, guess2, tmp, total1 = 0, total2 = 0, prev1 = 0, prev2 = 0;
for (int t = 5000; t < 6000; t++) {
if (t <= 5000) n = t;
else n = MINN + rand() % (MAXN - MINN);
cout << n << "\n";
int index = 0;
for (int i = 0; i < n; i++) {
weight[i] = int64(randomed()) % 100;
data1[i] = int64(randomed()) % 100;
data2[i] = int64(randomed()) % 100;
mask1[i] = rand() % 10;
mask2[i] = rand() % 10;
}
memcpy(weightPro, weight, n * sizeof(double));
memcpy(dataPro1, data1, n * sizeof(double));
memcpy(dataPro2, data2, n * sizeof(double));
memcpy(maskPro1, mask1, n * sizeof(int));
memcpy(maskPro2, mask2, n * sizeof(int));
//****
int tmp = flush_cache(); // do something to ensure the cache does not contain test data
cout << "ignore this " << tmp << "\n";
timer.startCounter();
guess1 = euclid_slow(n, data1, data2, mask1, mask2, weight);
tmp = timer.getCounterMicro();
total1 += tmp;
cout << "time slow = " << tmp << " us\n";
timer.startCounter();
guess2 = euclid_fast(n, dataPro1, dataPro2, maskPro1, maskPro2, weightPro);
tmp = timer.getCounterMicro();
total2 += tmp;
cout << "time fast = " << tmp << " us\n";
bool ok = fabs(guess1 - guess2) <= 0.1;
if (!ok) {
cout << "error at N = " << n << "\n";
exit(-1);
}
cout << "\n";
}
cout << "slow speed = " << (total1 / 1000) << " ms\n";
cout << "fast speed = " << (total2 / 1000) << " ms\n";
}
Basically, the function computes a kind-of Euclidean distance between 2 arrays:
result = sum(weight[i] * (data1[i] - data2[i])^2)
but only in positions where both values are available (mask1[i]==0 means it's ignored, same with mask2). The normal code is in function euclid_slow.
So I tried to improve the code by processing 4 elements at once, hoping that SSE/AVX can speed this up. However, the result stays the same or slower(using g++ -O3 -march=native) or becomes 40% slower (using Visual Studio 2019 compiler, release mode (x64), -O2, AVX2 enabled). I tried both -O2 and -O3, same result.
The compiler made better optimizations than what I wrote. But how can I make it actually faster?
Edit: code to test the programs here
I am newbie and having work with connected components labelling algorithm.
My purpose is that I need to find out 3 block of light points and then calculate the coordinates of the central point of each block (kind of image processing).
But after I run the for loop, I got the same coordinate for all the central points of three blocks, and don't know what was going wrong.
Could someone here please help me!
Thanks a lot!
This is my code
for (size_t i = 0; i < 128; i++)
{
for (size_t j = 0; j < 128; j++)
{
if (pInt[i * 128 + j] <= 18000) label[i][j] = 0;
if (pInt[i * 128 + j] > 18000)
{
if (label[i-1][j-1] != 0)
{
label[i][j] = label[i-1][j-1];
}
if (label[i-1][j] != 0)
{
label[i][j] = label[i-1][j];
}
if (label[i-1][j+1] != 0)
{
label[i][j] = label[i-1][j+1];
}
if (label[i][j-1] != 0)
{
label[i][j] = label[i][j-1];
}
if ((label[i - 1][j - 1] = 0) && (label[i - 1][j] = 0) && (label[i - 1][j + 1] = 0) && (label[i][j - 1] = 0))
{
l = l + 1;
label[i][j] = l;
}
}
if (label[i][j] = 1)
{
count1++;
sumx1 = sumx1 + i;
sumy1 = sumy1 + j;
}
if (label[i][j] = 2)
{
count2++;
sumx2 = sumx2 + i;
sumy2 = sumy2 + j;
}
if (label[i][j] = 3)
{
count3++;
sumx3 = sumx3 + i;
sumy3 = sumy3 + j;
}
}
}
float y1 = (float)sumx1 / count1;
float z1 = (float)sumy1 / count1;
float y2 = (float)sumx2 / count2;
float z2 = (float)sumy2 / count2;
float ya = (float)sumx3 / count3;
float za = (float)sumy3 / count3;
printf("three points:\n1(%f, %f)\n2(%f, %f)\na(%f, %f)\n", z1 - 64, 64 - y1, z2 - 64, 64 - y2, za - 64, 64 - ya);
In your if statements you need to use the == operator to compare. The single = is assignment. For example:
if (label[i][j] == 1)
There are 6 places I see where you need to make this change.
I'm writing myself a Newton Fractal Generator. The images all looked like this:
But I actually would like it to look a bit smoother - sure I've done some research and I ran over http://www.hiddendimension.com/FractalMath/Convergent_Fractals_Main.html and this looks rather correct, except that there are at the edges of the basins some issues..
This is my generation loop:
while (i < 6000 && fabs(z.r) < 10000 && !found){
f = computeFunction(z, params, paramc[0]);
d = computeFunction(z, paramsD, paramc[1]);
iterexp = iterexp + exp(-fabs(z.r) - 0.5 / (fabs(subComplex(zo, z).r)));
zo = z;
z = subComplex(z, divComplex(f, d));
i++;
for (int j = 0; j < paramc[0] - 1; j++){
if (compComplex(z, zeros[j], RESOLUTION)){
resType[x + xRes * y] = j;
result[x + xRes * y] = iterexp;
found = true;
break;
}
}
if (compComplex(z, zo, RESOLUTION/100)){
resType[x + xRes * y] = 12;
break;
}
}
The coloration:
const int xRes = res[0];
const int yRes = res[1];
for (int y = 0; y < fraktal->getHeight(); y++){
for (int x = 0; x < fraktal->getWidth(); x++){
int type, it;
double conDiv;
if (genCL && genCL->err == CL_SUCCESS){
conDiv = genCL->result[x + y * xRes];
type = genCL->typeRes[x + y * xRes];
it = genCL->iterations[x + y * xRes];
} else {
type = 3;
conDiv = runNewton(std::complex<double>((double)((x - (double)(xRes / 2)) / zoom[0]), (double)((y - (double)(yRes / 2)) / zoom[1])), type);
}
if (type < 15){
Color col;
col.setColorHexRGB(colors[type]);
col.setColorHSV(col.getHue(), col.getSaturation(), 1-conDiv);
fraktal->setPixel(x, y, col);
} else {
fraktal->setPixel(x, y, conDiv, conDiv, conDiv, 1);
}
}
}
I appreciate any help to actually smooth this ;-)
Thanks,
- fodinabor
I'm implementing an algorithm, I excuse myself for the extreme for looping, haven't found a better way yet.
The problem is that at the second iteration at line 81 it gives a First-chance exception at 0x000000007707320E (ntdll.dll) in Test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
void co_hog(Mat image, int offset, int blockSize, int nrBins, int cat) {
Mat img_x;
Mat img_y;
IplImage img = image;
Mat kern_x = (Mat_<char>(1, 3) << -1, 0, 1);
Mat kern_y = (Mat_<char>(3, 1) << -1, 0, 1);
filter2D(image, img_x, image.depth(), kern_x);
filter2D(image, img_y, image.depth(), kern_y);
Size imageSize = image.size();
int nrBlocksY = imageSize.height / blockSize;
int nrBlocksX = imageSize.width / blockSize;
int degreePerBin = 180 / nrBins;
Mat gradients = Mat(image.size(), CV_32FC1);
Mat magnitudes = Mat(image.size(), CV_32FC1);
for(int y = 0; y < image.rows; y++) {
for(int x = 0; x < image.cols; x++) {
float grad_x = (float)img_x.at<uchar>(y, x);
float grad_y = (float)img_y.at<uchar>(y, x);
gradients.at<float>(y, x) = abs(atan2(grad_y, grad_x) * 180 / PI);
magnitudes.at<float>(y, x) = sqrt(pow(grad_x, 2) + pow(grad_y, 2));
}
}
int bin_1, bin_2, bin_3, bin_4;
double theta_1, theta_2, theta_3, theta_4;
Mat H;
stringstream line(stringstream::in | stringstream::out);
line << cat << " ";
int index = 1;
for(int i = 0; i < nrBlocksY; i++) {
for(int j = 0; j < nrBlocksX; j++) {
Mat coOccMat = Mat::zeros(nrBins, nrBins, CV_32FC1);
for(int q = i * blockSize; q < (i * blockSize) + blockSize; q++) {
for(int p = j * blockSize; p < (j * blockSize) + blockSize; p++) {
for(int offy = -offset; offy < offset; offy++) {
for(int offx = -offset; offx < offset; offx++) {
if((q + offy) >= imageSize.height || (p + offx) >= imageSize.width || (q + offy) < 0 || (p + offx) < 0) {
continue;
}
float m_1 = magnitudes.at<float>(q, p);
float m_2 = magnitudes.at<float>(q + offy, p + offx);
float alpha = gradients.at<float>(q, p);
float beta = gradients.at<float>(q + offy, p + offx);
if(fmod(alpha / degreePerBin, 1) > 0.5) {
bin_1 = floor(alpha / degreePerBin);
bin_2 = bin_1 + 1;
} else {
bin_2 = floor(alpha / degreePerBin);
bin_1 = bin_2 - 1;
}
if(fmod(beta / degreePerBin, 1) > 0.5) {
bin_3 = floor(beta / degreePerBin);
bin_4 = bin_3 + 1;
} else {
bin_4 = floor(beta / degreePerBin);
bin_3 = bin_4 - 1;
}
theta_1 = (bin_1 * degreePerBin) + (degreePerBin / 2);
theta_2 = (bin_2 * degreePerBin) + (degreePerBin / 2);
theta_3 = (bin_3 * degreePerBin) + (degreePerBin / 2);
theta_4 = (bin_4 * degreePerBin) + (degreePerBin / 2);
coOccMat.at<float>(bin_1, bin_3) += (m_1 * (1 - (alpha - theta_1) / (theta_2 - theta_1))) + (m_2 * (1 - (beta - theta_3) / (theta_4 - theta_1)));
coOccMat.at<float>(bin_1, bin_4) += (m_1 * (1 - (alpha - theta_1) / (theta_2 - theta_1))) + (m_2 * ((beta - theta_3) / (theta_4 - theta_1)));
coOccMat.at<float>(bin_2, bin_3) += (m_1 * ((alpha - theta_1) / (theta_2 - theta_1))) + (m_2 * (1 - (beta - theta_3) / (theta_4 - theta_1)));
coOccMat.at<float>(bin_2, bin_4) += (m_1 * ((alpha - theta_1) / (theta_2 - theta_1))) + (m_2 * ((beta - theta_3) / (theta_4 - theta_1)));
}
}
}
}
cout << coOccMat << endl;
-> Next statement to be called *passes the first time* H = coOccMat.reshape(0, 1);
normalize(H, H);
cout << H.size() << endl;
for(int i = 0; i < H.cols; ++i) {
for(int j = 0; j < H.rows; ++j) {
if(H.at<float>(j, i) > 0) {
line << index << ":" << H.at<float>(j, i) << " ";
}
index++;
}
}
cout << "Done" << index << endl;
}
}
}
Problem has been fixed, sometimes the value for a bin was set on -1 so it couldn't access it, debugging tools of visual studio couldn't point out where it went wrong.