C++ 应用于阵列时使阵列积分的最小正乘数
给定一个由C++ 应用于阵列时使阵列积分的最小正乘数,c++,c,algorithm,boost,eigen,C++,C,Algorithm,Boost,Eigen,给定一个由n非负元素组成的数组,C/C++库中是否有一个函数返回最小的正乘数,当应用于数组的每个元素时返回一个整数 例如,如果n=2的数组是1.66667,2.33333,则乘法器将是3。因为当我们用3乘以数组中的每个元素时,我们得到了5,7,两者都是整数 如果数组为8,10,则乘数为0.5。这将给我们提供4,5 (1) 在诸如boost、eigen等著名的库中,是否有有效的函数来实现这一点 (2) 如果库中没有可用的数据,那么计算倍数的有效算法是什么?与您指定的否不同。问题是十进制值1.666
n
非负元素组成的数组,C/C++库中是否有一个函数返回最小的正乘数,当应用于数组的每个元素时返回一个整数
例如,如果n=2
的数组是1.66667,2.33333
,则乘法器将是3。因为当我们用3乘以数组中的每个元素时,我们得到了5,7
,两者都是整数
如果数组为8,10
,则乘数为0.5。这将给我们提供4,5
(1) 在诸如boost
、eigen
等著名的库中,是否有有效的函数来实现这一点
(2) 如果库中没有可用的数据,那么计算倍数的有效算法是什么?与您指定的否不同。问题是十进制值
1.66667
和2.33333
没有这样的乘数:您假设的近似值来自,从数学的角度来看,这是一种任意的舍入策略
还有一些浮点属性需要考虑,因此可以使用double
或float
排除任何问题
在这里,您最好使用一个分数类来表示数字。然后,任何普通的乘法器都会因为一些简单的数学运算而退出
请参见在一般情况下,您的问题没有很好的解决方案,因为值是以浮点格式存储的,该格式具有有限精度,并且只能精确存储分母为2次幂的分数。例如,
0.1*10
在您的平台上可能不是一个完整的值
如果从整数量计算数组中的值,则应将它们表示为具有适当大小整数对的标准化分数,并计算其分母的最小公倍数
如果需要问题的近似解决方案,可以指定epsilon的值,然后手动设计解决方案。我想不出任何库函数可以满足这一需求,但暴力解决方案很容易编写:
unsigned long long ullgcd(unsigned long long a, unsigned long long b) {
/* compute the greatest common divisor using Euclid's elegant method */
if (a < b)
return ullgcd(b, a);
else
if (b == 0)
return a;
else
return ullgcd(b, a % b);
}
double least_multiple(double *a, size_t n, double epsilon) {
for (double mult = 1;; mult += 1) {
size_t i;
unsigned long long div = 0;
for (i = 0; i < n; i++) {
double d = fabs(a[i] * mult);
unsigned long long v = round(d);
if (fabs(v - d) > epsilon)
break;
div = ullgcd(v, div);
}
if (i == n)
break;
}
/* mult is the smallest non zero integer that fits your goal.
the smallest multiplier is obtained by dividing it
by the greatest common divisor of the resulting integer array.
*/
return mult / div;
}
无符号长ullgcd(无符号长a,无符号长b){
/*用欧几里德的优雅方法计算最大公约数*/
if(aε)
打破
div=ullgcd(v,div);
}
如果(i==n)
打破
}
/*mult是符合您的目标的最小非零整数。
最小的乘数是除以它得到的
由结果整数数组的最大公约数。
*/
返回mult/div;
}
看一下Rosetta代码,因为我不熟悉C,所以我将C代码转换成Python(尽管我认为Python可能有一些相关的库),并添加了一些可以轻松适应C的函数。如果分数转换中的分母都是1.0
,我们除以数字列表中的最大公约数。否则,我们返回唯一分母的乘积
导入数学
进口经营者
def f(arr):
ε=4
分数=[arr中i的大鼠_近似值(i,16**epsilon)]
#分数转换中的分母均为1.0
如果总和([denom表示分数中的(num,denom)]==len(分数):
返回1.0/gcd_/u(分数中的[num代表(num,denom)])
其他:
#否则,返回唯一分母的乘积
返回reduce(operator.mul,set([denom for(num,denom)的分数]),1)
def gcd(a、b):
如果a
输出:
f([8,10])
=> 0.5
f([1.66667,2.33333])
=> 3.0
2.33333*3
是6.99999
,而不是7
。不,没有这样的函数。你需要自己写。似乎是个X-Y问题……我认为至少对于浮点型来说,这是不可能的,因为浮点型的对象不能准确地表示实数。也许您可以使用有理数类型,并基于该类型实现此函数。浮点数可以被视为整数*2^指数。因此,如果您的乘法器应该是整数,那么您正在寻找2的幂。很遗憾,有些数组元素将是另一个返回普通浮点数的程序的输出。你知道boost是否能用分数有效地逼近任意的双精度值吗?@Tryer:这样的函数太“基于意见”或“依赖用户”,所以不知道。你必须自己构建那个位,这取决于你准备承受的容忍度。从rational类开始,用一些有趣的方法构建一个适用于y的构造方法