CS50 Wk4 Blur Pset - cs50

void blur(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int red_total = 0;
int blue_total = 0;
int green_total = 0;
int number_counted = 0;
for (int k = -1; k <= 1; k++)
{
for (int l = -1; l <= 1; l++)
{
if (i + k <= height && i + k >= 0 && j + l <= width && j + l >= 0)
{
blue_total += image[i+k][j+l].rgbtBlue;
red_total += image[i+k][j+l].rgbtRed;
green_total += image[i+k][j+l].rgbtGreen;
number_counted ++;
}
}
}
image[i][j].rgbtBlue = blue_total / number_counted;
image[i][j].rgbtRed = red_total / number_counted;
image[i][j].rgbtGreen = green_total / number_counted;
}
}
return;
}
Why is that section && operators?
if (i + k <= height && i + k >= 0 && j + l <= width && j + l >= 0)
I ran it with || operators because my understanding is that under the guise of the problem IF any of those conditions are satisfied there is no block to add. Yet why is it that when I run it under || it returns segmentation fault whereas if I run it with && the problem works out?
Thank you for answering!

All of those conditions have to be true or else the array operations will be invalid.
e.g. if i+k > height then image[i+k] is invalid.
Also I think you have some "off by one problems. image is [height][width] so valid values are [0..height-1] and [0..width-1] so the checks should be more like if (i + k < height && i + k >= 0 && j + l < width && j + l >= 0)

Related

Multithreaded Nagel–Schreckenberg model (traffic simulation) with OpenMP

I'm trying to write a multithreaded Nagel–Schreckenberg model simulation in c language and have some problems when a thread accesses the data which wasn't calculated yet.
Here is a working code which only parallelizes velocity calculation per line:
#define L 3000 // number of cells in row
#define num_iters 3000 // number of iterations
#define density 0.48 // how many positives
#define vmax 2
#define p 0.2
for (int i = 0; i < num_iters - 1; i++)
{
int temp[L] = {0};
#pragma omp parallel for
for (int x = 0; x < L; x++)
{
if (iterations[i][x] > -1)
{
int vi = iterations[i][x]; // velocity of previews iteration
int d = 1; // index of the next vehicle
while (iterations[i][(x + d) % L] < 0)
d++;
int vtemp = min(min(vi + 1, d - 1), vmax); // increase speed, but avoid hitting the next car
int v = r2() < p ? max(vtemp - 1, 0) : vtemp; // stop the vehicle with probability p
temp[x] = v;
}
}
for (int x = 0; x < L; x++) // write the velocities to the next line
{
if (iterations[i][x] > -1)
{
int v = temp[x];
iterations[i + 1][(x + v) % L] = v;
}
}
}
This works fine, but it's not fast enough. I'm trying to use convolution to increase the performance, but it can't read neighbor thread's data half of the time because it wasn't calculated yet. Here is the code I used:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
#define L 4000 // number of cells in row
#define num_iters 4000 // number of iterations
#define density 0.48 // how many positives
#define vmax 2
#define p 0.2
#define BLOCKS_Y 4
#define BLOCKS_X 4
#define BLOCKSIZEY (L / BLOCKS_Y)
#define BLOCKSIZEX (L / BLOCKS_X)
time_t t;
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
void shuffle(int *array, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
double r2()
{
return (double)rand() / (double)RAND_MAX;
}
void writeImage(int *iterations[], char filename[])
{
int h = L;
int w = num_iters;
FILE *f;
unsigned char *img = NULL;
int filesize = 54 + 3 * w * h;
img = (unsigned char *)malloc(3 * w * h);
memset(img, 0, 3 * w * h);
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
int x = i;
int y = (h - 1) - j;
int color = iterations[i][j] == 0 ? 0 : 255;
img[(x + y * w) * 3 + 2] = (unsigned char)(color);
img[(x + y * w) * 3 + 1] = (unsigned char)(color);
img[(x + y * w) * 3 + 0] = (unsigned char)(color);
}
}
unsigned char bmpfileheader[14] = {'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0};
unsigned char bmpinfoheader[40] = {40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0};
unsigned char bmppad[3] = {0, 0, 0};
bmpfileheader[2] = (unsigned char)(filesize);
bmpfileheader[3] = (unsigned char)(filesize >> 8);
bmpfileheader[4] = (unsigned char)(filesize >> 16);
bmpfileheader[5] = (unsigned char)(filesize >> 24);
bmpinfoheader[4] = (unsigned char)(w);
bmpinfoheader[5] = (unsigned char)(w >> 8);
bmpinfoheader[6] = (unsigned char)(w >> 16);
bmpinfoheader[7] = (unsigned char)(w >> 24);
bmpinfoheader[8] = (unsigned char)(h);
bmpinfoheader[9] = (unsigned char)(h >> 8);
bmpinfoheader[10] = (unsigned char)(h >> 16);
bmpinfoheader[11] = (unsigned char)(h >> 24);
f = fopen(filename, "wb");
fwrite(bmpfileheader, 1, 14, f);
fwrite(bmpinfoheader, 1, 40, f);
for (int i = 0; i < h; i++)
{
fwrite(img + (w * (h - i - 1) * 3), 3, w, f);
fwrite(bmppad, 1, (4 - (w * 3) % 4) % 4, f);
}
free(img);
fclose(f);
}
void simulation()
{
printf("L=%d, num_iters=%d\n", L, num_iters);
int z = 0;
z++;
int current_index = 0;
int success_moves = 0;
const int cars_num = (int)(density * L);
int **iterations = (int **)malloc(num_iters * sizeof(int *));
for (int i = 0; i < num_iters; i++)
iterations[i] = (int *)malloc(L * sizeof(int));
for (int i = 0; i < L; i++)
{
iterations[0][i] = i <= cars_num ? 0 : -1;
}
shuffle(iterations[0], L);
for (int i = 0; i < num_iters - 1; i++)
for (int x = 0; x < L; x++)
iterations[i + 1][x] = -1;
double *randoms = (double *)malloc(L * num_iters * sizeof(double));
for (int i = 0; i < L * num_iters; i++) {
randoms[i] = r2();
}
#pragma omp parallel for collapse(2)
for (int blocky = 0; blocky < BLOCKS_Y; blocky++)
{
for (int blockx = 0; blockx < BLOCKS_X; blockx++)
{
int ystart = blocky * BLOCKSIZEY;
int yend = ystart + BLOCKSIZEY;
int xstart = blockx * BLOCKSIZEX;
int xend = xstart + BLOCKSIZEX;
for (int y = ystart; y < yend; y++)
{
for (int x = xstart; x < xend; x++)
{
if (iterations[y][x] > -1)
{
int vi = iterations[y][x];
int d = 1;
int start = (x + d) % L;
int i;
for (i = start; i < L && iterations[y][i] < 0; ++i);
d += i - start;
if (i == L)
{
for (i = 0; i < start && iterations[y][i] < 0; ++i);
d += i;
}
int vtemp = min(min(vi + 1, d - 1), vmax);
int v = randoms[x * y] < p ? max(vtemp - 1, 0) : vtemp;
iterations[y + 1][(x + v) % L] = v;
}
}
}
}
}
if (L <= 4000)
writeImage(iterations, "img.bmp");
free(iterations);
}
void main() {
srand((unsigned)time(&t));
simulation();
}
As you can see, as the second block gets calculated the first one didn't probably calculate yet which produces that empty space.
I think it's possible to solve this with the convolution, but I'm just doing something wrong and I'm not sure what. If you could give any advice on how to fix this problem, I would really appreciate it.
There is a race condition in the second code because iterations can be read by a thread and written by another. More specifically, iterations[y + 1][(x + v) % L] = v set a value that another thread should read when checking iterations[y][x] or iterations[y][(x + d) % L] when two threads are working on consecutive y values (of two consecutive blocky values).
Moreover, the r2 function have to be thread-safe. It appears to be a random number generator (RNG), but such random function is generally implemented using global variables that are often not thread-safe. One simple and efficient solution is to use thread_local variables instead. An alternative solution is to explicitly pass in parameter a mutable state to the random function. The latter is a good practice when you design parallel applications since it makes visible the mutation of an internal state and it provides way to better control the determinism of the RNG.
Besides this, please note that modulus are generally expensive, especially if L is not a compile-time constant. You can remove some of them by pre-computing the remainder before a loop or splitting a loop so to perform checks only near the boundaries. Here is an (untested) example for the while:
int start = (x + d) % L;
int i;
for(i=start ; i < L && iterations[y][i] < 0 ; ++i);
d += i - start;
if(i == L) {
for(i=0 ; i < start && iterations[y][i] < 0 ; ++i);
d += i;
}
Finally, please note that the blocks should be divisible by 4. Otherwise, the current code is not valid (a min/max clamping is likely needed).

Given a square matrix, calculate the absolute difference between the sums of its diagonals

import numpy as np n=int(input())
R = n C = n p,s=0,0
print("Enter the entries in a single line (separated by space): ")
entries = list(map(int, input().split())) matrix = np.array(entries).reshape(R, C) print(matrix) for i in range(R): for j in range(C): if i==j: p=p+matrix[i][j] if i+j==n-1: s=s+matrix[i][j] s1=p-s print(s1)
r_sum=0
l_sum=0
for i in range(len(arr)):
l_sum=l_sum+arr[i][i]
r_sum=r_sum+arr[i][(len(arr)-1)-i]
return abs(l_sum - r_sum)
#pyhton3 using array concept
Maybe this helps:
c = np.array([[1,2,3],[4,5,6],[7,8,9]])
i,j = np.indices(c.shape)
sum1 = c[i==j].sum()
sum2 = c[i+j == len(c)-1].sum()
print(abs(sum1-sum2))
function absoluteDifference(arr){
var sumDiagnoalOne=0
var sumDiagnoalTwo=0
for(var i=0; i<arr.length; i++){
for(var j=i; j<arr.length; j++){
sumDiagnoalOne+=arr[i][j]
break
}
}
var checkArray=[]
arr.map(array=>checkArray.push(array.reverse()))
for(var i=0; i<checkArray.length; i++){
for(var j=i; j<checkArray.length; j++){
sumDiagnoalTwo+=checkArray[i][j]
break
}
}
return Math.abs(sumDiagnoalOne- sumDiagnoalTwo)
}
#include
using namespace std;
int main() {
int n;
cin >> n;
int arr[n][n];
long long int d1=0; //First Diagonal
long long int d2=0; //Second Diagonal
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> arr[i][j];
if (i == j) d1 += arr[i][j];
if (i == n - j - 1) d2 += arr[i][j];
}
}
cout << abs(d1 - d2) << endl; //Absolute difference of the sums across the
diagonals
return 0;
}
#!/bin/ruby
n = gets.strip.to_i
a = Array.new(n)
(0..n-1).each do |i|
a[i] = gets.strip.split(' ').map(&:to_i)
end
d1 = 0
d2 = 0
(0..n-1).each do |i|
d1 = d1 + a[i][i]
d2 = d2 + a[-i-1][i]
end
print (d1-d2).abs
Javascript in O(n)
function diagonalDifference(arr) {
const size = arr.length;
let lsum = 0;
let rsum = 0;
for(let i = 0; i < size; i ++){
lsum += arr[i][i];
rsum += arr[i][Math.abs(size - 1 - i)];
}
return Math.abs(lsum - rsum);
}
//sample array matrix 4x4
const arr=[ [ 11, 2, 4 ,5], [ 4, 5, 6,4 ], [ 10, 8, -12,6 ],[ 10, 8, -12,6 ] ];
function findMedian(arr) {
const matrixType=arr.length
const flat=arr.flat()
let sumDiag1=0
let sumDiag2=0
for(let i=0;i<matrixType;i++)
{
sumDiag1+=flat[i*(matrixType+1)]
sumDiag2+=flat[(i+1)*(matrixType-1)]
}
const diff=Math.abs(sumDiag1-sumDiag2)
return diff
}
console.log(findMedian(arr))

Flipping algorithm

I have a string s containing different types of brackets : () and [] . How can I balance a string of this type with the minimum possible number of reversals ? I can replace any bracket with any other one.
For example : Cost for [)(] is 2, it becomes [()]. Cost for [](( is 1, it becomes []() . [(]) is not balanced.
A more complex example : )[)([)())] can be turned to ([])[(())] in 4 changes, but can also be turned to [()(()())] in 3 steps, which is the least number of modifications to make it balanced.
How can I solve the problem ?
First approach I came with is O(n^3) dynamic programming.
Let match(i, j) be the number of replaces you have to make in order to make s[i] and s[j] as () or []. So match(i, j) can be either 0, 1 or 2.
Consider dp[i][j] = the minimum cost to balance the subsequence from i to j in your brackets array. Now you will define dp[i][i + 1] as:
dp[i][i + 1] = match(i, i + 1)
Now the general rule is that we take the overall minimum between dp[i + 1][j - 1] + match(i, j) and min(dp[i][j], dp[i][p] + dp[p + 1][j]) for any i < p < j. Obviously, the result will be held in dp[1][n]. There is a C++ solution (I'll also upload a python program in about 15 minutes when I'll be done with it - not so strong with python :P).
#include <iostream>
#include <string>
using namespace std;
int dp[100][100];
string s;
int n;
int match(char a, char b) {
if (a == '(' && b == ')') {
return 0;
}
if (a == '[' && b == ']') {
return 0;
}
if ((a == ')' || a == ']') && (b == '(' || b == '[')) {
return 2;
}
return 1;
}
int main() {
cin >> s;
n = s.length();
s = " " + s;
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) {
dp[i][j] = 0x3f3f3f3f;
}
}
for (int i = 1; i < n; ++i) {
dp[i][i + 1] = match(s[i], s[i + 1]);
}
for (int k = 3; k <= n; k += 2) {
for (int i = 1; i + k <= n; ++i) {
int j = i + k;
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]));
for (int p = i + 1; p <= j; p += 2) {
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j]);
}
}
}
cout << dp[1][n] << '\n';
/*for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cout << dp[i][j] << ' ';
}
cout << '\n';
}*/
return 0;
}
Edit:
Here you go Python :)
s = input()
n = len(s)
inf = 0x3f3f3f3f
def match(x, y):
if x == '(' and y == ')':
return 0
if x == '[' and y == ']':
return 0
if (x == ')' or x == ']') and (y == '(' or y == '['):
return 2
return 1
# dp[i][j] = min. cost for balancing a[i], a[i + 1], ..., a[j]
dp = [[inf for j in range(n)] for i in range(n)]
for i in range(n - 1):
dp[i][i + 1] = match(s[i], s[i + 1])
for k in range(3, n, 2):
i = 0
while i + k < n:
j = i + k
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]))
for p in range(i + 1, j, 2):
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j])
i += 1
print(dp[0][n - 1])
#for i in range(n):
# for j in range(n):
# print(dp[i][j], end = ' ')
# print()

What does the value 0.5 represent here?

This is an implementation of Naive Bayes Classifier Algorithm.
I couldn't understand the line score.Add(results[i].Name, finalScore * 0.5);.
Where does this value 0.5 come from?
Why 0.5? Why not any other value?
public string Classify(double[] obj)
{
Dictionary<string,> score = new Dictionary<string,>();
var results = (from myRow in dataSet.Tables[0].AsEnumerable()
group myRow by myRow.Field<string>(
dataSet.Tables[0].Columns[0].ColumnName) into g
select new { Name = g.Key, Count = g.Count() }).ToList();
for (int i = 0; i < results.Count; i++)
{
List<double> subScoreList = new List<double>();
int a = 1, b = 1;
for (int k = 1; k < dataSet.Tables["Gaussian"].Columns.Count; k = k + 2)
{
double mean = Convert.ToDouble(dataSet.Tables["Gaussian"].Rows[i][a]);
double variance = Convert.ToDouble(dataSet.Tables["Gaussian"].Rows[i][++a]);
double result = Helper.NormalDist(obj[b - 1], mean, Helper.SquareRoot(variance));
subScoreList.Add(result);
a++; b++;
}
double finalScore = 0;
for (int z = 0; z < subScoreList.Count; z++)
{
if (finalScore == 0)
{
finalScore = subScoreList[z];
continue;
}
finalScore = finalScore * subScoreList[z];
}
score.Add(results[i].Name, finalScore * 0.5);
}
double maxOne = score.Max(c => c.Value);
var name = (from c in score
where c.Value == maxOne
select c.Key).First();
return name;
}
I figured it out.
0.5 is the apriori probability.

visual c++ an unhandled exception of type 'System.IndexOutOfRangeException' occurred

I am trying to transform my C# implementation of Levenstein algorithm into Visual C++ and I am facing this error message
An unhandled exception of type 'System.IndexOutOfRangeException' occurred
The original fully working C# code is
public static int Compute(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
Visual C++ code that produces IndexOutOfRangeException is this
int Compute(String^ s, String^ t)
{
int n = s->Length;
int m = t->Length;
array<int,2>^ d = gcnew array<int,2>(n+1 , m+1); //int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math::Min(
Math::Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
Is there anything wrong with my array declaration in Visual C++?
This exception occurs because of accessing the index more than its limit.
e.g. limit is n and you are using n+1 th element of an array.
check the value of i and j does it exceeds or and m+1 print the values of i and j so that you can find in which iteration the value exceeds limit.
I soved it , I used vectors instead or array
my 2D array implementation was not corrected , here is the correct implementation in visual C++
int Lev(String^ s, String^ t)
{
int n = s->Length;
int m = t->Length;
vector<vector<int> > d(n+1,vector<int>(m+1));
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i][0] = i++)
{
}
for (int j = 0; j <= m; d[0][j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i][j] = Math::Min(
Math::Min(d[i - 1][j] + 1, d[i][j - 1] + 1),
d[i - 1][j - 1] + cost);
}
}
// Step 7
return d[n][m];
}

Resources