I try to get the VHDL code corresponding to my simulation on MATLAB with HDL coder app, but I get a first error at the line 25 when I build the MATLAB code on the HDL coder app:
Index expression out of bounds. Attempted to access element 15. The valid range is 1-1.
I don't understand because the simulation on MATLAB works and I don't get this error.
function U_p = HDL_decoder_function(r)
H1 = [ 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 ];
H = 0;
S_in_rows = 0;
Sm = 0;
S = 0;
f_in_column = 0;
f = 0;
f_largest = 0;
f_nth_largest = 0;
% Declaration of the parity-check matrix
% Fill the first row to prepare the shift in the H matrix
for i = 1 : 15
H( 1, i ) = H1(i);
end
% Fill all the other rows with the shift
for j = 2 : 15
for i = 1 : 15
if( i == 1 )
H( j, i) = H( j-1, 15); % first error
else
H( j, i) = H( j-1, i-1);
end
end
end
H;
% Start of the bit-flipping algorithm
for k = 1 : 20 % Authorize 20 executions maximum of the statements of the algorithm
% Calculate the syndrome S = r^T * H
for j = 1 : 15
for i = 1 : 15
S_in_rows(i) = and( r(i), H( j, i) );
end
for i = 1 : 15
Sm = sum(S_in_rows);
end
if rem(Sm, 2) == 1
S(j) = 1;
else
S(j) = 0;
end
end
S;
% Go out from the loop when syndrome S = 0
if S == 0
U_p = r;
break
end
if k == 20
disp('Decoding fail')
U_p = [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ];
end
% Find the number f of failed syndrome bits for every received bits r
for i = 1 : 15
f(i) = 0; % Declaration
end
for i = 1 : 15
for j = 1 : 15
f_in_column = and( S(j), H( j, i) );
if f_in_column == 1
f(i) = f(i)+1;
end
end
end
f;
% Flip the the rth bit corresponding to the first largest number of error in f
f_largest = 0;
for i = 1 : 15
if f(i) > f_largest
f_largest = f(i); % Save the number of error
f_nth_largest = i; % Save the position of f_largest
end
end
f_largest;
f_nth_largest;
r(f_nth_largest) = not(r(f_nth_largest));
r;
U_p = r;
end
I don't use the HDL coder, but I have a likely cause. From your code:
H = 0;
% Fill the first row to prepare the shift in the H matrix
for i = 1 : 15
H( 1, i ) = H1(i);
end
Here, you define H to be a single integer, than use it as if it was a matrix. This is bad practice in Matlab (though will run) since each time you write to an array location that doesn't exist, Matlab creates a new array, then copy the current content to it, free the previous content and finally make the assignation. When it comes to VHDL, the variable size must be fixed and known in advance, there is no dynamic array in hardware.
You should pre-allocate your variables to the right dimensions before you use them. Simply change H = 0 to
H = zeros(15, 15);
Note that similarly, other variables are not initialized to the right size, including S, S_in_row and f.
Related
How would I go about finding the maximum sum of an array with the following conditions:
The summation must be consecutive.
If there exist any 0's, it is consider a "break"
The values in the sum of the array cannot be greater than the minimum value
EXAMPLE
1 0 1 0 0 = 1
2 0 2 1 1 = 3, why? [2 1 1] -> 1 + 1 + 1
3 1 3 2 2 = 6, why? [3 2 2] -> 2 + 2 + 2
4 0 0 3 0 = 4
I tried to think of a bottom up implementation, keeping track of the minimum value thus far
while at the same time keeping track of the maximum sum, but I'm getting stuck...
Compute the range in which a given element is the minimum efficiently:
Compute the range in which each element is the minimum as (i,j) with i and j excluded. Then with that element as minimum in that range, the sum is (j-i-1)*element.
Take maximum of all such values.
This should also take care of any zeros present in the array.
If you think about it, it is just another way of asking what is the largest rectangle formed by a histogram.
Lets take an example : [ 3, 1, 3, 2, 2 ]
For the first element 3 : the range in which it is minimum is (-1,1) where -1 is outside of the array and sum is 3*(1-(-1)-1) = 3
For the second element 1 : the range in which it is minimum is (-1,5) and sum is 1*(5-(-1)-1) = 5
....
....
For the fifth element 2 : the range in which it is minimum is (1, 5) and sum is 2*(5-1-1) = 6
For all elements it is : 3 5 3 6 6
The maximum value is 6.
How to compute the range?
Left bound:
For any given element, you look to its left if its greater then take its left bound and go on until you hit an element that is lesser than the current element. Note here that you are not going element by element rather by "bounds". This is important.
Right bound:
You do the same look to the right see if its greater, but keep going to the right until you hit an element that is lesser than the current element.
Code in Java will be :
private static int solve(int[] arr) {
int n = arr.length;
int[] leftBound = new int[n];
int[] rightBound = new int[n];
leftBound[0] = -1;
rightBound[n-1] = n;
for ( int i = 1; i < n; i++ ) {
int bound = i-1;
while ( bound >= 0 && arr[bound] >= arr[i] ) {
bound = leftBound[bound];
}
leftBound[i] = bound;
}
for ( int i = n-2; i >= 0; i-- ) {
int bound = i+1;
while ( bound < n && arr[bound] >= arr[i] ) {
bound = rightBound[bound];
}
rightBound[i] = bound;
}
int res = 0;
for ( int i = 0; i < n; i++ ) {
res = Math.max( res, (rightBound[i] - leftBound[i] - 1)*arr[i]);
}
return res;
}
I have an array called int arr[10] = {1,2,3,4,5}
From my understanding the rest of the array is filled with 0's.
My questions is if its a fixed array length how can I put the first index behind the last index that is not a 0. For example
I believe the 0 is not shown in real printf but I am including it for illustration purposes
for (int i = 0 ; i < 10 ; i++)
{
print("%i" , arr[i]);
}
The output
1 2 3 4 5 0 0 0 0 0
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
Will the output put the 1 behind the 5 or at the back of the whole array?
2 3 4 5 1 0 0 0 0 0
or because there is 0s then
2 3 4 5 0 0 0 0 0 1
If my question is unclear please tell me and I will try explain it.
The output
1 2 3 4 5 0 0 0 0 0
No, the actual output is
1234500000
Your code has undefined behavior. The first iteration of the loop (with i = -1) tries to assign to arr[-1], which does not exist:
arr[i] = arr[i + 1];
Similarly, the last iteration (with i = 9) tries to read from arr[10], which also does not exist.
I'm not sure why you think your code will move the first element back.
From my understanding the rest of the array is filled with 0's
You are right.:)
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
then you will get undefined behavior because the indices -1 and 10 are not valid indices.
It seems what you are trying to do is the following
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 2, 3, 4, 5 };
size_t pos = 0;
while ( pos < N && a[pos] != 0 ) ++pos;
if ( pos != N && !( pos < 3 ) )
{
int tmp = a[0];
pos -= 2;
memmove( a, a + 1, pos * sizeof( int ) );
a[pos] = tmp;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
2 3 4 1 5 0 0 0 0 0
Analyze output pattern and write algorithm of a program that prints such a pattern.
Input 4
Pattern:
55555
4444
333
22
1
Input 3
Pattern:
333
22
1
Process (what I have come up with)
n = input (“Enter a positive integer”)
r= 0
while r < n
c = (n – r) + 1
while c > 0
s = n – r
print s
c = c – 1
end
r = r + 1
n = n – 1
print end l
end
Problem: I have used r for rows, and c for columns. The problem rises in c = (n – r) + 1 for first row. It makes the first row n+1, works for following rows.
On dry run i get
Input 3
Pattern:
444
22
1
This should work:
n = input (“Enter a positive integer”)
while n > 0
c = n
while c > 0
print n
c = c – 1
end
n = n - 1
print end l
end
Be careful about what meaning you give to your variables and therefore, how you treat them consitently ;)
why are you using while for something that is an obviously an example of for statement?
n = input (“Enter a positive integer”)
for(i=n ; i > 0 ; i--)
{
for(j=0 ;j<i; j++)
{
print i;
}
print "\n";
}
I'm not very sure how to approach this problem. Basically, I have an algorithm that loops through 100 buttons (10 rows of 10) and assigns a number value based on a randomized start and end point. When clicked, the buttons should enter the next portion of a game, and take themselves off the map. To do this, I used this code:
public function createMap()
{
var startPointX:int = int(10 * Math.random()); //creates random values that set the x and y values of the start and end points
var startPointY:int = int(10 * Math.random());
var endPointX:int = int(10 * Math.random());
var endPointY:int = int(10 * Math.random());
var spaceDiffX:int = startPointX - endPointX; //the difference in X values
var spaceDiffY:int = startPointY - endPointY; //the difference in Y values
//Creation loop - loops through all of the buttons to create them
for (i = 0; i <= 9; i++)
{
mapY[i] = mapX; //Adds the rows into each column
for (j = 0; j <= 9; j++)
{
mapY[i][j] = new LocationButton(); //Creates a new button
mapY[i][j].x = 6 * 20 * i; //Sets X position
mapY[i][j].y = 6 * 10 * j; //Sets Y position
//places start point
if (i == startPointX && j == startPointY) //checks if this point on the grid is equal to the random start point
{
mapY[i][j].buttonType = 1; //sets it to the start point
}
//places end point
if (i == endPointX && j == endPointY) //checks if this point is equal to the random end point
{
mapY[i][j].buttonType = 2; //sets it to the end point
}
//finds path on x axis
if (i != startPointX && j == startPointY) //checks if this point is on the same Y value as the start point
{
if (spaceDiffX >= 0) //checks to see if the start point is on the left or right of the end point, left is negative, right is positive
{
if (i < startPointX && i >= endPointX) //checks if i is between the start X and end X
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
else
{
if (i > startPointX && i <= endPointX) //checks to see if i is between the start X and end X
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
}
if (j != startPointY && i == endPointX) //checks if this point is on the same X value as the end point
{
if (spaceDiffY >= 0) //checks to see if the start point is over or under the end point, above is positive, below is negative
{
if (j < startPointY && j >= endPointY) //checks if j is between the end Y and the start Y
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
else
{
if (j > startPointY && j <= endPointY)
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
}
if (mapY[i][j].buttonType != 0) //checks whether or not the button should be added
{
mapY[i][j].addEventListener(MouseEvent.CLICK, createBattleGUI); //adds event listener
stage.addChild(mapY[i][j]); //adds it to stage
}
}
}
}
The problem with this is how the code after the eventListener acts, however. The function it calls starts with this loop:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
{
if (mapY[i][j].buttonType != 0)
{
stage.removeChild(mapY[i][j]);
}
}
}
Once that loop goes through, it -should- remove all of the buttons. However, it doesn't. I started tracing some variables, and noticed that in the second loop, it is actually looping through the same 10 objects 10 times, instead of looping through all 100 objects. The * denotes the trace statement in the first for loop (before the event), and those without it are the buttons being traced in the second for loop:
name - buttonType - i - j
*instance33 1 1 6
*instance53 3 2 6
*instance73 3 3 6
*instance93 3 4 6
*instance113 3 5 6
*instance133 3 6 6
*instance153 3 7 6
*instance173 3 8 6
instance181 0 0 0
instance183 0 0 1
instance185 0 0 2
instance187 0 0 3
instance189 0 0 4
instance191 0 0 5
instance193 0 0 6
instance195 0 0 7
instance197 0 0 8
instance199 0 0 9
instance181 0 1 0
instance183 0 1 1
instance185 0 1 2
instance187 0 1 3
instance189 0 1 4
instance191 0 1 5
instance193 0 1 6
instance195 0 1 7
instance197 0 1 8
instance199 0 1 9
I realize that it is a bit of a long question, but I can't figure this out for the life of me. Thanks for any help.
In the hottest part of my program (90% of time according to gprof), I need to sum one array A into another B. Both arrays are 2^n (n is 18..24) sized and holds an integer (for simplicity, actually the element stored is mpz_t or small int array). The rule of summing: for each i in 0..2^n-1, set B[i] = sum (A[j]), where j is bit vector, and j & ~ i == 0 (in other words, k-th bit of any j can't be set to 1 if k-th bit of i is not 1).
My current code (this is a body of innermost loop) does this in the time of 2^(1.5 * n) sums, because I will iterate for each i on (in average) 2^(n/2) elements of A.
int A[1<<n]; // have some data
int B[1<<n]; // empty
for (int i = 0; i < (1<<n); i++ ) {
/* Iterate over subsets */
for (int j = i; ; j=(j-1) & i ) {
B[i] += A[j]; /* it is an `sum`, actually it can be a mpz_add here */
if(j==0) break;
}
}
My I mentioned, that almost any sum is recomputed from the values, summed earlier. I suggest, there can be code, doing the same task in the time of n* 2^n sums.
My first idea is that B[i] = B[i_without_the_most_significant_bit] + A[j_new]; where j_new is only j's having the most_significant bit from i in '1' state. This halves my time, but this is not enough (still hours and days on real problem size):
int A[1<<n];
int B[1<<n];
B[0] = A[0]; // the i==0 will not work with my idea and clz()
for (int i = 1; i < (1<<n); i++ ) {
int msb_of_i = 1<< ((sizeof(int)*8)-__builtin_clz(i)-1);
int i_wo_msb = i & ~ msb;
B[i] = B[i_wo_msb];
/* Iterate over subsets */
for (int j_new = i; ; j_new=(j_new-1) & i ) {
B[i] += A[j_new];
if(j_new==msb) break; // stop, when we will try to unset msb
}
}
Can you suggest better algorithm?
Additional image, list of i and j summed for each i for n=4:
i j`s summed
0 0
1 0 1
2 0 2
3 0 1 2 3
4 0 4
5 0 1 4 5
6 0 2 4 6
7 0 1 2 3 4 5 6 7
8 0 8
9 0 1 8 9
a 0 2 8 a
b 0 1 2 3 8 9 a b
c 0 4 8 c
d 0 1 4 5 8 9 c d
e 0 2 4 6 8 a c e
f 0 1 2 3 4 5 6 7 8 9 a b c d e f
Note the similarity of figures
PS the msb magic is from here: Unset the most significant bit in a word (int32) [C]
Divide and conquer anyone? Now not in-place.
void sums(int *a, int n, int *b) {
if (n <= 0) {
*b = *a;
return;
}
int m = 1 << (n - 1);
sums(a, n - 1, b);
sums(a + m, n - 1, b + m);
for (int i = 0; i < m; i++) {
b[m + i] += b[i];
}
}