SQL Factorial ErlangC - tsql

I am trying to use this factorial in an ErlangC Function.. However my number of Agents can get up to the 300s. With this you can get pretty large numbers. For example. My question is how do I store and calculate these numbers? Is there a way in native SQL. I know I can go to CLR and make an outside function. But for simplicity I would like to keep this native SQL. Really trying to get to 9 and 10 from here. But I will get that done when I solve this one. Thank you in advance for any assistance you can provide.
ALTER FUNCTION [dbo].[Factorial] ( #iNumber int )
RETURNS float
AS
BEGIN
Declare #i float
IF #iNumber <= 1
SET #i = 1
ELSE
SET #i = #iNumber
WHILE #iNumber > 1
BEGIN
SET #i = #i * (#iNumber - 1)
Set #iNumber = #iNumber -1
END
RETURN (#i)
END
ErlangC code is as follows:
ALTER FUNCTION [AMS].[ErlangC]
(
-- Add the parameters for the function here
#m float -- Number of Agents
,#u float -- Traffic floatensity
)
RETURNS float
AS
BEGIN
--Source http://www.mitan.co.uk/erlang/elgcmath.htm Number 6
-- Return Variable
DECLARE #Prob Float -- Probability of Call not being answered immediately and having to wait.
-- Variables
Declare #Numerator Float -- Top of Equation
Declare #Denominator Float -- Bottom of Equation
Declare #Summation float -- Summation part of Denominator
Declare #k float -- increment for summation
--Calculate Numerator
SET #Numerator = Power(#u,#m)/dbo.Factorial(#m)
-- Start Summation with k starting at 0.
SET #k = 0
SET #Summation = 0
While #k < #m-1
Begin
SET #Summation = #Summation + Power(#u,#k)/dbo.Factorial(#k)
SET #k = #k +1
End
--Calculate denominator
SET #Denominator = Power(#u,#m)/dbo.Factorial(#m) + (1-#u/#m)*#Summation
SET #Prob = #Numerator/#Denominator
-- Return the result of the function
RETURN #Prob
END

Well I found someone else's code and it works... But I am not sure why.. basically instead of doing the factorial they do the power and factorial together using a logarithm to get the same number as if you had exponentially multiplied out the numbers.
ALTER FUNCTION [dbo].[PowerFactorial] ( #m float, #u float)
RETURNS float
AS
BEGIN
Declare #counter float --counter
Declare #total float -- return value
SET #counter = 1
SET #total = 0
WHILE #counter <= #u
BEGIN
SET #total = #total + Log(#m/#counter)
Set #counter= #counter + 1
END
RETURN Exp(#total)
END
Which would change ErlangC to this.
ALTER FUNCTION [AMS].[ErlangC]
(
-- Add the parameters for the function here
#m float -- Number of Agents
,#u float -- Traffic intensity
)
RETURNS float
AS
BEGIN
--Source http://www.mitan.co.uk/erlang/elgcmath.htm Number 6
-- Return Variable
DECLARE #Prob Float -- Probability of Call not being answered immediately and having to wait.
-- Variables
Declare #Numerator Float -- Top of Equation
Declare #Denominator Float -- Bottom of Equation
Declare #Summation float -- Summation part of Denominator
Declare #k float -- increment for summation
--Calculate Numerator
SET #Numerator = dbo.PowerFactorial(#u,#m)
-- Start Summation with k starting at 0.
SET #k = 0
SET #Summation = 0
While #k < #m-1
Begin
SET #Summation = #Summation + dbo.PowerFactorial(#u,#k)
SET #k = #k +1
End
--Calculate denominator
SET #Denominator = dbo.PowerFactorial(#u,#m) + (1-#u/#m)*#Summation
SET #Prob = #Numerator/#Denominator
-- Return the result of the function
RETURN #Prob
END
If anyone has any insight on how the function works please comment. Thanks..

Related

Can not assign values to an array when using sample() function

I'm trying to implement a DFT on my own because the FFT example in OpenModelica is not working for me and I can't figure out why.
But I'm already stuck sampling a sine function and assigning the sampled values to a buffer array.
This is why I tried to make it even simpler and just assign a counter variable "iTick" to the array which still doesn't work.
See the basic example.
Can anyone tell me why this is not working and how I can actually assign a value to the array when using the sample() function ??
block DFT
import Modelica.Constants.pi;
parameter Integer N = 360 "Total number of samples";
Integer iTick;
Real y_buf[N];
algorithm
when sample(0, 0.1) then
iTick :=iTick + 1;
if iTick >= 1 and iTick <= N then
y_buf[iTick] := iTick;
end if;
end when;
end DFT;
[358] 14:56:15 Symbolisch Warnung
The linear system:
1 : $PRE.y_buf[2] = y_buf[2]
2 : y_buf[2] = $PRE.y_buf[2]
[
-1.0 , 1.0 ;
1.0 , -1.0
]
*
[
y_buf[2] ;
$PRE.y_buf[2]
]
=
[
0.0 ;
0.0
]
might be structurally or numerically singular for variable $PRE.y_buf[2] since U(2,2) = 0.0. It might be hard to solve. Compilation continues anyway.
[359] 14:56:15 Symbolisch Warnung
The linear system:
1 : $PRE.y_buf[1] = y_buf[1]
2 : y_buf[1] = $PRE.y_buf[1]
[
-1.0 , 1.0 ;
1.0 , -1.0
]
*
[
y_buf[1] ;
$PRE.y_buf[1]
]
=
[
0.0 ;
0.0
]
might be structurally or numerically singular for variable $PRE.y_buf[1] since U(2,2) = 0.0. It might be hard to solve. Compilation continues anyway.
[360] 14:56:15 Übersetzung Warnung
Assuming fixed start value for the following 2 variables:
y_buf[360]:DISCRETE(fixed = false ) type: Real [360]
iTick:DISCRETE(fixed = false ) type: Integer
After a long search and try and error I found out that the magic word "discrete" solves my problem! I can't yet explain why, but see below the working example:
model Test
import Modelica.Constants.pi;
parameter Integer N = 360 "Total number of samples";
Integer iTick(start=0, fixed=true);
discrete Real y_buf[N](start=fill(0,N), fixed=fill(true, N));
algorithm
when sample(0, 0.1) then
iTick :=iTick + 1;
if iTick >= 1 and iTick <= N then
y_buf[iTick] := iTick;
end if;
end when;
end Test;
Hopefully this is a help to someone!
Your "Symbolisch Warnung" disappears once you initialize iTick and y_buf. However, the code still does not work. OpenModelica simulates it, but the items of y_buf are never updated.
This issue might be related to this question where the delay operator is not working in algorithm sections. Therefore, I suggest a similar workaround: Try to avoid the algorithm section. With an equation section and proper initialization, your minimal example could look as follows:
block DFT
import Modelica.Constants.pi;
parameter Integer N = 360 "Total number of samples";
Integer iTick(start=0, fixed=true);
Real y_buf[N](start=fill(0, N), fixed=fill(true, N));
equation
when sample(0, 0.1) then
iTick = pre(iTick) + 1;
end when;
for i in 1:N loop
when iTick >= i then
y_buf[i] = iTick;
end when;
end for;
end DFT;

Systemverilog coverage point for multiple of n

I am trying to create a bin in my coverage group to sample values that are multiple of n (where n is a constant integer in my case 15). So far, I have came
up with the following code:
class rx_port;
int unsigned rx_rates[];
...
covergroup rx_cov with function sample (int unsigned rate);
coverpoint rate{
bins no_rate = {0};
bins mul_of_15 = {SOME_PRE_DEFINED_PATTERN};
}
endgroup;
....
endclass
Where SOME_PRE_DEFINED_PATTERN is an array of int from 0 to a system macro with the step of 15. I am not sure if this is the correct/best way of generating this bin. Any better suggestion?
How about writing some helper functions:
module FIFTEEN;
class rx_port;
typedef enum {IS_ZERO, IS_DIVISIBLE_BY_15, IS_NOT_DIVISIBLE_BY_15} rate_type;
function new;
rx_cov=new;
endfunction
local function rate_type covergroup_helper(input int unsigned i);
if (i==0) return IS_ZERO;
if (i%15==0) return IS_DIVISIBLE_BY_15;
return IS_NOT_DIVISIBLE_BY_15;
endfunction
function sample (input int unsigned i);
rx_cov.sample(covergroup_helper(i));
endfunction
covergroup rx_cov with function sample (rate_type rate);
coverpoint rate;
endgroup;
endclass
rx_port R = new;
initial
begin
void'(R.sample(0));
void'(R.sample(30));
void'(R.sample(31));
$display("coverage R.rx_cov.get_coverage= %f", R.rx_cov.get_coverage);
end
endmodule
https://www.edaplayground.com/x/65v7
Here I've written a function that determines whether its input is divisible by 15 or not and another function which calls that to do the sampling. You could combine those functions together, but I like the division of labour in my example.
It turns out that there is a better way:
module FIFTEEN;
class rx_port;
function new;
rx_cov=new;
endfunction
function sample (input int unsigned i);
rx_cov.sample(i);
endfunction
covergroup rx_cov with function sample (int unsigned rate);
coverpoint rate {
bins IS_ZERO = {0};
bins IS_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)==0);
bins IS_NOT_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)!=0);
}
endgroup;
endclass
rx_port R = new;
initial
begin
void'(R.sample(0));
void'(R.sample(30));
void'(R.sample(31));
$display("coverage R.rx_cov.get_coverage= %f", R.rx_cov.get_coverage);
end
endmodule
https://www.edaplayground.com/x/3T5v
You can use with to specify bins. So
bins IS_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)==0);
gives you a bin that is hit whenever the value is divisible by 15 (but not 0) and
bins IS_NOT_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)!=0);
gives you a bin that is hit whenever the value is not divisible by 15.

How to convert Matlab code to Delphi?

How to convert this part of Matlab code to Delphi?
for i=1:popsize
fi=rand(1,dimension); % Generate a vector of uniform random numbers
p=pbest(i,:);
pbest(i,:)=x(i,:);
end
My code:
for i:= 1 to popsize do
begin
fi:= // which function generates vector of uniform random numbers in Delphi?
for k :=1 to popsize do
begin
p:=pbest(i,k);
pbest(i,k):=x(i,k);
end;
end;
You can call Random function to generate a uniformly distributed random value. Calling Randomize once makes Random generate different values in each run.
var
fi: array of Double;
J: Integer;
begin
Randomize;
for J := 0 to dimension - 1 do
fi[J] := Random;
end;

Ones count system-verilog

I have a wire vector with 64 bits;
wire [63:0] sout;
I want to compute the sum of these bits or, equivalently, count the number of ones.
What is the best way to do this? (it should be synthesizable)
I prefer using for-loops as they are easier to scale and require less typing (and thereby less prone to typos).
SystemVerilog (IEEE Std 1800):
logic [$clog2($bits(sout)+1)-1:0] count_ones;
always_comb begin
count_ones = '0;
foreach(sout[idx]) begin
count_ones += sout[idx];
end
end
Verilog (IEEE Std 1364-2005):
parameter WIDTH = 64;
// NOTE: $clog2 was added in 1364-2005, not supported in 1364-1995 or 1364-2001
reg [$clog2(WIDTH+1)-1:0] count_ones;
integer idx;
always #* begin
count_ones = {WIDTH{1'b0}};
for( idx = 0; idx<WIDTH; idx = idx + 1) begin
count_ones = count_ones + sout[idx];
end
end
The $countones system function can be used. Refer to the IEEE Std 1800-2012, section "20.9 Bit vector system functions". It might not be synthesizable, but you did not list that as a requirement.
"Best" is rather subjective, but a simple and clear formulation would just be:
wire [6:0] sout_sum = sout[63] + sout[62] + ... + sout[1] + sout[0];
You might be able to think hard and come up with something that produces better synthesized results, but this is probably a good start until a timing tool says it's not good enough.
The following solution uses a function to calculate the total number of set (to High) bits in a 64-bits wide bus:
function logic [6:0] AddBitsOfBus (
input [63:0] InBus
);
AddBitsOfBus[2:0] = '0;
for (int k = 0; k < 64; k += 1) begin // for loop
AddBitsOfBus[6:0] += {6'b00_0000, InBus[k]};
end
endfunction
The following synthesizable SystemVerilog functions do this for you:
$countbits(sout,'1); // Counts the # of 1's
$countbits(sout,'0); // Counts the # of 0's
$countones(sout); // equivalent to $countbits(sout,'1)
The logic the synthesis tools will produce is a different story.
Ref: IEEE Std 1800-2012, Section 20.9

ERROR: missing "LOOP" at end of SQL expression

I'm getting the above error in my code, which indicates the 'while' line.
I'm trying to find the number of intersection points to a line on some gis data.
I've copied the code verbatim, the postgis code shouldn't affect the problem.
(And if I'm trying to do this in a really stupid way, please say. I'm only a beginner)
create or replace function border() returns table(x real, sum bigint) as $$
declare x real;
begin
x := -35.5724;
while x > -36.4 do
return query select x,sum(st_npoints(st_intersection(the_geom,st_setsrid(st_makeline(st_point(173.3,x),st_point(175,x)),4167)))) from auckland_numberlines;
x := x - 0.1;
end while
end
$$ language plpgsql;
while x > -36.4 do
return query select x,sum(st_npoints(st_intersection(the_geom,st_setsrid(st_makeline(st_point(173.3,x),st_point(175,x)),4167)))) from auckland_numberlines;
x := x - 0.1;
end while
should be
WHILE x > -36.4 LOOP
return query select x,sum(st_npoints(st_intersection(the_geom,st_setsrid(st_makeline(st_point(173.3,x),st_point(175,x)),4167)))) from auckland_numberlines;
x := x - 0.1;
END LOOP ;