Function to calculate a value inside a Verilog generate loop - verilog

I am trying to create a parametrized circuit for the multiplication stage of a BCD Wallace Tree Multiplier, which I implemented in Orcad. The trouble I'm having is that I need to calculate the bit positions that each two digits that result from BCD multiplication will inhabit.
Here is my code:
module bcd_mult_1_n #(parameter N = 8)
(input [N * 4 - 1:0] num1, num2, output reg [2 * 4 * N * N - 1:0] partProds);
genvar i, j;
generate
for(i = 0; i < N; i = i + 1) begin : dig1
for(j = 0; j < N; j = j + 1) begin : dig2
localparam lsd = posLSD(i, j);
localparam msd = posMSD(i, j);
bcd_mult_1 bcd_mult(num1[i * 4 + 3:i * 4], num2[j * 4 + 3:j * 4],
partProds[msd * 4 + 3:msd * 4], partProds[lsd * 4 + 3: lsd * 4]);
end
end
endgenerate
In the above code, numPrev(i + j) needs to return a value calculated something like this
int numPrev(int x) {
int acc = 0;
for(int i = x; i > 0; i++) acc = acc + 2 * i;
return acc;
}
Thanks to help from #Morgan I have created the following function; the logic is meant to count up and down a sort of triangle of values which rise from 1 to N and back down to 1.
function integer posLSD;
input integer x, y;
integer weight;
integer acc;
integer num;
integer i;
weight = x + y;
acc = 0;
if(weight >= N) num = N - 1;
else num = weight;
for(i = num; i > 0; i = i - 1)
acc = acc + 2 * i;
if(weight >= N) begin
for(i = 2 * N - weight; i <= N; i = i + 1) begin
acc = acc + 2 * i;
end
acc = acc + N - weight + y - 1;
end
else
acc = acc + y;
posLSD = acc;
endfunction
function integer posMSD;
input integer x, y;
integer acc;
integer weight;
acc = posLSD(x, y);
weight = x + y;
if(weight < N) acc = acc + weight + 1;
else acc = acc + 2 * N - weight - 1;
posMSD = acc;
endfunction
How could I achieve this functionality? If needed, I could use SystemVerilog constructs.

When I change to use a function I get the error Packed dimension must specify a range. I think you need to think about your partProds width and connections.
Using a function:
module bcd_mult_1_n #(
parameter N = 8
) (
input [N * 4 - 1:0] num1,
input [N * 4 - 1:0] num2,
output reg [2 * 4 * N * N] partProds
);
integer prev = 1;
genvar i, j;
generate
for(i = 0; i < N; i = i + 1) begin : dig1
for(j = 0; j < N; j = j + 1) begin : dig2
bcd_mult_1
bcd_mult(
num1[i * 4 + 3:i * 4],
num2[j * 4 + 3:j * 4],
partProds[numPrev(i+j) + 2*j + i + 1],
partProds[numPrev(i+j) + j]
);
end
end
endgenerate
function numPrev;
input integer x ;
integer acc;
begin
acc = 0;
for(int ij = x; ij > 0; ij++) begin
acc = acc + 2 * ij;
end
numPrev = acc;
end
endfunction
endmodule
module bcd_mult_1(
input [3:0]a,
input [3:0]b,
input c,
input d
);
endmodule
Example on EDA Playground.

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).

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()

Rewrite code using generate statement (Verilog HDL)

I'm trying to rewrite this code using generate statements (Verilog HDL):
integer j;
always#(posedge cpu_clk) begin
// ACCU_RST
if(RAM[3][7]) begin
RAM[3][7] <= 1'b0;
for(j = 10; j <= 15; j = j + 1)
RAM[j] <= 8'b0;
end
// CPU write
RAM[addr + 0] <= in_valid && cmd && (addr + 0 <= 9 || addr + 0 >= 16) ? data_in[8 * 0 + 7:8 * 0] : RAM[addr + 0];
RAM[addr + 1] <= in_valid && cmd && (addr + 1 <= 9 || addr + 1 >= 16) ? data_in[8 * 1 + 7:8 * 1] : RAM[addr + 1];
RAM[addr + 2] <= in_valid && cmd && (addr + 2 <= 9 || addr + 2 >= 16) ? data_in[8 * 2 + 7:8 * 2] : RAM[addr + 2];
RAM[addr + 3] <= in_valid && cmd && (addr + 3 <= 9 || addr + 3 >= 16) ? data_in[8 * 3 + 7:8 * 3] : RAM[addr + 3];
//CPU read
out_valid <= !cmd && in_valid;
out_data[8 * 0 + 7:8 * 0] <= !cmd && in_valid ? RAM[addr + 0] : out_data[8 * 0 + 7:8 * 0];
out_data[8 * 1 + 7:8 * 1] <= !cmd && in_valid ? RAM[addr + 1] : out_data[8 * 1 + 7:8 * 1];
out_data[8 * 2 + 7:8 * 2] <= !cmd && in_valid ? RAM[addr + 2] : out_data[8 * 2 + 7:8 * 2];
out_data[8 * 3 + 7:8 * 3] <= !cmd && in_valid ? RAM[addr + 3] : out_data[8 * 3 + 7:8 * 3];
end
Yet I recieve the following errors if I try this:
// CPU write
for(i = 0; i <= 3; i = i + 1) begin
if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8 * i + 7:8 * i];
end
//CPU read
out_valid <= !cmd && in_valid;
for(i = 0; i <= 3; i = i + 1) begin
if(in_valid && !cmd)
out_data[8 * i + 7:8 * i] <= RAM[addr + i];
end
ERROR: i is not a constant value.
(error points to data_in[8 * i + 7:8 * i] and out_data[8 * i + 7:8 * i])
Another try, using two always blocks, one for generate, one for ACCU_RST yields multiple drivers for RAM (duh).
Last try:
genvar i;
always#(posedge cpu_clk) begin
if(ACCU_RST) begin
RAM[3][7] <= 1'b0;
for(j = 10; j <= 15; j = j + 1)
RAM[j] <= 8'b0;
end
// CPU write cmd
for(i = 0; i <= 3; i = i + 1) begin :CPU_W
if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8 * i + 7:8 * i];
end
//CPU read cmd
out_valid <= !cmd && in_valid;
for(i = 0; i <= 3; i = i + 1) begin :CPU_R
if(in_valid && !cmd)
out_data[8 * i + 7:8 * i] <= RAM[addr + i];
end
end
That yields:
ERROR: Procedural assignment to a non-register i is not permitted,
left-hand side should be reg/integer/time/genvar
(and points to i = 0 and to i = i + 1).
For this you shouldn't use a generate block. The generate for loop must exist outside of an always block. And a values must only be assigned in one always block to be synthesizable. Take the below example, RAM[2] can be assigned when addr==0 on the third loop (i==2), when addr==1 on the second loop (i==1), and when addr==2 on on the first loop (i==0). Three separate always blocks which is a synthesizable error.
genvar i;
generate
for(i=0; i<4; i++) begin
always #(posedge clk)
if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8*i + 7 : 8*i];
end
endgenerate
Skip the generate and use a standard for loop inside the always block. Use indexed part-select (references here and here):
integer i; // <-- not genvar
always #(posedge cpu_clk) begin
/* ... your other code ... */
// CPU write cmd
for (i = 0; i < 4; i = i + 1) begin :CPU_W
if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[ 8*i +: 8];
end
//CPU read cmd
out_valid <= !cmd && in_valid;
for (i = 0; i < 4; i = i + 1) begin :CPU_R
if (in_valid && !cmd)
out_data[ 8*i +: 8] <= RAM[addr + i];
end
end

(computer graphics) radial image distortion

I need to create an effect, that radially distorts a bitmap, by stretching or shrinking its "layers of pixels" radially (as shown on the image):
http://i.stack.imgur.com/V6Voo.png
by colored circles (their thickness) is shown the transform, that is applied to the image
What approach should I take? I have a bitmap (array of pixels) and an another bitmap, that should be the result of such a filter applied (as a result, there should be some kind of a round water ripple on the bitmap).
Where could I read about creating such effects?
Thank you.
Try to look here
http://www.jhlabs.com/ip/blurring.html
Zoom and Spin Blur
it is Java but nevertheless it could be fit to your request.
Well, the most accurate results would come from mapping the euclidean coordinates to a polar matrix. Then you would very easily be able to stretch them out. Then just translate them back to a euclidean representation and save. I'll write and edit with some code in a second.
Alright I got a bit carried away but here's my code. It will take a bitmap, convert it to and from polar coordinates and save it. now, radial based distortion should be a breeze.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define PI 3.141592654
#define C_R 1000
#define C_S 1000
#define C_M 2000
typedef struct{ int r,g,b; } color;
typedef struct{ int t; color* data; int w, h; } bitmap;
typedef struct{ int t; color* data; int r, s, w, h; } r_bitmap;
bitmap* bmp_load_from_file( const char* fname ){
FILE* b = fopen( fname, "rb" );
if( b <= 0 ) return 0;
int num;
fscanf( b, "BM%n", &num );
if( num < 2 ) return 0;
struct{ int size, reserved, offset;
int hsize, wid, hig, planes:16, bpp:16, comp, bmpsize, hres, vres, colors, important; } head;
fread( &head, 13, 4, b );
bitmap* bmp = malloc( sizeof( bitmap ) );
bmp->data = malloc( head.wid * head.hig * sizeof( color ) );
bmp->w = head.wid;
bmp->h = head.hig;
for( int y = head.hig - 1; y >= 0; --y ){
int x;
for( x = 0; x < head.wid; ++x ){
color t;
t.r = fgetc( b );
t.g = fgetc( b );
t.b = fgetc( b );
bmp->data[x+y*bmp->w] = t;
}
x*=3;
while( x%4 != 0 ){
++x;
fgetc( b );
}
}
bmp->t = 0;
fclose( b );
return bmp;
}
void bmp_save( const char* fname, bitmap* bmp ){
FILE* b = fopen( fname, "wb" );
if( b <= 0 ) return 0;
struct{ int size, reserved, offset;
int hsize, wid, hig, planes:16, bpp:16, comp, bmpsize, hres, vres, colors, important; } head;
fprintf( b, "BM" );
head.size = 3 * (bmp->w+4)/4*4 * bmp->h + 54;
head.offset = 54;
head.hsize = 40;
head.wid = bmp->w;
head.hig = bmp->h;
head.planes = 1;
head.bpp = 24;
head.comp = 0;
head.bmpsize = 3 * (bmp->w+4)/4*4 * bmp->h;
head.hres = 72;
head.vres = 72;
head.colors = 0;
head.important = 0;
fwrite( &head, 13, 4, b );
for( int y = bmp->h - 1; y >= 0; --y ){
int x;
for( x = 0; x < bmp->w; ++x ){
fputc( bmp->data[x + y * bmp->w].r, b );
fputc( bmp->data[x + y * bmp->w].g, b );
fputc( bmp->data[x + y * bmp->w].b, b );
}
x*=3;
while( x % 4 != 0 ){
++x;
fputc(0, b);
}
}
fclose( b );
}
color color_mix( color a, color b, int offset ){ /*offset is a value between 0 and 255 to determine the weight. the lower it is the more color a gets*/
//if( offset > 255 || offset < 0)
//printf("%i\t", offset);
a.r += ( b.r - a.r ) * offset / 255;
a.g += ( b.g - a.g ) * offset / 255;
a.b += ( b.b - a.b ) * offset / 255;
return a;
}
r_bitmap* bmp_to_r( bitmap* b ){
r_bitmap* r = malloc( sizeof( r_bitmap ) );
r->t = 1;
int radius = sqrt( b->w * b->w + b->h * b->h ) / 2 * C_R / C_M + 2;
int step = C_S * ( b->w + b->h ) / C_M;
r->data = malloc( radius * step * sizeof( color ) );
r->r = radius;
r->s = step;
r->w = b->w;
r->h = b->h;
color black = {0, 0, 0};
for( double i = 0; i < radius; ++ i ){
for( double j = 0; j < step; ++j ){
double x = i * C_M * cos( 2 * PI * j / step ) / C_R + b->w / 2;
double y = i * C_M * sin( 2 * PI * j / step ) / C_R + b->h / 2;
int ix = x;
int iy = y;
if( x < 0 || x >= b->w || y < 0 || y >= b->h )
r->data[(int)(j + i * step)] = black;
else{
color tmp = b->data[ix + iy * b->w];
if( iy < b->h - 1 ){
int off = 255 * (y - iy);
tmp = color_mix( tmp, b->data[ix + (iy+1) * b->w], off );
}
if( ix < b->w - 1 ){
int off = 255 * ( x - ix );
tmp = color_mix( tmp, b->data[ix +1 + iy * b->w], off );
}
r->data[(int)(j + i * step)] = tmp;
}
}
}
return r;
}
bitmap* bmp_from_r( r_bitmap* r ){
bitmap* b = malloc( sizeof( bitmap ) );
b->t = 0;
b->data = malloc( r->w * r->h * sizeof( color ) );
b->w = r->w;
b->h = r->h;
for( int y = 0; y < b->h; ++y ){
for( int x = 0; x < b->w; ++x ){
int tx = x - b->w/2;
int ty = y - b->h/2;
double rad = sqrt( tx*tx+ty*ty ) * C_R / C_M;
double s = atan2( ty, tx );
if( s < 0 ) s += 2 * PI;
s *= r->s / ( 2 * PI );
int is = s;
int irad = rad;
color tmp = r->data[(int)(is + irad * r->s)];
/*if( x > 0 && x < r->w - 1 && y > 0 && y < r->h - 1 ){
tmp = color_mix(tmp, r->data[((int)(is+1)%r->s + irad * r->s)], abs(255* rad - floor(rad)));
tmp = color_mix(tmp, r->data[(is + (irad + 1) * r->s)], abs(255* s - floor(s)));
}*/
b->data[x+y*b->w] = tmp;
}
}
return b;
}
int main( ) {
bitmap* b = bmp_load_from_file( "foo.bmp" );
r_bitmap* r = bmp_to_r( b );
bitmap* c = bmp_from_r( r );
bmp_save( "lol.bmp", c );
}

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