Algorithm for (A+Bi) n

Asked

Viewed 279 times

3

I need to make a program that given the formula : A + B*i n You have to find the lowest value of n for it to be a real number

Being A and B inputs and i is part of the complex numbers.

I have a sketch :

#include <stdio.h>
#include <math.h>

int main(){
  int a,b,c,n;
  int I  = sqrt(-1);
  scanf("%d",&a);
  scanf("%d",&b);

  for(n=1;n<=30;n++){
    c = pow(a + (b * **I**),n);
    if (c==**Número Real**) 
      printf("Valor de N é: %d",n);         
      break;   
    }
    return 0;   
  }
}

Where is "Real Number" I do not know how to represent it codifically and the Square Root of -1 would have to be i but gives an absurd number. And I need this to make the equation.

  • There is the macro complex in C and the bundle std::complex in C++, which allow this representation in terms of the real and imaginary part. Have you tried using? And by the way, according to the definition, its resulting number will be real if the imaginary part is zero.

  • I tried to use but could not separate the terms ( Real and imaginary part ) . Exact will be real if the imaginary part is zero. But I can’t encode that . Since I need to figure out what value of n for the imaginary to zero.

  • Well, then, that’s why your question has already received votes to close. It is unclear whether your doubt is about mathematics (outside the scope of the site) or programming (within the scope of the site). If you’ve tried to use (it doesn’t look like the code you posted), why couldn’t you separate the terms? Where are you going wrong? That is, what is the specific doubt? Edit the question to try to improve it in this sense.

  • 1

    An example of using the macro in C: http://en.cppreference.com/w/language/arithmetic_types#Complex_floating_types

  • is (a + b * i) n? or only i?

  • Probably misunderstood the question... #include <stdio.h> main(){printf("0\n");} (OK I’m not helping at all...)

Show 1 more comment

2 answers

8

In fact its doubt becomes more a mathematical concept than a programming concept. To work with complex powers use the trigonometric form or the Euler form. There is no need to worry about the value of "i", since there is, in mathematics itself, notation that does not use it, as (real, imaginary), notation that treats the number as an ordered pair of the complex plane. The "i" is a representation that separates the real part from the complex, does not need to be worked.

Code: (response to (a + b * i) n) Comments on the code explain it (assuming n real):

#include <stdio.h> 
#include <math.h> 

#define PI 3.1415926535

/* Estrutura para forma complexa cartesiana */
typedef struct complexCart {

    double real;
    double imaginario;

} ComplexCart; 

/* Estrutura para forma complexa trigonométrica */
typedef struct complexTrig {

    double raio;
    double angulo;

} ComplexTrig;

/* Converte complexo cartesiano para trigonométrico */
ComplexTrig converterTrig(ComplexCart);

/* Converte complexo trigonométrico para cartesiano*/
ComplexCart converterCart(ComplexTrig);

int main(void)
{
    /* Variável que irá armazenar a menor potência 
       necessária. */
    double menorPot;

    /* Variável "cart" irá guardar número na forma
       cartesiana: a + bi, já "trig" na forma trigono-
       métrica: r(cos(Angulo) + i sen(Angulo)). 
       Vale notar que basta trabalhar com os parâmetros 
       em cada um desses casos, por exemplo, para trabalhar
       com dados cartesianos basta (a, b) e trigonométrico sim-
       plesmente (r, Angulo) */
    ComplexCart cart;
    ComplexTrig trig;

    printf("\nDigite um número imaginário da forma a + bi: ");
    /* Espera receber o número da forma cartesiana. 
       Ex: -2 + 3i, ou 2 + -3i (imaginária negativa) */
    scanf("%lf + %lfi", &cart.real, &cart.imaginario);

    /* Converte para forma trigonométrica, essa é mais fácil de lidar 
       com potências, raízes, divisões e multiplicações. Também poderia 
       ser utilizada a forma de Euler */
    trig = converterTrig(cart);

    /* Mostra a forma trigonométrica com o ângulo em radianos: Somente quando
       for exibir o resultado se preocupe com a forma de escrita complexa! */
    printf("O número em forma trigonométrica (em radianos): z = %.2f(cos(%.2f)   + i sen(%.2f))\n", 
         trig.raio, trig.angulo, trig.angulo);  

    /* Com o ângulo calcula-se a menor potência necessária 
       para que a parte do seno zere, ou seja, quando o ângulo é */
    menorPot = PI / (trig.angulo) ;

    /* Mostra a potência e o ângulo final quando a forma trigonométrica
       possui tal ângulo. */
    printf("A menor potência para tornar o número somente real é: %.2f\n", menorPot);
    printf("Ângulo da forma trigonométrica: %.2f rad\n", (trig.angulo) * menorPot); 

    /* Reatribui à forma trigonométrica o valor com a potência, ou seja,
       a forma já será com o valor elevado à potência */
    trig.raio = pow((trig.raio), menorPot);
    trig.angulo = (trig.angulo) * menorPot;

    /* Converte a forma trigonométrica da potência à forma cartesiana */
    cart = converterCart(trig);

    /* Mostra o resultado trigonométrico, o seno do ângulo dev ser zero. 
       Verifique!*/
    printf("Forma trigonométrica z^(%.2f) = %.2f(cos(%.2f) + i sen(%.2f))\n",
        menorPot, trig.raio, trig.angulo, trig.angulo); 

    /* Aqui, na fomra cartesiana, por garantia mostra-se a parte imaginária, 
       que deverá sempre ser zero. */  
    printf("Forma cartesiana z^(%.2f) = %.2f + %.2f i\n\n", menorPot, cart.real,
        cart.imaginario);  

    return 0;
}

/* Implementações dos Protótipos. */
ComplexTrig converterTrig(ComplexCart dadoCart){

    ComplexTrig dadoTrig;

    dadoTrig.raio = sqrt( (dadoCart.real) * (dadoCart.real) +
        (dadoCart.imaginario) * (dadoCart.imaginario) );

    if(dadoCart.real != 0)  
        dadoTrig.angulo = atan( (dadoCart.imaginario) / (dadoCart.real));

    else 
        dadoTrig.angulo = PI / 2;

    return dadoTrig;
}

ComplexCart converterCart(ComplexTrig dadoTrig){

    ComplexCart dadoCart;

    dadoCart.real = (dadoTrig.raio) * cos(dadoTrig . angulo);
    dadoCart.imaginario = (dadoTrig.raio) * sin(dadoTrig.angulo);

    return dadoCart;
}

In the above example I used structures to better idealize (and demonstrate union) the complex pair. (It could have been done with 4 independent doubles, but with structure it is easier to visualize). The rest is mathematics. Remember that whenever working with complex numbers is not necessary (most of the time) dealing with the VALUE of i, just work as a usual ordered pair, but subject to certain algebra (I will not comment as it comes out of the scope of the site).

  • Really very good answer. Congratulations! :)

  • Fixed case 0 + 0i, which previously gave error.

3

Rafael’s answer solves the problem in the smartest way (by converting the complex to a trigonometric representation), but I think it would be interesting to show that it is not difficult to solve the problem in a way similar to what you already have.

All you need to do is implement multiplication yourself instead of trying to want for complex numbers in C and use the operator * native.

If you have two numbers X = a + b*i and Y = c + d*i the product X*Y will be

X*Y =
(a + b*i)(c + d*i)        =  (por distributividade)
ac + ad*i + bc*i + ad*i^2 = (por i^2 = -1)
(ac - bd) + (ad + bc)*i

We can represent this in C using a pair of integers (a,b) to represent the complex number a + b*i.

typedef struct {
    int r; /* parte real */
    int i; /*parte imaginaria */
} Complex;

And we can implement the operations on the complex type that we have just created as simple functions instead of operators.

Complex addComplex(Complex x, Complex y){
    Complex z;
    z.r = x.r + y.r;
    z.i = x.i + y.i
    return z;
}

Complex multComplex(Complex x, Complex y){
     Complex z;
     z.r = x.r*y.r - x.i*y.i;
     z.i = x.r+y.i + x.i+y.r;
     return z;
}

After that, it’s easy to implement a working version of the code you already have:

int main(){

    Complex x;
    scanf("%d",&x.r);
    scanf("%d",&x.i);

    Complex x_n = {1, 0};
    for(int n=1;n<=30;n++){
        x_n = multComplex(x_n, x);
        if (x_n.i == 0){
            printf("Valor de N é: %d",n);         
            break;
        }
    }
    return 0;
}

One advantage of writing code this way is that all accounts are done in integers rather than doubles, which avoids rounding problems. However, the fields of x_n will overflow after a few iterations due to the exponential growth of the "radius" of x_n. A more robust version of this code should represent complex numbers with a data type for "infinitely accurate integers" rather than using int.

  • 1

    But complex numbers can be broken: a + Ib , "a" and "b" belong to the real ones, because the set of the real ones must be contained in the complex ones.

  • His input is always integer so he only needs to deal with the real numbers with integer parts (Gauss integers).

  • 2

    But this will never give the result, this "n" has to be float or double, even if "a" and "b" are integers. Not always the exponent will be integer. If you test it will be rare for some result to hit, and if hit will be truncated. For example: 2 + 3i, the exponent will be 3.2, even with "a" and "b" being integers. Also tested in your code 2 and 3, for example, and showed nothing (did not reach the if), perhaps due to this problem.

  • Given the case of the initial question I assumed "smallest n integer" instead of "smallest n". These are two different interpretations of the question

  • Although it is a possible interpretation and your interesting solution, it gives me the idea that n whole very rarely will have solution.

  • 1

    Well, if that were the case, it may be impossible to find an integer n data for "a" and "b" provided by the user (such as @Jjoao) spoke. Nothing guarantees that it is whole, even with greater powers, even varying to infinity, that is, it can be left without solution. Moreover the very definition of complex number uses the term "real" precisely by falling into the set of reals when the imaginary part is zero.

  • It will have a solution when the Phi angle is pi*fractional; otherwise it has no solution (by definition imaginary). We will have to choose a and b carefully. I still like the solution (+1)

  • The problem is the user choose a and b, it will practically be a lottery game. It would be interesting a program in which the user type a (or b) and then yes to calculate b and n integers.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.