Saving a complex number in a variable - c++

I am trying to perform this computation which results in a complex number. However, C++ gives me "NaN".
double Q, r, Theta;
Q=-0.043543950754930;
r=0.009124131609174;
Theta=acos(r/sqrt(pow(-Q,3)));
// result must be (0.00000000000000 + 0.0911033580003565i)

Yes, by using the std::complex type:
#include <complex>
#include <iostream>
int main()
{
std::complex<double> Q = -0.043543950754930;
std::complex<double> r = 0.009124131609174;
std::complex<double> Theta = std::acos(r / std::sqrt(std::pow(-Q, 3)));
std::cout << Theta << '\n';
}
Note that the complex functions return values in specific ranges. You may have to adjust for this if you are looking for a specific answer.

I am trying to perform this computation which results in a complex number.
All the variables in the posted snippet are of type double, so that the compiler has to use the overloads of std::acos, std::sqrt and std::pow accepting parameters of type double and returning double values.
In particular, the function double std::acos(double arg)[1]:
If a domain error occurs, an implementation-defined value is returned (NaN where supported).
[...]
Domain error occurs if arg is outside the range [-1.0, 1.0].
Given the values of R and Q in the posted example, the value of arg is greater than 1, causing a domain error.
To obtain a complex value, the OP should use (or cast to) variables of type std::complex<double>, so that the "correct" overloads of the mathematical functions are chosen, as well as the expected return type.
They could also implement different numerical algorithms (one for real, one for complex values) and let the program choose the right path based upon the value of some "discriminant" variable. E.g. a cubic equation has three complex solutions in general, but those can either be three different real values or three real values (two coincident) or one real value and two complex conjugate ones. A program might use different methods instead of a single general (all complex) one.
[1] Quotes from https://en.cppreference.com/w/cpp/numeric/math/acos, emphasis mine.

Related

Calculating positive non-integer power of negative base

To my knowledge
(-1)^1.8 = [(-1)^18]^0.1 = [1]^0.1 = 1
Hope I am not making a silly mistake.
std::pow(-1, 1.8) results in nan. Also, due to this link:
If base is finite and negative and exp is finite and non-integer, a domain error occurs and a range error may occur.
Is there a workaround to calculate the above operation with C++?
std::pow from <cmath> is for real numbers. The exponentiation (power) function of real numbers is not defined for negative bases.
Wikipedia says:
Real exponents with negative bases
Neither the logarithm method nor the rational exponent method can be used to define br as a real number for a negative real number b and an arbitrary real number r. Indeed, er is positive for every real number r, so ln(b) is not defined as a real number for b ≤ 0.
The rational exponent method cannot be used for negative values of b
because it relies on continuity. The function f(r) = br has a unique
continuous extension from the rational numbers to the real numbers
for each b > 0. But when b < 0, the function f is not even continuous
on the set of rational numbers r for which it is defined.
For example, consider b = −1. The nth root of −1 is −1 for every odd
natural number n. So if n is an odd positive integer, (−1)(m/n) = −1
if m is odd, and (−1)(m/n) = 1 if m is even. Thus the set of rational
numbers q for which (−1)q = 1 is dense in the rational numbers, as is
the set of q for which (−1)q = −1. This means that the function (−1)q
is not continuous at any rational number q where it is defined.
On the other hand, arbitrary complex powers of negative numbers b can
be defined by choosing a complex logarithm of b.
Powers of complex numbers
Complex powers of positive reals are defined via ex as in section
Complex exponents with positive real bases above [omitted from this quote]. These are continuous
functions.
Trying to extend these functions to the general case of noninteger
powers of complex numbers that are not positive reals leads to
difficulties. Either we define discontinuous functions or multivalued
functions. Neither of these options is entirely satisfactory.
The rational power of a complex number must be the solution to an
algebraic equation. Therefore, it always has a finite number of
possible values. For example, w = z1/2 must be a solution to the
equation w2 = z. But if w is a solution, then so is −w, because (−1)2
= 1. A unique but somewhat arbitrary solution called the principal value can be chosen using a general rule which also applies for
nonrational powers.
Complex powers and logarithms are more naturally handled as single
valued functions on a Riemann surface. Single valued versions are
defined by choosing a sheet. The value has a discontinuity along a
branch cut. Choosing one out of many solutions as the principal value
leaves us with functions that are not continuous, and the usual rules
for manipulating powers can lead us astray.
So, before calculating the result, you must first choose what you are calculating. The C++ standard library has in <complex> a function template std::complex<T> pow(const complex<T>& x, const T& y), which is specified to calculate (through definition of cpow in C standard):
The cpow functions compute the complex power function xy, with a branch cut for the first parameter along the negative real axis.
For (-1)1.8, the result would be e-(iπ)/5 ≈ 0.809017 + 0.587785i.
This is not what you expected as result. There is no exponentiation function in the C++ standard library that would calculate the result that you want.

Function of a letter in C++

I have the following expression:
A = cos(5x),
where x is a letter indicating a generic parameter.
In my program I have to work on A, and after some calculations I must have a result that must still be a function of x , explicitly.
In order to do that, what kind of variable should A (and I guess all the other variables that I use for my calculations) be?
Many thanks to whom will answer
I'm guessing you need precision. In which case, double is probably what you want.
You can also use float if you need to operate on a lot of floating-point numbers (think in the order of thousands or more) and analysis of the algorithm has shown that the reduced range and accuracy don't pose a problem.
If you need more range or accuracy than double, long double can also be used.
To define function A(x) = cos(5 * x)
You may do:
Regular function:
double A(double x) { return std::cos(5 * x); }
Lambda:
auto A = [](double x) { return std::cos(5 * x); };
And then just call it as any callable object.
A(4.); // cos(20.)
It sounds like you're trying to do a symbolic calculation, ie
A = magic(cos(5 x))
B = acos(A)
print B
> 5 x
If so, there isn't a simple datatype that will do this for you, unless you're programming in Mathematica.
The most general answer is "A will be an Expression in some AST representation for which you have a general algebraic solver."
However, if you really want to end up with a C++ function you can call (instead of a symbolic representation you can print as well as evaluating), you can just use function composition. In that case, A would be a
std::function<double (double )>
or something similar.

Is this reinterpret_cast OK to do

I am a EE, not a code expert, so please bear with me here.
I am using Embarcadero C++ Builder (XE3).
I have an FFT algorithm which does a fair number of operations on complex numbers. I found out that if I bypass Embarcadero's complex math library, and do all the calculations in my own code, my FFT will run about 4.5 times faster. The 4 operations shown here all require an inordinate amount of time.
#include <dinkumware\complex>
#define ComplexD std::complex<double>
ComplexD X, Y, Z, FFTInput[1024];
double x, y;
Z = X * Y;
x = X.real();
y = X.imag();
Z = ComplexD(x,y);
Replacing the multiplication with my own cross multiply cut my execution times in half. My concern however is with the way I am accessing the real and imaginary parts of the input array. I am doing this:
double *Input;
Input = reinterpret_cast<double *>(FFTInput);
// Then these statements are equivalent.
x = FFTInput[n].real();
y = FFTInput[n].imag();
x = Input[2*n];
y = Input[2*n+1];
Doing this cut my execution times in half again, but I don't know if this reinterpret_cast is a wise thing to do. I could change the input array to two doubles instead of a complex, but I am using this FFT in numerous programs and don't want to rewrite everything.
Is this reinterpret_cast OK, or will I have memory problems? Also, is there a way to get the Embarcadero complex math functions to run faster? And finally, although its not terribly important to me, is this reinterpret_cast portable?
This is allowed. Whilst this isn't a standard quote, cppreference has this to say:
For any pointer to an element of an array of complex numbers p and any
valid array index i, reinterpret_cast<T*>(p)[2*i] is the real part of
the complex number p[i], and reinterpret_cast<T*>(p)[2*i + 1] is the
imaginary part of the complex number p[i].
I will look for the quote from the actual standard soon.
From here it says at the bottom of the page:
For any complex number z, reinterpret_cast<T(&)[2]>(z)[0] is the real part of z and reinterpret_cast<T(&)[2]>(z)[1] is the imaginary part of z.
For any pointer to an element of an array of complex numbers p and any valid array index i, reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i], and reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[i]. (Since C++11)
These requirements essentially limit implementation of each of the three specializations of std::complex to declaring two and only two non-static data members, of type value_type, with the same member access, which hold the real and the imaginary components, respectively.
So what you are doing is guaranteed to work in C++11, but not before that. It may still work with your library's implementation, but you need to check that your library's implementation does not define any more non-static data members as per the third paragraph.

Dividing each element in a container between a given number C++

I was multiplying each container against another number so I did the following:
local_it begin = magnitudesBegin;
std::advance(begin , 2);
local_it end = magnitudesBegin;
std::advance(end, 14);
std::transform(begin, end, firstHalf.begin(),
std::bind1st(std::multiplies<double>(),100));
It worked wonders, problem is when doing the same to divide between another container. Here is a working example of my problem:
const std::size_t stabilitySize = 13;
boost::array<double,stabilitySize> secondHalf;
double fundamental = 707;
boost::array<double, stabilitySize> indexes = {{3,4,5,6,7,8,9,10,11,12,13,14,15}};
std::transform(indexes.begin(), indexes.end(), secondHalf.begin(),
std::bind1st(std::divides<double>(),fundamental));
It does divide the container. But instead of dividing each element in the array against 707 it divides 707 between each element in the array.
std::bind1st(std::divides<double>(),fundamental)
The code above takes a functor std::divides<double> that takes two arguments and fixes the value of the first argument to be fundamental. That is it fixes the numerator of the operation and you get the expected result. If you want to bind fundamental to be the denominator, use std::bind2nd.
you can try the following , divide has a completely different operation than multiply, it just divides a constant number by all your elements
std::bind1st(std::multiplies<double>(),1.0/707.0));
If the number 707.0 is something like a fundamental constant, and a division can be seen as a "conversion", let's call it "x to y" (I don't know what your numbers are representing, so replace this by meaningful words). It would be nice to wrap this "x to y" conversion in a free-standing function for re-usability. Then, use this function on std::transform.
double x_to_y(double x) {
return x / 707.0;
}
...
std::transform(..., x_to_y);
If you had C++11 available, or want to use another lambda-library, another option is to write this in-line where being used. You might find this syntax more readable like parameter binding using bind2nd:
std::transform(..., _1 / 707.0); // when using boost::lambda

out put of the cross product

i am trying to get the 'cross product' of two vectors. these two vectors represent two planes. so, my vectors are as a1,b1,-1 and a2,b2,-1. (I used, my plane equation as ax+by-z+d=0).
this was my defined function to get the cross product;
vector<double> cross_vector(vector<double> plane1,vector<double> plane2){
vector<double> cross_product;
double a1=plane1.at(0); double a2=plane2.at(0);
double b1=plane1.at(1); double b2=plane2.at(1);
int c1,c2=-1;
double cross_a=(b1*c2)-(b2*c1);
double cross_b=(a2*c1)-(a1*c2);
double cross_c=(a1*b2)-(a2*b1);
cross_product.push_back(cross_a);
cross_product.push_back(cross_;
cross_product.push_back(cross_c);
return cross_product;
}
for the result i got as below result for different plane combinations;
523554 -1.3713e+006 -0.00160687
556340 -1.43908e+006 0.00027957
-568368 1.46225e+006 -0.00034963
143455 -380017 -0.00027957
i can't understand the values like 1.46225e+006? is there any wrong with my function?
i know, my resultant cross vector should be directed exactly horizontal. So, could you also tell me how can i check whether my cross-vector is horizontal or not?
hope your advices.
int c1,c2=-1;
This leaves c1 uninitialized. Use:
int c1=-1, c2=-1;
The math looks correct. Placing a quick A = <1,0,0> and B = <0, 1, 0> gave a reasonable result on the backside of <0, 0, 1>. The e notatin represent the number times 10 to the power after the e. So those might be reasonable as well, but it's hard to say as from your example I can't tell what your input values were. I wouldn't personnaly return the value directly though - I'd prefer to return as a reference or pointer to prevent needless copying. Also, as the above poster mentioned, you do have an initialized var.