How to do a bubble sort in Occam - occam-pi

I am trying to program in occam, and I think that it is not so easy to understand because the documentation is not so good. Anyway, I hope someone to help me.
I am trying just to learn how make a simple program. A bubble sort in occam.
#INCLUDE "course.module"
[32]INT x:
INT aux:
BOOL flag:
flag:= TRUE
aux:=0
--put values on the array
SEQ k=0 for 10
x[i] = -x[i]
-- bubble sort
WHILE (flag)
SEQ i = 0 for 9
IF
x[i] > x[i+1]
aux:= x[i]
x[i]:= x[i+1]
x[i+1] := aux
flag:= false
:
I got this image on the terminal:
What is wrong with this code?

occam-pi is indentation sensitive
A few hints in the code may help and courtesy of TiO-IDE may provide a place for online experimentation:
#INCLUDE "course.module"
PROC main( CHAN BYTE keyboard, screen, error )
[32]INT x:
INT aux:
BOOL flag:
SEQ -- ------------------------- BoSEQ:
SEQ i = 0 FOR 31 -- SEQ used as <-an-iterator->
x[i] := i -- put values on the array
SEQ i = 0 FOR 10 -- SEQ used as <-an-iterator->
x[i] := -x[i] -- put values on the array
flag := TRUE
WHILE ( flag ) -- WHILE
SEQ -- SEQ as a bubble sort
SEQ i = 0 FOR 10 -- SEQ used as <-an-iterator->
IF -- IF
x[i] > x[i+1] -- CASE: x[i] > x[i+1]
SEQ -- SEQ of steps
aux := x[i] -- 1
x[i] := x[i+1] -- 2
x[i+1] := aux -- 3
-- -- -- -- -- -- -- -- -- -- -- -- -- --
-- INTERESTING [occam-pi] FEATURE IS, THAT
-- [occam-pi] CAN _SWAP_ IN-PLACE
-- USING JUST x[i], x[i+1] := x[i+1], x[i]
TRUE -- OTHERWISE:
SKIP
-- SEQ used above as <-an-iterator-> got exhausted
flag := FALSE -- SET FALSE
-- ----------------------------- EoSEQ:
: -- main()

Related

Radix 2 DIT Twiddle factor calculation VHDL

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.

SAS assigning binary values if variable matches in first instance for 'n' times for unsorted data

I hope you guys are well.
DATA: The input data is unsorted and hence I am using hash tables to take the input data, do some iterations, sort and then output. Sorting the original table prior to any iterations (using proc sort) would be a time-consuming effort. If there is no other option, then I will need to sit down for the gruesome sorting approach.
What I want: I am trying to enumerate a table variable "answer" with binary values (0/1) if variable filter = "Y" for the next 6 month observations with the same client. In some instances, the client is missing from some monthly observations eg: client FG5151 is missing from September and October 2006. In short if variable filter "Y" then this observation and the next 6 months observations for same client should be assigned variable "answer" eq 1, else 0.
data have;
input client $ dates date9. filter $;
datalines ;
Fg5151 28.Feb.06 N
Fg5151 31.Mar.06 N
Fg5151 30.Apr.06 N
Fg5151 31.May.06 Y
Fg5151 30.Jun.06 N
Fg5151 31.Jul.06 Y
Fg5151 31.Aug.06 N
Fg5151 30.Nov.06 N
Fg5151 31.Dec.06 N
Fg5151 01.Jan.07 N
A101 28.Feb.06 N
A101 31.Mar.06 N
A101 30.Apr.06 Y
A101 31.May.06 N
A101 30.Jun.06 N
A101 31.Jul.06 N
ABC123 31.Mar.06 N
;
data want;
input client $ dates date9. filter $ answer;
datalines ;
A101 28.Feb.06 N 0
A101 31.Mar.06 N 0
A101 30.Apr.06 Y 1
A101 31.May.06 N 1
A101 30.Jun.06 N 1
A101 31.Jul.06 N 1
ABC123 31.Mar.06 N 0
Fg5151 28.Feb.06 N 0
Fg5151 31.Mar.06 N 0
Fg5151 30.Apr.06 N 0
Fg5151 31.May.06 Y 1
Fg5151 30.Jun.06 N 1
Fg5151 31.Jul.06 Y 1
Fg5151 31.Aug.06 N 1
Fg5151 30.Nov.06 N 1
Fg5151 31.Dec.06 N 1
Fg5151 01.Jan.07 N 0
;
I have written both a hash statement and a data step statement. I dont know how to approach this problem:
/* data step approach */
data want;
set have;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
call symput('xdate',dates);
answer=1;
c=1;
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
end;
run;
/* hash method approach */
data _null_;
set have end=last;
if _n_ = 1 then do;
length newdate 8 answer 8 c 8;
format newdate ddmmyy10.;
declare hash hs(ordered: "a",hashexp: 9);
hs.defineKey("client","dates");
hs.defineData("client","dates","filter","answer","c");
hs.defineDone();
end;
rc = hs.find();
by client dates notsorted;
if rc ne 0 then do;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
answer=1;
c=1;
hs.add();
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
hs.replace();
end;
hs.replace();
end;
if last eq 1 then do;
hs.output(dataset:
"not_working");
end;
run;
Any help would be greatly appreciated.
thank you.
regards,
S
One option is PROC FORMAT. This has a sort in it, but only of the filter='Y' folks, so hopefully that's minimal; and it's actually unnecessary if you are confident your data is grouped (but not sorted) by client (ie, you can skip it, it will not delete anything), and in fact with the m option being used anyway (to avoid worrying about collisions) you probably can skip it regardless.
This is not super-fast necessarily, because it uses putn function instead of put statement. You will have to see how it performs on larger datasets.
The idea here is we construct a format that defines the range of 'Y' for each record, and uses hlo='o' option to define the rest of the ragne as n.
data for_fmt;
set have;
by client notsorted;
if filter='Y' then do;
start = dates;
end = intnx('Month',dates,5,'s');
hlo=' m';
fmtname=cats(client,'F');
label='Y';
output;
end;
if last.client then do;
fmtname=cats(client,'F');
call missing(of start end);
hlo='om';
label='N';
output;
end;
run;
proc sort nodupkey data=for_fmt;
by fmtname start;
run;
proc format cntlin=for_fmt;
quit;
data want;
set have;
answer = putn(dates,cats(client,'F'));
run;

Division on the last outputs

Counter count the number of input samples. Then the counter output (n) and I want to check if the number of samples is even,then n_of_samples = (n*n) else if odd make that ((n*n)-1)
will be something like that
signal dis : integer range 0 to 255 := 0;
signal n : integer range 0 to 255 :=0;
if n mod 2=1 then
n_of samples<= ((n*n)-1);
else
n_of_samples <= n*n;
end if;
norm_dis <= dis / n_of_samples ;
the two signals will have values as (1,6,9,8,.....100) and (0,2,8,9.......,200)
and i want to fetch the two last outputs from the two signal (100,200)
and divide 100/200.how can i write it in vhdl and how can overcome the divide by zero error.
just make sure that you do not divide by zero!
if n_of_samples/=0 then
norm_dis <= dis / n_of_samples ;
end if;

Stats with random numbers

I want to create 7 stats for a character, randomly generating a value from 3-21, with the stat's sum being no higher than 91. I've tried arranging the stats into an array, and just going through them like this:
1) add random(15) to each array member
2) computing the total, subtracting from the 91 maximum
3) dividing this difference by 7
4) do step 1 with random(difference) adding it to the stat
5) Until I hit the 91 total.
Doing this a few hundred times I seem to get a curve where the 5,6, and 7th stats tend to be higher. And sometimes I hit the 4 or 5th stat and there are no more numbers to be added, meaning then that the first few stats get the most points. I think I am approaching this the wrong way to begin with. Any ideas? I have tunnel vision at this point I think.
It sounds like you're overthinking this. I might do something like this :
const
STAT_QTY = 7;
STATSUM_MAX = 91;
STAT_MIN = 3;
STAT_MAX = 21;
type
TStatArray = Array [0..STAT_QTY-1] of integer;
Then in implementation :
function GenerateStats : TStatArray;
var statArr : TStatArray;
i, statSum, excess, debit : integer;
done : boolean;
begin
Randomize;
done := false;
while not done do begin
done := true;
statSum := 0;
for i := 0 to STAT_QTY - 1 do begin
statArr[i] := STAT_MIN + Random(STAT_MAX - STAT_MIN);
statSum := statSum + statArr[i];
end;
if statSum > STATSUM_MAX then begin
excess := statSum - STATSUM_MAX;
debit := excess div STAT_QTY + 1;
for i := 0 to STAT_QTY -1 do begin
statArr[i] := statArr[i] - debit;
end;
end;
for i := 0 to STAT_QTY -1 do begin
if statArr[i] < STAT_MIN then done := false;
end;
end;
result := statArr;
end;
This generates a list of random stats in the range 3-21. If the sum is more than 91 then divide the excess by the number of stats (use div then round up the answer) and subtract an equal number from each. In the rare case that you end up with stats less than three, just do it again. Job done.
Tested over 2000 iterations I get average stats of :
[1] : 11.13893053
[2] : 11.15692154
[3] : 11.16141929
[4] : 11.11444278
[5] : 11.10194903
[6] : 10.9800100
[7] : 10.86856572
That's a total average of 11.07 with a standard deviation of 0.11 - certainly about what one would expect from a generally random set with your construction parameters.
Here's C-ish pseudo code for a slightly different approach, assuming a suitable random(N) function that returns numbers in the range 0 - N-1.
int stats[7], deficit = 70;
for (int i = 0; i < 7; ++i)
stats[i] = 3; // initial assignments of the minimum to each stat
while (deficit)
{ int tmp = random(7); // pick a random stat to bump
if (stats[tmp] == 21) // but not if it's already at max
continue;
++stats[tmp];
--deficit;
}
Assuming your random() is uniformly distributed, that should give pretty good results.

Pascal Bubble Sort

I have a project where the program must accept 10 words and display the words in descending order (alphabetical order from Z-A)
using bubble sorting.
Here's what I know so far:
Program sample;
uses crt;
TYPE
no._list=ARRAY(1...10)OF REAL;
CONST
no.:no._list=(20.00,50.50.35.70....);
VAR
x:INTEGER;
small:REAL;
BEGIN clrscr:
small:=no.(1);
FOR x:=2 TO 10 DO
IF small>number(x);
writeln('Smallest value in the array of no.s is',small:7:2);
END
I really don't know how to do this though and could use some help.
Here's a video by Alister Christie on Bubble sort describing the principle :
http://codegearguru.com/index.php?option=com_content&task=view&id=64&Itemid=1
The algorithm in Pascal can be found # http://delphi.wikia.com/wiki/Bubble_sort
function BubbleSort( list: TStringList ): TStringList;
var
i, j: Integer;
temp: string;
begin
// bubble sort
for i := 0 to list.Count - 1 do begin
for j := 0 to ( list.Count - 1 ) - i do begin
// Condition to handle i=0 & j = 9. j+1 tries to access x[10] which
// is not there in zero based array
if ( j + 1 = list.Count ) then
continue;
if ( list.Strings[j] > list.Strings[j+1] ) then begin
temp := list.Strings[j];
list.Strings[j] := list.Strings[j+1];
list.Strings[j+1] := temp;
end; // endif
end; // endwhile
end; // endwhile
Result := list;
end;

Resources