C++ 什么';在计算多项式时,跳过0系数是一种有效的方法吗?
我正在研究一个单核的微芯片(stm32f103c8t6),我想计算一些多项式,使其达到预定的指数,因此C++ 什么';在计算多项式时,跳过0系数是一种有效的方法吗?,c++,performance,polynomials,C++,Performance,Polynomials,我正在研究一个单核的微芯片(stm32f103c8t6),我想计算一些多项式,使其达到预定的指数,因此f(x)=a0+a1*x+a2*x^2+…+an*x^n其中n在编译时已知 系数a0…an将在运行期间发生变化,其中一些很可能变为零,我想找到一种方法,在计算f(x)时跳过这些系数。注意,大多数将是非零的。理想情况下,我希望在运行时重写f(x),这样零的系数就不再存在于函数中,但我不想进入自修改代码领域(除非有一些简单的方法在C++中实现)。微芯片能够进行单指令乘法,因此,任何等效于使用if语句
f(x)=a0+a1*x+a2*x^2+…+an*x^n
其中n在编译时已知
系数a0…an将在运行期间发生变化,其中一些很可能变为零,我想找到一种方法,在计算f(x)时跳过这些系数。注意,大多数将是非零的。理想情况下,我希望在运行时重写f(x),这样零的系数就不再存在于函数中,但我不想进入自修改代码领域(除非有一些简单的方法在C++中实现)。微芯片能够进行单指令乘法,因此,任何等效于使用if语句检查系数是否为零的解决方案都将与仅计算整个表达式相同或更慢
评估会发生很多次,因此即使在评估函数时保存一个周期也是有帮助的。目前我没有一个可行的解决方案,我只是把多项式作为一个整体来评估
我正在用C++编写微芯片,虽然我现在正在研究Python中的算法,因为它更容易绘制结果,所以我没有任何代码来解决这个问题。< P>使用有限状态机。您需要为每个可能的状态编写代码。但这可能是最快的计算方法 这是一个示例,它使用示例数学函数和迭代的示例值。OP必须为每个状态提供自己的数学函数和迭代值
#include <iostream>
int main(int argc, char *argv[]){
/* MAX_COEFFICIENTS <-- states == 2^coefficients */
const int MAX_COEFFICIENTS = 3;
int coefficientsv[] = {1, 0, 3}; /* {A, B, C} */
int coefficientsc = sizeof coefficientsv / sizeof coefficientsv[0];
if(coefficientsc > MAX_COEFFICIENTS) return -1; /* Out of bounds! */
register int A = 0, B = 0, C = 0;
for(int i = 0; i < coefficientsc; i++){
if(i == 0) A = coefficientsv[i];
else if(i == 1) B = coefficientsv[i];
else if(i == 2) C = coefficientsv[i];
}
register long polycalc = 0; /* or use just int, if int is big enough */
register int iteration = 1000; /* example value */
/* state truth table */
/* A B C */
/* 0 0 0 goto STATE_0 */
/* 1 0 0 goto STATE_A */
/* 0 1 0 goto STATE_B */
/* 1 1 0 goto STATE_AB */
/* 0 0 1 goto STATE_C */
/* 1 0 1 goto STATE_AC */
/* 0 1 1 goto STATE_BC */
/* 1 1 1 goto STATE_ABC */
STATE_SELECT:
if(!A && !B && !C) goto STATE_0;
if( A && !B && !C) goto STATE_A;
if(!A && B && !C) goto STATE_B;
if( A && B && !C) goto STATE_AB;
if(!A && !B && C) goto STATE_C;
if( A && !B && C) goto STATE_AC;
if(!A && B && C) goto STATE_BC;
if( A && B && C) goto STATE_ABC;
STATE_0:
while(iteration){
polycalc = 0;
iteration--;
}
goto END;
STATE_A:
while(iteration){
polycalc = A;
iteration--;
}
goto END;
STATE_B:
while(iteration){
polycalc = B * B;
iteration--;
}
goto END;
STATE_AB:
while(iteration){
polycalc = A + B * B;;
iteration--;
}
goto END;
STATE_C:
while(iteration){
polycalc = C * C * C;
iteration--;
}
goto END;
STATE_AC:
while(iteration){
polycalc = A + C * C * C;
iteration--;
}
goto END;
STATE_BC:
while(iteration){
polycalc = B * B + C * C * C;
iteration--;
}
goto END;
STATE_ABC:
while(iteration){
polycalc = A + B * B + C * C * C;
iteration--;
}
/* Example: Pseudo-Code */
/* Maybe your first calculation has shown that C becomes 0. */
/* So simply use "goto STATE_AB", maybe set some variables. */
/* In another example, you only know that some coefficient */
/* has become 0, but you don't know which one, */
/* so use "goto STATE_SELECT", maybe set some variables too. */
goto END;
END:
std::cout << polycalc << std::endl;
return 0;
}
#包括
int main(int argc,char*argv[]){
/*MAX_系数MAX_系数)返回-1;/*超出范围*/
寄存器int A=0,B=0,C=0;
对于(int i=0;i std::cout使用有限状态机。您需要为每个可能的状态编写代码。但这可能是最快的计算方法
这是一个示例,它使用示例数学函数和迭代的示例值。OP必须为每个状态提供自己的数学函数和迭代值
#include <iostream>
int main(int argc, char *argv[]){
/* MAX_COEFFICIENTS <-- states == 2^coefficients */
const int MAX_COEFFICIENTS = 3;
int coefficientsv[] = {1, 0, 3}; /* {A, B, C} */
int coefficientsc = sizeof coefficientsv / sizeof coefficientsv[0];
if(coefficientsc > MAX_COEFFICIENTS) return -1; /* Out of bounds! */
register int A = 0, B = 0, C = 0;
for(int i = 0; i < coefficientsc; i++){
if(i == 0) A = coefficientsv[i];
else if(i == 1) B = coefficientsv[i];
else if(i == 2) C = coefficientsv[i];
}
register long polycalc = 0; /* or use just int, if int is big enough */
register int iteration = 1000; /* example value */
/* state truth table */
/* A B C */
/* 0 0 0 goto STATE_0 */
/* 1 0 0 goto STATE_A */
/* 0 1 0 goto STATE_B */
/* 1 1 0 goto STATE_AB */
/* 0 0 1 goto STATE_C */
/* 1 0 1 goto STATE_AC */
/* 0 1 1 goto STATE_BC */
/* 1 1 1 goto STATE_ABC */
STATE_SELECT:
if(!A && !B && !C) goto STATE_0;
if( A && !B && !C) goto STATE_A;
if(!A && B && !C) goto STATE_B;
if( A && B && !C) goto STATE_AB;
if(!A && !B && C) goto STATE_C;
if( A && !B && C) goto STATE_AC;
if(!A && B && C) goto STATE_BC;
if( A && B && C) goto STATE_ABC;
STATE_0:
while(iteration){
polycalc = 0;
iteration--;
}
goto END;
STATE_A:
while(iteration){
polycalc = A;
iteration--;
}
goto END;
STATE_B:
while(iteration){
polycalc = B * B;
iteration--;
}
goto END;
STATE_AB:
while(iteration){
polycalc = A + B * B;;
iteration--;
}
goto END;
STATE_C:
while(iteration){
polycalc = C * C * C;
iteration--;
}
goto END;
STATE_AC:
while(iteration){
polycalc = A + C * C * C;
iteration--;
}
goto END;
STATE_BC:
while(iteration){
polycalc = B * B + C * C * C;
iteration--;
}
goto END;
STATE_ABC:
while(iteration){
polycalc = A + B * B + C * C * C;
iteration--;
}
/* Example: Pseudo-Code */
/* Maybe your first calculation has shown that C becomes 0. */
/* So simply use "goto STATE_AB", maybe set some variables. */
/* In another example, you only know that some coefficient */
/* has become 0, but you don't know which one, */
/* so use "goto STATE_SELECT", maybe set some variables too. */
goto END;
END:
std::cout << polycalc << std::endl;
return 0;
}
#包括
int main(int argc,char*argv[]){
/*MAX_系数MAX_系数)返回-1;/*超出范围*/
寄存器int A=0,B=0,C=0;
对于(int i=0;iint max_idx = a.size() - 1;
float result = a[max_idx];
int i = max_idx;
while (i > 0) {
-- i;
result = a[i] + x * result;
}
return result;
// compute powers between nonzero coefficients
int max_idx = a.size() - 1;
assert(a[max_idx] != 0); // you should not have leading zeroes in the first place
std::vector<int> inc_powers;
std::vector<int> inc_indices;
int inc_pow = 0;
int i = max_idx;
while (i > 0) {
-- i;
++ inc_pow;
if (a[i] != 0 || i == 0) {
inc_powers.push_back(inc_pow);
inc_indices.push_back(i);
inc_pow = 0;
}
}
int i = a.size() - 1;
float result = a[i];
for (int i = 0; i < inc_powers.size(); ++i) {
result = a[inc_indices[i]] + x_powers[inc_powers[i]] * result;
}
return result;
int max_powers = 0;
for (power: inc_powers) {
if (power > max_powers) { max_powers = power; }
}
std::vector<float> x_powers(max_powers + 1);
float value = x;
for (int i = 1; i < max_powers; ++i) {
x_powers[i] = value;
value *= x;
}
x_powers[max_powers] = value;