C++ Xtensor increase floating point significant numbers - c++

I am building a neural network and using xtensor for array multiplication in feed forward. The network takes in xt::xarray<double> and outputs a decimal number between 0 and 1. I have been given a sheet for expected output. when i compare my output with the provided sheet, I found that all the results differ after exactly 7 digits. for example if the required value is 0.1234567890123456, I am getting values like 0.1234567-garbage-numbers-so-that-total-numbers-equal-16, 0.1234567993344660, 0.1234567221155667.
I know I can not get that exact number 0.1234567890123456 due to floating point math. But how can I debug/ increase precision to be close to that required number. thanks
Update:
xt::xarray<double> Layer::call(xt::xarray<double> input)
{
return xt::linalg::dot(input, this->weight) + this->bias;
}
for code I am simply calling this call method a bunch of times where weight and bias are xt::xarray<double> arrays.

Related

Whats wrong with setprecision in my compiler?

I've been having trouble with my compiler, NetBeans. It seems that using setprecision is not doing anything. Here is the code needed to see what's happening. This part of the program check to see if a triangle it possible given three sides.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main(){
double SideA,SideB,SideC,p,a,longest;
cout<<"Enter the length of each side of your triangle. Press enter after each number."<<endl;
cin>>SideA>>SideB>>SideC;
cout<<fixed<<setprecision(3);
if(SideA+SideB<=SideC||SideA+SideC<=SideB||SideB+SideC<=SideA||SideA<=0||SideB<=0||SideC<=0)
{
cout<<"The length of the first side is "<<SideA<<"."<<endl;
cout<<"The length of the second side is "<<SideB<<"."<<endl;
cout<<"The length of the third side is "<<SideC<<"."<<endl;
cout<<"This triangle is impossible."<<endl;
}
return 0;
}
My problem is that I want the side length to be rounded to the nearest thousandths when shown on the screen. It does not do this with my NetBeans compiler. I've put this into online compilers, and it works there.
Here's my C++ configuration in NetBeans:
The sample input data is: 6.6666666, 5.4444444, 1
The expected output is: 6.667, 5.443, 1.000
The actual output is: 6.66667, 5.44444, 1
Your code is behaving correctly. You are using cout to display the values of double variables, and by default it will use a precision of 6:
A double value will be printed using a general format that usually
works fine to represent a number in a small amount of space. The basic
amount of space used is determined by the precision. The default
precision is 6, which means up to 6 significant digits are used to
represent the number. This counts digits both to the left and the
right of the decimal point. Fewer digits are printed if the result is
accurate; e.g. trailing zeros at the right of the decimal point are
not printed. As shown in the example below, as the number increases in
size, places to the right of the decimal point will be dropped, and
the result rounded off as needed to stay within 6 digits.
The text in bold font explains the output you obtained for your sample input: 6.66667, 5.44444, and 1.
You can limit the precision to obtain the results you want by using cout.precision() or setprecision(). This is also detailed in the linked article.
Finally, note that this is issue has nothing to do with NetBeans. You can confirm this by using g++ to compile your code from the command line. When you run it you will get the same results, even though you are not using NetBeans.

extract opengl version from version string

Im trying to get the current opengl verson.
glGetString(GL_VERSION) returns
"4.6.0 NVIDIA 391.01"
std::string strVersion = (const char*)glGetString(GL_VERSION);
strVersion = strVersion.substr(0, strVersion.find(" "));
float number = std::atof(strVersion.c_str());
float number = 4.59999990
why is the float not 4.6.0?
Why you don't get the third number
std::atof will take as many characters as it can that represent a decimal number. That's 4.6. The next dot cannot be part of the number, because there is no such thing as a decimal number with two dots. Decimal numbers only have one dot, separating the integer and the fractional parts.
Why you get 4.59999990 instead of 4.6
Because floating point numbers cannot store any possible combination of integer and fractional part. They have limited space to store information, so they always are just approximations. See is floating point math broken?.
How to get the version
A version is not a number. That version consists of three numbers, not one: 4, 6 and 0. They are integers, not decimal numbers. So you need to either just handle the version as a string:
if (strVersion == "4.6.0")
or you have to split it into three parts and get those integer values separately. See Splitting a C++ std::string using tokens for how to do that.

Obtaining exact positions

I have a simple code written in standard FORTRAN 77 for numerically integrating equations of motion. The integration loop is the following
yant=x0(2)
DO i=1,n-1
ti=t0+DBLE(i-1)*tstep
t=ti
CALL bstoer8(t,tstep,x,ndimf,ierr,derivs)
IF(x(2)*yant.LT.0d0)THEN
WRITE(52,'(7(F16.8))')t,x
ENDIF
yant=x(2)
ENDDO
The bstoer8 module contains the standard Bulirsh-Stoer integrator and it can be found here.
As we can see, I want to print, to an external data file, the time and all six vector elements (x, y, z, p_x, p_y, p_z) when y = 0.
However I do not get the exact times when y = 0. What I get is the closest time step. For example one of lines in the data file is the following
-0.17000000 10.45572291 0.00264921 -0.83321521 -0.21271715 45.32160003 -1.24830046
We observe that y is very small (0.00264921) but not exactly equal to zero. Moreover the time t contains only two decimal digits because the time step of the numerical integration is equal to 0.01.
So, my question is the following: How can I obtain the exact times when y = 0? In other words, how can I have y equal to 0 (with eight decimal digits) and the corresponding time with eight decimal digits?
Many thanks in advance!

SAS Format in calculation

I am creating New variable as AGE.The CUTOFF value is 100 and it is divided by 12 so the value is exactly 8.3333.....But Few freshness values are 8.3333333. I have to pick the value of SEGMENT if FRESHNESS>= 100/12, but its picking AMU where freshness is 8.3333... The format of FRESHNESS is F12.9 and CUTOFF is BEST12.
data new;
set SEGMENT_AGE;
IF Freshness< CUTOFF/12 THEN AGE=AMU;
ELSE AGE=SEGMENT;
RUN;
I tried with different format making cutoff to F12.9 , still its not working
You're running into an issue of floating point precision. If a number is a repeating decimal (in binary), you may have two different values (the higher or lower - ie, 0.333333333333333333 or 0.3333333333333333333334) depending on how it was arrived at. IE:
1-(1/3) - (1/3) = 0.33333333333333333334
0+(1/3) = 0.33333333333333333333
So do not assume it is precisely equal just because it looks like it should be. Further, some numbers in decimal that are not repeating decimals are repeating in binary - 7/10 for example is 0.7 decimal but is not storable precisely in binary.
You should compare rounded numbers if you need to compare precisely; for example,
if round(freshness,0.001) < round(cutoff/12,0.001) ...
should result in your calculations matching your expectations.

Scientific Notation with PrecisionEvaluate in Coldfusion

I have problems working with large numbers and long decimal numbers,
as others have mentioned or solved such issue using PrecisionEvaluate,
I could not get consistent result with such function.
Example with this code :
<cfset n = 0.000000000009>
<cfoutput>#precisionEvaluate(n)#</cfoutput> // this will produce "9E-12"
<cfoutput>#precisionEvaluate("n")#</cfoutput> // this will produce "0.000000000009"
According to Adobe Documentation, using Quote is not recommended (due to processing inefficiency) as well as it should produce same result, however this is not the case from the above code.
Further trials with inconsistent result:
<cfset n = 0.000000000009>
<cfset r = 12567.8903>
<cfoutput>#precisionEvaluate(r * n)#</cfoutput> // this will produce "1.131110127E-7"
<cfoutput>#precisionEvaluate("r * n")#</cfoutput> // this will produce "1.131110127E-7", same as above
<cfoutput>#precisionEvaluate(r / n)#</cfoutput> // this will produce "1396432255555555.55555555555555555556"
<cfoutput>#precisionEvaluate("r / n")#</cfoutput> // this will produce "1396432255555555.55555555555555555556", same as above
Has anybody run into problems with a similar case? What is a practical solution to address the inconsistency?
I have tried : using val() function does not resolve as it is limited to short numbers only,
using numberFormat() function which is difficult as we have to pass number of decimals to format it properly.
When it comes to numbers, do not always believe what you see on the screen. That is just a "human friendly" representation of the number. In your case, the actual results (or numbers) are consistent. It is just a matter of how those numbers are presented ..
PrecisionEvaluate returns a java.math.BigDecimal object. In order to display the number represented by that object inside <cfoutput>, CF invokes the object's toString() method. Per the API, toString() may use scientific notation to represent the value. That explains why it is used for some of your values, but not others. (Though with or without the exponent, it still represents the same number). However, if you prefer to exclude the exponent, just use BigDecimal.toPlainString() instead:
toPlainString() - Returns a string representation of this BigDecimal without an exponent
field....
Example:
<cfscript>
n = 0.000000000009;
r = 12567.8903;
result = precisionEvaluate(r * n);
WriteOutput( result.getClass().name );
WriteOutput("<br />result.toString() ="& result.toString());
WriteOutput("<br />result.toPlainString() ="& result.toPlainString());
</cfscript>
Result:
java.math.BigDecimal
result.toString() =1.131110127E-7
result.toPlainString() =0.0000001131110127