Cot(0) gives division by zero warning

octave:1> cot(0)
warning: division by zero
warning: called from
cot at line 33 column 5

what version are you running?

on Windows, Octave 6.3.0, i just got:

>> cot(0)
ans = Inf

which matches Matlab 2021a output.

GNU Octave, version 5.2.0 in Linux Mint 20.2
I can not easily update this version…

ok. looks like cot is just an m file calling 1./tan(x). since tan is a compiled function, i’m not sure if there’s anything else that could really be done for an older version of the code. since it’s just a warning, not an error, you could just turn off that warning if it’s a problem.

does the answer return as Inf?

It looks working normally in that sense, the answer is Inf.
ans = Inf
Maybe this cot(x) is not available and it is using the 1/tan(x).
But it looks quite disturbing if there is no reason for the warning as this.
If it use 1/tan(x) the accuracy may not be good at x ~ 0 region, but accuracy looks quite good.
Maybe this case the accuracy of the ‘pi’ is the problem:

octave:18> cot(pi/2)
ans =    6.123233995736766e-17
octave:25> cot(pi/2-64*eps)
ans =    1.427208705515937e-14


However using cotd() seems to be ‘exact’:

octave:3> cotd(90)
ans = 0

Octave’s output is the same as Matlab. for both the pi/2 and pi/2 - 64*eps answers. Within the accuracy limits of floating point arithmetic, I think you may be asking for more than it can give. if you need variable precision arithmetic, the symbolic package has a vpa() function that can give you as many decimals of accuracy as you could want.

I guess the problem as accuracy of the pi, because it is numeric:

octave:5> cot(pi)
ans =   -8.1656e+15
octave:6> cotd(180)
warning: division by zero
warning: called from
    cotd at line 33 column 5
ans =  Inf

But it looks accuracy is good enough though.

But what about exp() and arg() -functions? Can they have degree format also?
Similarly as expd() and argd()?

octave:8> exp(i*pi/2)
ans =  6.1232e-17 + 1.0000e+00i
octave:9> expd(i*90)
error: 'expd' undefined near line 1 column 1
octave:9> arg(i)
ans =  1.5708

To use the 360 degree system. Otherwise the 90-degree case will not be accurate.
Using
expd=complex(cosd(90),sind(90));
could help remove the inaccuracy at near 90-degree.
But how to fix the arg to argd (is it needed?)?

octave:4> exp(i*pi)
ans = -1.0000e+00 + 1.2246e-16i
octave:5> expd=complex(cosd(180),sind(180))
expd = -1 + 0i

Also with sind() & cosd() case I find some inaccuracies as:

octave:2> cosd(45)-sind(45)
ans =    1.1102e-16
octave:2> sind(30)-cosd(60)
ans =   -1.6653e-16
octave:3> sind(60)-cosd(30)
ans =   -1.1102e-16

And some cases it works fine:

octave:2> sind(90)-cosd(0)
ans = 0
octave:3> cosd(90)-sind(0)
ans = 0

And also in radians some case works, some not:

octave:1> cos(pi/2)-sin(0)
ans =    6.1232e-17
octave:2> sin(pi/2)-cos(0)
ans = 0

Below cases seem to work nicely:

octave:1> sin(pi/2)^2+cos(pi/2)^2-1
ans = 0
octave:2> sin(0)^2+cos(0)^2-1
ans = 0

But it failed if its used as:

octave:4> sind(45)^2+sind(45)^2-1
ans =   -2.2204e-16
octave:5> cosd(45)^2+cosd(45)^2-1
ans =    2.2204e-16

But I guess accuracy is not problem necessarily…
Checking:

for i=1:91, d(i,1)=sind(i-1)-cosd(91-i); end
for i=1:91, d(i,1)=sind(i-1)^2+cosd(i-1)^2-1; end
for i=1:91, d(i,1)=sind(i-1)^2+sind(91-i)^2-1; end
for i=1:91, d(i,1)=cosd(i-1)^2+cosd(91-i)^2-1; end

It could be irritating that largest errors (just below or exactly at eps) occur at 45 degree angle…
It could depend on the floating point register’s size (in number of bits).
If there was one bit more the highest error could shift into other area than 45 degrees.
Most likely this is not important question.

octave:41> dec2bin(floor(cosd(45)*2^52))
ans = 1011010100000100111100110011001111111001110111100110
octave:42> dec2bin(floor(sind(45)*2^52))
ans = 1011010100000100111100110011001111111001110111100110
octave:43> dec2bin(floor(cosd(45)*2^53))
ans = 1011010100000100111100110011001111111001110111100110`1`
octave:44> dec2bin(floor(sind(45)*2^53))
ans = 10110101000001001111001100110011111110011101111001100
octave:45> dec2bin(floor(cosd(45)*2^54))
ans = 1011010100000100111100110011001111111001110111100110`1`0
octave:46> dec2bin(floor(sind(45)*2^54))
ans = 101101010000010011110011001100111111100111011110011000
octave:47> dec2bin(floor(cosd(45)*2^55))
ans = 1011010100000100111100110011001111111001110111100110100
octave:48> dec2bin(floor(sind(45)*2^55))
ans = 1011010100000100111100110011001111111001110111100110000

If the number was cut (at LSB) at the point where there is following two or more zeros for the 1/sqrt(2) or sind(45) or cosd(45), that might shift the error from 45 degree point to some other point.
The exact value is (LSB cut point at ’ = 2^-52 following one zero)
1011010100000100111100110011001111111001110111100110'0100100001
If LSB cut point was at " = 2^-58 (following 3 zeroes)
1011010100000100111100110011001111111001110111100110010010"0001
it might have more accuracy at 45 degree case, but if making the calculation slower
would cause problems then instead.
But of course each function could have different cut point where it’s behavior is is more or less chaotic and this might not fit into the all the cases of all the functions and their arguments…

octave:3> sind(45)*sind(45)-0.5
ans =   -1.1102e-16
octave:4> 1/sqrt(2)*1/sqrt(2)-0.5
ans =   -5.5511e-17
octave:5> cosd(45)*cosd(45)-0.5
ans =    1.1102e-16

I guess the best way then is just to cut the result with the eps.
So that for example:

octave:1> sin(pi)
ans = 1.2246e-16
octave:2> x=pi; y=sin(x); if abs(y)<eps, y=0; end; [x y]
ans =
3.14159 0.00000

pi (3.14159…) in binary is:
11.00100100001111110110101010001000100001011010001100'0010001101
Thus the input argument pi for sin()&cos() may have high uncertainty and there is possibly no safe cut point that has following four or more zeroes and if someone using pi/2, pi/4 etc, the cut point would shift to point with following ‘1’ after ‘0’ or something like that.
I guess the accuracy is good,if it can be managed so that there is not coming these residues out.
If there is problem it is maybe with the handling of the inaccuracies/residues.
I guess the technology like WFA (Wolfram alpha) can ‘cascade’ the FPU registers to
make use more than 52bits if more bits/decimals is needed in the result. I don’t know
can this be possible with octave also?

I understand if you cannot easily upgrade, but this is a very old and unsupported version of Octave. The behavior which is the title of the report no longer exists in current versions. The other topics belong to a different thread with a different title.

I hope soon I can update it…

11 posts were split to a new topic: Install recent Octave version in Linux Mint