Obtaining exact positions - fortran

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!

Related

Identify the value with highest number of decimal values

I have a range of values and I want to count the decimal points of all values in the range and display the max count. the formula should exclude the zeroes at the end(not count ending zeroes in the decimal points).
for example, in the above sample, in the whole range the max of count of decimal places is 4 excluding the ending zeroes. so the answer is 4 to be displayed in cell D2
I tried doing regex, but do not know how do I do it for a whole range of values.
Please help!
try:
=INDEX(MAX(LEN(IFERROR(REGEXEXTRACT(TO_TEXT(A2:C4), "(\..+)")*1))-2))
Player0's solution is a good start, but uses TO_TEXT which seems to rely on the formatting of your cells.
If you want to safely compute the number of decimal places, use the TEXT function instead.
TEXT(number, format) requires a format whose max. number of decimal places has to be specified. There is no way around this, because formulas like =1/3 can have infinitely many decimal places.
Therefore, first decide on the max, precision for your use-case (here we use 8). Then use below function which works independently from your document's formatting and language:
=INDEX(MAX(
LEN(REGEXEXTRACT(
TEXT(ABS(A2:C4); "."&REPT("#";8));
"[,.].*$"
))-1
))
We subtract -1 since LEN(REGEXEXTRACT()) also counts the decimal separator (. for english, , for many others) .
Everything after the 8th decimal place is ignored. If all your numbers are something like 123.00000000987 the computed max. is 0. If you prefer it to be 8 instead, then add ROUNDUP( ; 8):
=INDEX(MAX(
LEN(REGEXEXTRACT(
TEXT(ROUNDUP(ABS(A2:C4);8); "."&REPT("#";8));
"[,.].*$"
))-1
))

how to correctly record the counting of averages between the minimum and maximum of the matrix on fortran

I was trying to write a program to calculate the average without considering the minimum and average of the columns, what is the best way to do this? To begin with, I wanted to simply output the average value of the columns to a file, there are no errors, but nothing is output.
Program Matrix
Implicit None
Real,Allocatable,dimension(:,:)::A
Real,Allocatable,dimension(:):: b
Integer varStr,varStlb
Integer i, j
real summa
Open(1,file='in.txt')
Open(8,file='out.txt')
Do
read(*,*)varStr,varStlb
Allocate(A(1:varStr,1:varStlb),B(1:varStlb))
Read(1,*) ( A(i,:), i = 1,varStr )
do j = 1, varStlb
summa = 0
do i = 1, varStr
summa = summa + a(j,i)
end do
b(j) = summa/varStr
write(8,'(A,F8.2,A)')'b = ',b(j), ' - сумма всех элементов'
end do
Deallocate(A)
Enddo
End Program Matrix
in file is
10.05 -22.0 3.0
4.0 0.0 60.0
8.0 13.0 22.5
As I wrote, there are too many points in your question. Therefore it is hard to make an answer, that covers your question well and does not give you just a solution to your homework without real understanding of the problem.
You have many problems or strange points in your code
I do not see the reason for the outer Do loop. In this loop you will try to read from the file many times. There is no protection to read past the end of the file.
When reading from the file you always allocate your arrays. But you never deallocate them In the next iteration of the outer Do loop you try to allocate them again, but that is not allowed, they are allocated already.
Perhaps you just wanted to read the whole file just once?
I always suggest to learn in steps. First read the file as you need it, print it, verify that it is in the form you needed. Only than compute normal averages. Only then compute averages that exclude maximum and minimum.
Ignoring the maximum and the minimum is simple, just subtract them from the sum and decrease the count of the elements by 2. However, as the rest of your code is so chaotic, it is impossible to just add it there. I will just show a sketch of the procedure:
Normal average of array a(1:n):
avg = sum(a) / n
Average of all elements except the maximum and the minimum:
avg2 = (sum(a) - minval(a) - maxval(a)) / (n - 2)

C++ Xtensor increase floating point significant numbers

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.

root mean square (RMSD) of two datasets

I'm dragging along in python, learning so slow but making progress. Have hit a wall, and don't even know where to start on this.
I have other scripts that get me to where I am now: two output CSV files with multiple rows containing 4 numbers each. The first number is an identifier integer, the other three are X, Y, Z coordinates.
Now the OTHER file is the same thing, with the same set of identifier integers, but a different set of X, Y, Z coordinates.
For each identifier integer, I want to calculate the RMSD between the X,Y,Z. In other words, I think I need to do (X2-X1)^2 + (Y2-Y1)^2 + (Z2-Z1)^2 then take the square root of that. This will give me a float as an output answer, which I'd like to write into an output file of two columns: one with the the identifier integer, and the second is the output from this script.
I actually have no idea where to start on this one.. I've never had to work with two files at once. Gah!
thanks so much!!
sorry I have no script to even start here!

Is it possible to ask Fortran to write out some results once the program is forced to stop?

I am solving a fixed point problem through the following algorithm:
1. specify grids x1,x2,x3,... xn
2. initial guess f=0 on all grids x1, x2, x3, ..., xn
3. update f according to some mapping T. f'=Tf on all grids.
4. calculate distance ||f'-f||. If greater than tolerance, go back to 3; otherwise, end.
5. Write a .txt file to record the solution f.
If let'say, I'm interested in checking out f and f' before the tolerance is reached (i.e. before the program jumps from 4 to 5), is there a way to ask Fortran to write out f and f' once the program is forced to stop? Something like:
IF (stop message received) THEN
PRINT f and f' to files
END IF
I know a variation of doing that is to write f and f' each time the function is updated. But that's perhaps too costly as the algorithm takes 100 seconds for 1 iteration and about 200 iterations to finish, which is approx. 6~7 hours.
Any thoughts and suggestions? Thanks!
So replace
4. calculate distance ||f'-f||. If greater than tolerance, go back to 3; otherwise, end.
5. Write a .txt file to record the solution f.
with
4. calculate distance ||f'-f||. If greater than tolerance, go back to 3.
5. Write a .txt file to record the solution f. end
This seems so obvious I expect I've completely missed the point.