So, I've been trying to implement an N length FFT in VHDL but I can't seem to get the right outputs. I believe it's because of the Twiddle Factor but I'm unsure, I've been troubleshooting this for a while but can't find the solution
I've tried changing the Twiddle factor to another formula described on a couple of websites ((k/2**Stage)/N), like this, from one twiddle factor calculation website but it does not work.
constant M : integer := 3;
constant N : integer := 8;
constant Nminus1 : integer := 7;
constant TwoPiN : real := 2.0*MATH_PI/real(N);
Butterfly code :
TempRe := xtmp(kNs).re *WCos - xtmp(kNs).re * WSin;
TempIm := xtmp(kNs).im*WCos + xtmp(kNs).im*Wsin;
xtmp(kNs).re := xtmp(k).re - TempRe;
xtmp(kNs).im := xtmp(k).im - TempIm;
xtmp(k).re := xtmp(k).re + TempRe;
xtmp(k).im := xtmp(k).im + TempIm;
Main:process(x_in)
variable Ns, count ,Stage, k, kNs, p ,p_int, M1: integer;
variable Wcos, Wsin : real;
variable x : complexArr;
begin
x := x_in; --copy insignal
Ns := N;
M1 := M;
count := 0;
for Stage in 1 to M loop
k := 0;
Ns := Ns/2; --index distance between a dual node pair
M1 := M1 - 1;
while(k< N) loop
for n in 1 to Ns loop
p := Digit_Reverse(k/2**(M-1));
Wcos := cos(TwoPiN*real(p));--W to the power of p
Wsin := - sin(TwoPiN*real(p)); --W = exp(\u2212 j2\u03c0/N)
kNs := k + Ns;
Butterfly(x,k,kNs,Wcos,Wsin);
k := k + 1;
count := count +1;
end loop;
k := k + Ns;
end loop;
end loop;
Unscramble(x); --output
x_ut <= x;
No errors but I expect the correct values, for 2048 length FFT, but at the moment I'm troubleshooting the 16 point FFT and 8 point FFT with [-1;i]-[1;i] etc.
Related
I've been using a quicksort function to sort my stringlists, but as an exercise I wanted to try and code an heapsort function too. Unfortunately it does not work and I can't understand why. The utility functions I use work (because I use them in the quicksort script too and trying both on a list the quicksort one works and the other doesn't)
{------------------------------------------------------------------------------}
Procedure Heapify(AList : TStringList; N, Root : Integer);
Var
Max, L, R : Integer;
Begin
Max := Root;
L := (2 * Root) + 1;
R := (2 * Root) + 2;
If (L < N) And (ListSort(AList, Max, L) < 0 {function to compare strings, read as List[L]>List[Max]}) Then Max := L;
If (R < N) And (ListSort(AList, Max, R) < 0) Then Max := R;
If Max <> Root Then
Begin
ExchangeItems(AList, Root, Max); {Function to swap strings}
Heapify(AList, N, Max);
End;
End;
{------------------------------------------------------------------------------}
Procedure HeapSortStringList(AList : TStringList);
Var
I : Integer;
Begin
For I := (AList.Count / 2) - 1 DownTo 0 Do Heapify(AList, AList.Count, I);
For I := AList.Count - 1 DownTo 1 Do
Begin
ExchangeItems(AList, I, 0);
Heapify(AList, I, 0);
End;
End;
{------------------------------------------------------------------------------}
How did you compile this code?
Note that compiler gives us message:
[dcc32 Error] Unit2.pas(175): E2010 Incompatible types: 'Integer' and
'Extended'
(AList.Count / 2) should be (AList.Count div 2) for integers
After this correction code becomes working.
Part of the program I have checks if an input number is a perfect number. We're supposed to find a solution that runs in O(sqrt(n)). The rest of my program runs in constant time, but this function is holding me back.
function Perfect(x: integer): boolean;
var
i: integer;
sum: integer=0;
begin
for i := 1 to x-1 do
if (x mod i = 0) then
sum := sum + i;
if sum = x then
exit(true)
else
exit(false);
end;
This runs in O(n) time, and I need to cut it down to O(sqrt(n)) time.
These are the options I've come up with:
(1) Find a way to make the for loop go from 1 to sqrt(x)...
(2) Find a way to check for a perfect number that doesn't use a for loop...
Any suggestions? I appreciate any hints, tips, instruction, etc. :)
You need to iterate the cycle not for i := 1 to x-1 but for i := 2 to trunc(sqrt(x)).
The highest integer divisor is x but we do not take it in into account when looking for perfect numbers. We increment sum by 1 instead (or initialize it with 1 - not 0).
The code if (x mod i = 0) then sum := sum + i; for this purpose can be converted to:
if (x mod i = 0) then
begin
sum := sum + i;
sum := sum + (x div i);
end;
And so we get the following code:
function Perfect(x: integer): boolean;
var
i: integer;
sum: integer = 1;
sqrtx: integer;
begin
sqrtx := trunc(sqrt(x));
i := 2;
while i <= sqrtx do
begin
if (x mod i = 0) then
begin
sum := sum + i;
sum := sum + (x div i) // you can also compare i and x div i
//to avoid adding the same number twice
//for example when x = 4 both 2 and 4 div 2 will be added
end;
inc(i);
end;
if sum = x then
exit(true)
else
exit(false);
end;
You play a game with 100 opponents. The game has k rounds. Every round you can eliminate some opponents (always atleast 1). You are rewarded for eliminating them.
The reward is: 100.000 * '# of eliminated opponents' / '# of opponents' <= in integers (rounded down)
I want to eliminate the opponents in a way, that gets me the largest amount of money possible.
Example game:
number of rounds = 3
first round we eliminate 50 opponents, so we get 100.000 * 50 / 100 = +50.000
second round we eliminate 30, so we get 100.000 * 30 / 50 = +60.000
last round we eliminate last 20 opponents, so we get 100.000 * 20 / 20 = +100.000
so the total winnings are: 210.000
I tried to write up something, but I don't think it's the most effective way to do it?
Program EliminationGame;
var
selectedHistory : array [1..10] of integer;
opponentCount,roundCount : integer;
maxOpponents,numberSelected : integer;
totalMoney : integer;
i : integer;
begin
totalMoney := 0;
maxOpponents := 100;
opponentCount := maxOpponents;
roundCount := 3; {test value}
for i:=1 to roundCount do begin
if (i = roundCount) then begin
numberSelected := opponentCount;
end else begin
numberSelected := floor(opponentCount / roundCount);
end;
selectedHistory[i] := numberSelected;
totalMoney := floor(totalMoney + (numberSelected / opponentCount * 100000));
opponentCount := opponentCount - numberSelected;
end;
writeln('Total money won:');
writeln(totalMoney);
writeln('Amount selected in rounds:');
for i:= 0 to Length(selectedHistory) do
write(selectedHistory[i],' ');
end.
Also it seems that floor function does not exist in pascal?
It seems the question has a maths answer that can be calculated in advance. As #Anton said it was obvious that the number of points given during the third round did not depend upon the number of eliminated enemies. So the third round should eliminate 1 enemy.
So We get the following function for a thre-round game.
f(x)=100000x/100+100000(99-x)/(100-x)+100000*1/1, where x- the number
of enemies eleminated at first round.
if we find the extrema (local maximum of the function) it appears equal to 90. That means the decision is the following: the first round eliminates 90 the second - 9, the third - 1 enemy.
Of course, for consideration: 90=100-sqrt(100).
In other words: the Pascal decision of the task is to loop a variable from 1 to 99 and see the maximum of this function. X-will be the answer.
program Project1;
var
x, xmax: byte;
MaxRes, tmp: real;
begin
xmax := 0;
MaxRes := 0;
for x := 1 to 99 do
begin
tmp := 100000 * x / 100 + 100000*(99 - x) / (100 - x) + 100000 * 1 / 1;
if tmp > MaxRes then
begin
MaxRes := tmp;
xmax := x;
end;
end;
writeln(xmax);
readln;
end.
The general decision for other number of enemies and rounds (using recursion) is the following (Delphi dialect):
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
Uses System.SysUtils;
var
s: string;
function Part(RemainingEnemies: byte; Depth: byte;
var OutputString: string): real;
var
i: byte;
tmp, MaxRes: real;
imax: byte;
DaughterString: string;
begin
OutputString := '';
if Depth = 0 then
exit(0);
imax := 0;
MaxRes := 0;
for i := 1 to RemainingEnemies - Depth + 1 do
begin
tmp := i / RemainingEnemies * 100000 + Part(RemainingEnemies - i, Depth - 1,
DaughterString);
if tmp > MaxRes then
begin
MaxRes := tmp;
imax := i;
OutputString := inttostr(imax) + ' ' + DaughterString;
end;
end;
result := MaxRes;
end;
begin
writeln(Part(100, 3, s):10:1);//first parameter-Enemies count,
//2-Number of rounds,
//3-output for eliminated enemies counter
writeln(s);
readln;
end.
This problem can be solved with a dynamic approach.
F(round,number_of_opponents_remained):
res = 0
opp // number_of_opponents_remained
for i in [1 opp]
res = max(res, opp/100 + F(round-1,opp - i) )
return res
I should say this not the complete solution and you add some details about it, and I am just giving you an idea. You should add some details such as base case and checking if opp>0 and some other details. The complexity of this algorithm is O(100*k).
I need an algorithm to print all possible sums of a number (partitions).
For example: for 5 I want to print:
1+1+1+1+1
1+1+1+2
1+1+3
1+2+2
1+4
2+3
5
I am writing my code in Pascal. So far I have this:
Program Partition;
Var
pole :Array [0..100] of integer;
n :integer;
{functions and procedures}
function Minimum(a, b :integer): integer;
Begin
if (a > b) then Minimum := b
else Minimum := a;
End;
procedure Rozloz(cislo, i :integer);
Var
j, soucet :integer;
Begin
soucet := 0;
if (cislo = 0) then
begin
for j := i - 1 downto 1 do
begin
soucet := soucet + pole[j];
if (soucet <> n) then
Write(pole[j], '+')
else Write(pole[j]);
end;
soucet := 0;
Writeln()
end
else
begin
for j := 1 to Minimum(cislo, pole[i - 1]) do
begin
pole[i] := j;
Rozloz(cislo - j, i + 1);
end;
end;
End;
{functions and procedures}
{Main program}
Begin
Read(n);
pole[0] := 101;
Rozloz(n, 1);
Readln;
End.
It works good but instead of output I want I get this:
1+1+1+1+1
2+1+1+1
2+2+1
3+1+1
3+2
4+1
5
I can't figure out how to print it in right way. Thank you for help
EDIT: changing for j:=i-1 downto 1 to for j:=1 to i-1 solves one problem. But my output is still this: (1+1+1+1+1) (2+1+1+1) (2+2+1) (3+1+1) (3+2) (4+1) (5) but it should be: (1+1+1+1+1) (1+1+1+2) (1+1+3) (1+2+2) (1+4) (2+3) (5) Main problem is with the 5th and the 6th element. They should be in the opposite order.
I won't attempt Pascal, but here is pseudocode for a solution that prints things in the order that you want.
procedure print_partition(partition);
print "("
print partition.join("+")
print ") "
procedure finish_and_print_all_partitions(partition, i, n):
for j in (i..(n/2)):
partition.append(j)
finish_and_print_all_partitions(partition, j, n-j)
partition.pop()
partition.append(n)
print_partition(partition)
partition.pop()
procedure print_all_partitions(n):
finish_and_print_all_partitions([], 1, n)
Before i must say this : Please, excuse me for my bad english...
I'm student.My teacher gave me problem in pascal for my course work...
I must write program that calculates 2^n for big values of n...I've wrote but there is a problem...My program returns 0 for values of n that bigger than 30...My code is below...Please help me:::Thanks beforehand...
function control(a: integer): boolean;
var
b: boolean;
begin
if (a >= 10) then b := true
else b := false;
control := b;
end;
const
n = 200000000;
var
a: array[1..n] of integer;
i, j, c, t, rsayi: longint; k: string;
begin
writeln('2^n');
write('n=');
read(k);
a[1] := 1;
rsayi := 1;
val(k, t, c);
for i := 1 to t do
for j := 1 to t div 2 do
begin
a[j] := a[j] * 2;
end;
for i := 1 to t div 2 do
begin
if control(a[j]) = true then
begin
a[j + 1] := a[j + 1] + (a[j] div 10);
a[j] := a[j] mod 10;
rsayi := rsayi + 1;
end;
end;
for j := rsayi downto 1 do write(a[j]);
end.
The first (nested) loop boils down to "t" multiplications by 2 on every single element of a.
30 multiplications by two is as far as you can go with a 32-bit integer (2^31-1 of positive values, so 2^31 is out of reach)
So the first loop doesn't work, and you probably have to rethink your strategy.
Here is a quick and dirty program to compute all 2^n up to some given, possibly large, n. The program repeatedly doubles the number in array a, which is stored in base 10; with lower digit in a[1]. Notice it's not particularly fast, so it would not be wise to use it for n = 200000000.
program powers;
const
n = 2000; { largest power to compute }
m = 700; { length of array, should be at least log(2)*n }
var
a: array[1 .. m] of integer;
carry, s, p, i, j: integer;
begin
p := 1;
a[1] := 1;
for i := 1 to n do
begin
carry := 0;
for j := 1 to p do
begin
s := 2*a[j] + carry;
if s >= 10 then
begin
carry := 1;
a[j] := s - 10
end
else
begin
carry := 0;
a[j] := s
end
end;
if carry > 0 then
begin
p := p + 1;
a[p] := 1
end;
write(i, ': ');
for j := p downto 1 do
write(a[j]);
writeln
end
end.