HP Forums

Full Version: [CAS problem] High-precision operations in numerical solution equations
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone, I recently came across an x = tan (x) equation about x. Find x> 0, the solution over the interval [k * pi, (k + 1/2) * pi] (k is a positive integer). It is found that when k is taken large, the error occurs.
Code:
subst(tan(x)-x,x=fsolve(tan(x)=x,x=100000.5*pi))
Calculation output:142106699.971
Very large error。

mathematica supports high-precision operations
Code:
FindRoot[Tan[x] - x, {x, 100000.5*Pi}, WorkingPrecision -> 30]
Calculation output:{x -> 314160.836152123035796438894350}


I wrote it in C (dichotomy), compared it, and found that the error increases with increasing k.
Code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define pi 3.14159265358
#define n 10000
double MidPoint(double (*function)(double),double x0,double x1,double error)
{
     double start=x0,end=x1;
    do{
            if((*function)((start+end)*0.5)<0)
            {
                   start=(start+end)*0.5;
            }else
            {
                    end=(start+end)*0.5;
            }
    }while(end-start>error);
    return (end+start)*0.5;
}
double equation(double x) {return tan(x)-x;}
int main()
{
    double next,last=0;
    char s[20];
    FILE *file=fopen("/Users/yangyongkang/Desktop/a.txt","w");
    for(int k=1;k<=n;k++)
    {
         next=MidPoint(equation,k*pi,(k+0.5)*pi,1e-11);
         sprintf(s,"%f\n",last*last*sin(next-last));
         fputs(s,file);
         last=next;
    }
    fclose(file);
}


Contrast with MMA, found this
Code:
Show[ListPlot @@@ {{#1^2*Sin[#2 - #1] & @@@ 
     Partition[
      ParallelTable[
       First@Values@
         FindRoot[Tan[x] - x, {x, n*3.14159265358}, 
          WorkingPrecision -> 20], {n, 1.5, 10000.5, 1}], 2, 1], 
    PlotStyle -> Red}, {ToExpression@
     StringSplit@Import["/Users/yangyongkang/Desktop/a.txt"]}}]



Red represents the MMA result, blue represents the C language calculation result, and the accuracy gap is widened.
(04-01-2020 01:03 PM)yangyongkang Wrote: [ -> ]Hi everyone, I recently came across an x = tan (x) equation about x. Find x> 0, the solution over the
interval [k * pi, (k + 1/2) * pi] (k is a positive integer). It is found that when k is taken large, the error occurs.
Code:
subst(tan(x)-x,x=fsolve(tan(x)=x,x=100000.5*pi))
Calculation output:142106699.971
Very large error。

Solver might converge to a root outside your required interval.
It is better to solve for x, then calculate tan(x)-x

XCas> guess := 10000.5*pi
XCas> fsolve(tan(x)=x, x=guess)     → 7.72525183694
XCas> fsolve(tan(x)=x, x=guess)     → 4.49340945791

XCas> guess := 100000.5*pi                 → 314160.836155
XCas> x := fsolve(tan(x)=x,x=guess)     → 314160.836155 (not shown, but slightly less than guess)

XCas> tan(guess) - guess          → 27378944702.1              
XCas> tan(x) - x                       → 4735723246.82
XCas> x := 314160.836152       // Error for x is tiny, only -0.000003
XCas> tan(x) - x                       → -11691.0416004

For large guess (=pi/2 + k*pi), solved x is only slightly smaller.
We can estimate tan(x) = cot(guess-x) ≈ 1/(guess-x), and x ≈ guess

XCas> x := guess - 1/guess   // "solved" tan(x)=x, we have x = 314160.836152123
Your guess is at a singularity of the tan function (k*pi+pi/2), it's not surprising. You should rewrite your equation with atan
fsolve(x=atan(x)+100000*pi,x=100000*pi+pi/2)
(04-02-2020 12:00 PM)parisse Wrote: [ -> ]Your guess is at a singularity of the tan function (k*pi+pi/2), it's not surprising. You should rewrite your equation with atan
fsolve(x=atan(x)+100000*pi,x=100000*pi+pi/2)

About function header replacement, such as defining an anonymous function, f = lambda x, y: x + y,list(a,b)=[a,b]
I want f to act on list (a, b) and replace list with f. Replace list (a, b) with f (a, b).
A bit more complicated, such as list (list (a, b) ...), I want to replace the innermost list with f.

Based on your ideas, I wrote a bit of code.
Code:
plotlist((lambda l:map(range(0,length(l)-1),lambda index:(l[index])^2*sin(l[index+1]-(l[index]))))([seq(fsolve(equal(x,atan(x)+k*π),equal(x,(k+0.5)*π)),equal(k,1 .. 10000))]))

Got the error storm graph。
Reference URL's