Fortran: Evaluation of a multiplication in parenthesis - fortran

In Fortran I have print *,(4,2)*(2,1) and the result is (6.,8.). How does this computation is evaluated?

Those are complex numbers, an intrinsic type in Fortran since the year . And you are looking at a complex multiplication.

Related

Fortran sqrt of complex number -1 gives different results

This code
print *, sqrt(cmplx(-1))
print *, sqrt(cmplx(-1,0))
print *, sqrt((-1,0))
print *, sqrt(-(1,0))
gives me this output
(0.00000000,1.00000000)
(0.00000000,1.00000000)
(0.00000000,1.00000000)
(0.00000000,-1.00000000)
I believe that the correct algebra is sqrt(-1)=i. Why the result of the last line?
The compiler version is GCC 7.3.0, running on Linux openSUSE 42.2 (x86_64).
EDIT
Following #francescalus answer I have tried more cases:
print *, sqrt((-1,-0))
print *, sqrt((-1,-0.))
print *, (-1,-0)
print *, (-1,-0.)
and I get
(0.00000000,1.00000000)
(0.00000000,-1.00000000)
(-1.00000000,0.00000000)
(-1.00000000,-0.00000000)
So, it seems that my compiler support negative zeros for real numbers. So, I guess it is important to care when working with variables like this:
complex :: asd
asd=(1.,0.)
print *, sqrt(-asd)
Here I get again the wrong result, but the zero negative thing is more difficult to predict. I have so many questions! Do you know some other exmple that can induce a mistake? Do you have an advice to avoid this mistakes? Do you now some compiler flag to turn off the negative cero support for the GCC compiler?
Fortran 2008 (13.7.159) defines the result of the sqrt function, for argument X, as (my emphasis):
The result has a value equal to a processor-dependent approximation to the square root of X. A result of type complex is the principal value with the real part greater than or equal to zero. When the real part of the result is zero, the imaginary part has the same sign as the imaginary part of X.
Your square roots do indeed have zero real part, so let's look at the sign of the imaginary part of your argument. What is the sign of the imaginary component of -(1,0)? If your processor supports signed zero, then it could well be negative. In which case, the imaginary part of the result should be negative according to the standard's requirement.
In all other cases, there'd be no reason to expect the imaginary component of the argument to be negative, rather than positive, zero.

Why isn't there a unary operator to get a multiplicative inverse? 0-x = -x ... 1/x =?

In C/C++ there is a unary minus operator, which returns the additive inverse of an arithmetic type (at least in most cases), i.e.
int x = 2, y = 2;
assert(x + (-x) == 0);
From a mathematical viewpoint it doesn't matter if one writes -x or 0-x, but from a programmer perspective it does. The sequence of instructions used to evaluate -x is in general different than the sequence of instructions used to evaluate 0-x! Having a unary minus operator in C++ does actually make sense despite being just syntactic sugar. So does a unary operator returning the multiplicative inverse, doesn't it? But why does C++ (like many (most?all?) languages) lack such an operator?
EDIT:
My main point is, that calculating an inverse of a number x (additive or multiplicative) does not require neutral elements (0 or 1 respectively) being processed by the computer. In fact 0 and 1 are non trivial entities for computers. While evaluating 0.0-x or 1.0/x is rather "simple" (precision is still a big problem here) for floating types (like float or double in C), it can become quite complex in general. Like for muti. precision floating point types 0.0-x is way more complex than -x and thus -x is not just handy but also generates more efficient code. On the other hand one has to introduce a function like inv(x) or x.inv() or whatever to achieve the same for multiplication (multiplicative inverse), instead of maybe just writing /x for 1.0/x ... Afaik the lack of such an operator is not only observable in C and C++ but in many other languages even in languages primarily designed for math which gets me puzzled ;)
Because there is no unary multiplicative inverse symbol in mathematics.
You either represent it as x^-1 or 1/x both of which can be down (albeit in a roundabout way for power) in C++ as well.
Unary negation only exists because it exists in mathematics.
Guvante's answer correctly points out that there's no common mathematical notation for the multiplicative inverse (though x-1 could loosely be thought of as a postfix operator).
In addition, C++ is derived from C, which is derived from B. The B language didn't even have floating-point arithmetic.
C itself is primarily a systems programming language, which a greater emphasis on integers than on floating-point arithmetic. A multiplicative inverse operation on integers is not particularly useful. (Well, it might be useful for modular arithmetic, but C unsigned types don't behave that way.)
The set of arithmetic operators hasn't changed much from B to C to C++. I think the addition of unary + was the biggest change.
Furthermore, there's really no great need for a multiplicative inverse operator even for floating-point. It's easy enough to write 1.0 / x -- and any decent compiler will generate the same code that as it would for a hypothetical inverse operator applied to x. (For some CPUs, that code would apply a division operator to the values 1.0 and x anyway.)

How to calculate numbers to arbitrarily high precision?

I wrote a simple fortran program to compute Gauss's constant :
program main
implicit none
integer :: i, nit
double precision :: u0, v0, ut, vt
nit=60
u0=1.d0
v0=sqrt(2.d0)
print *,1.d0/u0,1.d0/v0
do i=1,nit
ut=sqrt(u0*v0)
vt=(u0+v0)/2.d0
u0=ut
v0=vt
print *,1.d0/u0,1.d0/v0
enddo
end program main
Result is 0.83462684167407308 after 4 iterations. Anyway to have better results using the arithmetico-geometric mean method? How do people compute many digits for numbers such as pi, Euler's constant, and so on ? Does each irrational number has a specific algorithm?
If you goal is to insert a constant value into your program, the easiest solution is to look up the value on the web in or a book. Be sure to add a type specification to the numeric value, other Fortran will treat it as the default of single precision. One could write pi as pi_quad = 3.14159265358979323846264338327950288_real128 -- showing the use of a type specifier on a constant.
If you want to do high precision calculations, you could some high precision type available in your compiler. Many compilers now have quadruple precision. If they have the Fortran 2008 version of the ISO_FORTRAN_ENV module, you can request this via the type real128.
Arbitrary precision (user specified number of digits, to very high number of digits) is outside the language and is available in libraries, e.g., MPFUN90, http://crd-legacy.lbl.gov/~dhbailey/mpdist/
Yes, different constants have various algorithms. This is a very large topic.
Solution for pi:
pi = 4.0d0 * datan(1.0d0)

Rounding error in dgesv?

I'm using the dgesv and dgemm fortran subroutines in C++ to do some simple matrix multiplication and left division.
For random matrices A and B, I do:
A\(A\(A*B));
where * is defined using dgemm and \ using dgesv. Obviously, this expression should simplify to the identity matrix. I'm testing my answers against MATLAB and I'm getting more or less 1's on the diagonal but the other entries are very slightly off (the numbers are on the order of magnitude e-15, so they're close to 0 already).
I'm just wondering if this result is to be expected or not? Because if I do something like this:
C = A+B;
D = A*B;
D\(C\(C*C));
the result should come out to D\C. Basically, C(C*C) is very accurate (matches MATLAB perfectly), but the second I do D\C I get something that's off by e-1 or even e+00. I'm guessing that's not supposed to happen?
Your problem seems to be related to finite accuracy of floating point variables in C/C++. You can read more about it here. There are some techniques of minimizing that effect (some of them described in the wiki article) but there will always be some loss of accuracy after a few operations. You might want to use some third-party mathematical library that supports numbers of arbitrary precision (e.g. GMP). But still - as long as you stick to numerical approach accuracy of your calculations will always be tainted.

multiplication of string [ containing integer], output also stored in string, How? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Inputting large numbers in c++?
Arbitrary-precision arithmetic Explanation
I need to multiply two huge huge integers, like:
a=1212121212121212121212121212121212121212121212121212;
b=1212121212121212121212121212121212121212121212121212;
I think there are no data types in C and C++ to hold this huge an integer, so I thought to keep it as a string format like:-
char *number1="1212121212121212121212121212121212121212121212121212";
char *number2="1212121212121212121212121212121212121212121212121212";
during the time of multiplication I convert it into string with help of atoi() function like:
atoi(number1)*atoi(number2);
As usual the output of this multiplication will be obviously huge, so I need to change the output in string format.
I know there is an itoa() function which converts an integer to a string but it is not compatible with all compilers. Can any body tell me what I should do in this scenario?
I am using Ubuntu-10.04 and the g++ compiler.
Since C and C++ do not offer a native type that supports big numbers, it makes no sense to call atoi() to parse such numbers. atoi() returns a native int which is capped at 2,147,483,647 on 32-bit platforms.
You can use one of the numerous bignum libraries, like GMP for instance.
I think, the best variant besides using some math libraries is to split those numbers into int arrays with some fixed limit. Then just perform multiplication using basic math multiplication methods. And do not forget about overflows.
Multiplying the large numbers is very
difficult, however we can do it by
applying the logarithm of
multiplication of two numbers formula
and now we are going know how we
derived the product of two numbers’
logarithm.
Let us consider a, m and n are positive real numbers but a does not equal to 1 which means ‘a’ belongs to R+ – {1}. Logarithm of m and n to base a are x and y respectively by satisfying ax is equal to m and ay is equal to n condition.
loga (m.n) = x + y
As we already know x = loga m and y = loga n.
loga (m.n) = loga m + loga n
logarithm of multiplication of two values is equal to summation of the same values’ logarithms. The same logarithmic fundamental can now help us in multiplying the two large numbers by adding the logarithm of those values. If you don’t have a calculator, just take the logarithmic table help to perform this.
Using atoi() is also not helpful since the number itself won't fit in integer data type.
You have to simulate the method you did in elementary school.
121
*23
----
363
242*
----
2783
The implementation is left as an exercise. You would also need to know how to add big numbers.