【问题标题】:Return a preferred root from the square root of a function从函数的平方根返回首选根
【发布时间】:2014-03-06 23:00:53
【问题描述】:

我正在尝试解决以下等式的特殊情况,其中 l=b=0;它应该返回一个完美平方函数的平方根,例如平方((x-d)^2)。这可以有两种解决方案,(x-d)或(d-x)。我想获得 (x-d) 作为我的最终解决方案,但程序默认返回 (d-x) 解决方案。我尝试改变 d 和 x 的位置,但似乎没有任何效果。这是我的程序:

float y(float x) {
  float l=0., b=0., d=8.5, r_0=3., z_0=0.1;
  return exp(-pow(x*x*cos(b*PI/180.)*cos(b*PI/180.)+d*d-2*d*x*cos(b*PI/180.)*cos(l*PI/180.), 0.5)/r_0)*exp(-x*pow(1-cos(b*PI/180.)*cos(b*PI/180.),0.5)/z_0) ;
}
int main(){
  FILE* fp =NULL;
  float x0,xn,step,s,int_val, tau; /* s = distance to the star from the sun*/

  int i,n, j ;
  scanf("%f%f%d",&x0,&xn,&n);
  step = (xn-x0)/n;
  s = y(x0) + y(xn);
  fp = fopen("trap.txt", "w");
  for(i = 1; i < n; i++) {
    s += 2*y(x0+i*step);
    fprintf(fp,"%e\n",s*step/2);
  }
  fclose(fp);

【问题讨论】:

  • 是否缺少某些代码?
  • 该指数至少有一个优化可能,即1-cos^2(x)=sin^2(x) 等。另外,你有什么理由不能只取负分支?

标签: c square-root


【解决方案1】:

我假设您正在谈论这部分:

-pow( x*x*cos( b*PI / 180. )*cos( b*PI / 180. ) + d*d - 2 * d*x*cos( b*PI / 180. )*cos( l*PI / 180. ), 0.5 )

首先,实际上有一个函数double sqrt( double x ) 用于计算平方根。

第二件事是,与数学携手并进,sqrt( square( anything ) ) 将返回absolutevalue( anything )。在您的示例中,sqrt( (x-d)^2 ) 将等同于 absolutevalue( x-d )。由于absolutevalue( x-d ) 等于absolutevalue( d-x ),因此更改值的位置不会改变任何内容...

如果x &gt; d,那么它将评估为x - d;否则d - x,这就是数学所说的。

不改变位置,但您可以简单地在整个 sqrt( square( ) ) 之前放一个减号来改变他们的位置。你已经有一个减号了,你可以简单地删除它。

知道平方的平方根等于绝对值,您还可以将我上面写的特定提取替换为fabs( x * cos( b * PI / 180. ) - d ),其中fabs 是采用double 的绝对值的函数,并在math.h 中定义。

【讨论】:

  • 简化为 fabs( x * cos( b * PI / 180. ) - d ) 有效,因为 l0.0?
  • 非常感谢您的帮助
  • 如果l == b,但cos( l*PI / 180. ) != 1.0,公式不会简化为fabs( x * cos( b * PI / 180. ) - d )
【解决方案2】:

使用替换来替换重复的术语。使用选择常量,简化。

#include <math.h>
#define PI 3.1415926535897932384626433832795

float y(float x) {
  float l=0., b=0., d=8.5, r_0=3., z_0=0.1;
  double y;
  // y = exp(-pow(x*x*cos(b*PI/180.)*cos(b*PI/180.)+d*d-2*d*x*cos(b*PI/180.)*cos(l*PI/180.), 0.5)/r_0)
  // y *= exp(-x*pow(1-cos(b*PI/180.)*cos(b*PI/180.),0.5)/z_0);
  if (l != 0.0 || b != 0.0) {
    double xcosb = x*cos(b*PI/180.);
    double xsinb = x*sin(b*PI/180.);
    double  cosl =   cos(l*PI/180.);
    // general solution
    y = exp(-sqrt(xcosb*xcosb - 2*xcosb*d*cosl + d*d)/r_0);
    y *= exp(-xsinb/z_0);  // @abiessu
  } else {
    // y = exp(-sqrt(x*x - 2*x*d*1.0 + d*d)/r_0);
    // y *= exp(-0/z_0);
    // y = exp(-sqrt((x-d)*(x-d))/r_0);
    // y *= 1.0;
    y = exp(-fabs(x - d))/r_0;
  }
  return y;
}

这确实获得了(x-d) 作为最终解决方案。建议 OP 检查函数的正确性。

【讨论】:

  • 感谢所有建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多