将米哈伊尔的答案扩展为对于从1到n的所有数字计算阶乘的正确答案,其中n <500,以下解决方案成立并且可以有效地进行计算:
我需要在Google BigQuery中计算变量的阶乘-是否有为此功能?我在这里的文档中找不到一个:
https://cloud.google.com/bigquery/query-reference#arithmeticoperators
我目前建议的解决方案是计算数字1到100的阶乘并将其作为表上传并与该表联接。如果您有更好的东西,请提出建议。
由于上下文可能揭示最佳解决方案,因此阶乘用于计算随机变量(时间窗口中的事件数)的泊松概率。参见此处的第一个方程式:https://en.wikipedia.org/wiki/Poisson_distribution
尝试以下。快速而肮脏的示例
select number, factorial
FROM js(
// input table
(select number from
(select 4 as number),
(select 6 as number),
(select 12 as number)
),
// input columns
number,
// output schema
"[{name: 'number', type: 'integer'},
{name: 'factorial', type: 'integer'}]",
// function
"function(r, emit){
function fact(num)
{
if(num<0)
return 0;
var fact=1;
for(var i=num;i>1;i--)
fact*=i;
return fact;
}
var factorial = fact(r.number)
emit({number: r.number, factorial: factorial});
}"
)
如果直接方法适用于所需的值,则需要计算泊松分布,然后冷却。如果达到极限或无法获得准确的结果,请继续阅读以进行数值分析。
通常,如果对数进行算术运算,然后将exp()作为最终运算,则将获得更好的范围和数值稳定性。
但是,如何在不计算k!的情况下得到ln(k!)?有一个函数叫做gamma函数,在这里的实际要点是它的对数gammaln()可以直接近似,而ln(k!)= gammaln(k + 1)。
Phil Mainwaring的answer here中有一个Javascript gammaln(),我尚未测试过,但是假设它可以工作,那么它应该适合您的UDF。
将米哈伊尔的答案扩展为对于从1到n的所有数字计算阶乘的正确答案,其中n <500,以下解决方案成立并且可以有效地进行计算:
select number, factorial
FROM js(
// input table
(
SELECT
ROW_NUMBER() OVER() AS number,
some_thing_from_the_table
FROM
[any table with at least LIMIT many entries]
LIMIT
100 #Change this to any number to compute factorials from 1 to this number
),
// input columns
number,
// output schema
"[{name: 'number', type: 'integer'},
{name: 'factorial', type: 'float'}]",
// function
"function(r, emit){
function fact(num)
{
if(num<0)
return 0;
var fact=1;
for(var i=num;i>1;i--)
fact*=i;
return fact;
}
#Use toExponential and parseFloat to handle large integers in both Javascript and BigQuery
emit({number: r.number, factorial: parseFloat(fact(r.number).toExponential())});
}"
)
您最多可以起床27!使用SQL UDF。大于该值的NUMERIC类型将发生溢出错误。
CREATE OR REPLACE FUNCTION factorial(integer_expr INT64) AS ( (
SELECT
ARRAY<numeric>[
1,
1,
2,
6,
24,
120,
720,
5040,
40320,
362880,
3628800,
39916800,
479001600,
6227020800,
87178291200,
1307674368000,
20922789888000,
355687428096000,
6402373705728000,
121645100408832000,
2432902008176640000,
51090942171709440000.,
1124000727777607680000.,
25852016738884976640000.,
620448401733239439360000.,
15511210043330985984000000.,
403291461126605635584000000.,
10888869450418352160768000000.][
OFFSET
(integer_expr)] AS val ) );
select factorial(10);
将米哈伊尔的答案扩展为对于从1到n的所有数字计算阶乘的正确答案,其中n <500,以下解决方案成立并且可以有效地进行计算:
您最多可以起床27!使用SQL UDF。大于该值的NUMERIC类型将发生溢出错误。