Conceptual error about functions in C++!

Asked

Viewed 105 times

0

good morning!

I am a programmer beginner in C++, and I am certainly making a conceptual mistake when creating functions, which I could not detect in any forum and material about C++. I have the following code:

#include <iostream>
#include <array>
#include <cmath>

const int k = 3;
const int J = 6;
const int Q = 3;
constexpr size_t mdimenK = k;

double chi(const std::array<std::array<double,J>,mdimenK> &mB, const std::array<std::array<int,Q>,2> &qc, const std::array<long double, J> &sp); 

int main()
{
    std::array<std::array<double, J>,mdimenK> B{{
    {0.622, 0.168, 0.064, 0.070, 0.070, 0.005},
    {0.252, 0.489, 0.148, 0.039, 0.011, 0.061},
    {0.131, 0.368, 0.356, 0.088, 0.014, 0.043}
  }};

  std::array<std::array<int, Q>,2> qc{{
    {0,0,1},
    {1,2,2}
  }};

  std::array<long double, J> sp{2.1414738, 0.3732512, 0.1804191, 1.9928826, 0.2322304, 1.0797428};

  double chiold, chiest;

  chiold = chi(B, qc, sp); 

  chiest = chi(B, qc, sp);

  std::cout << "O valor de chiold é: " << chiold << " e de chiest é: " << chiest << std::endl;

  return 0;
}

double chi(const std::array<std::array<double,J>,mdimenK> &mB, const std::array<std::array<int,Q>,2> &qc, const std::array<long double, J> &sp) 
{
  std::array<std::array<double,J>,Q> dchi;
  std::array<double,Q> sChi;
  double sqrtChi;

  for(int q=0;q<Q;q++){
    for(int j=0;j<J;j++){
      dchi[q][j] = (pow((mB[qc[0][q]][j] - mB[qc[1][q]][j]),2)/sp[j]);
    }
  }

  for(int q=0;q<Q;q++){
    sChi[q] = 0;
    for(int j=0;j<J;j++){
      sChi[q] += dchi[q][j];
    }
  }

  for(int q=0;q<Q;q++){
    sqrtChi += sqrt(sChi[q]);
  }
  return sqrtChi;
}

The values of chiold and chiest were to be the same. However, to my surprise and as I am beginner in this language, the values are different. Could someone explain to me what is the conceptual error? I have read about pointers, reference and etc, but I still could not detect the error. I’m an advanced programmer in the R language. Thanks in advance for any help.

  • 2

    Could explain what the code should be doing?

  • Use using std.

  • Congratulations because it is perceived that even beginner understands what is doing better than very beginner and some "experienced" (just think ugly this lot of blank line and lack of spaces where it leaves more readable), produced an almost true C++ code (only failed to use pow() of C when it could be of C++), but also I think we lack to give subsidies to help you. And maybe it’s not even a programming error.

  • The ideal is to explain your code so that it is easy for people to understand the values obtained and why the chiold and chiest should be the same. The explanation should be at the level of the algorithm used and represent the final values obtained.

  • Dear friends, good afternoon. I thank you for all your comments. This piece of code is part of a much more complex code, in which, the goal is to make a "simulated annealing", whose goal is to minimize/maximize a function chi according to the matrix B, that changes along a "loop". The function chi is responsible for computing the chi-square distance. The matrix B, changes along the "loop" according to the matrix Tn (that is not in the code).

  • Part 2: As the matrix Tn is an identity matrix in the first iteration, then the snitch and chiest should be the same. In the other "loops", obviously these variables will change. As I am beginner in this language, my "fear" is to be with some misconception, and so, all calculations of other functions are wrong. Therefore, I need to understand how C++ "thinks", so as not to make a serious mistake. I accept book suggestions among other materials. Thank you to everyone. I stay in the water.

  • This information should be included in the question and not as comments. Edit it and enter this information.

Show 2 more comments

1 answer

1

the problem is on that line:

double sqrtChi;

the correct would be :

double sqrtChi = 0;

if you do not instate object the second call your function will reuse the first added value.


A second option 'and change += for =+ pq o =+ will rewrite the first value with the second function operation, in case += will use the previous memory value but the next function value.

  • Hi Hudson. In fact it solves the problem. However, I am in the search for "why", given that the code is much more complex than exposed in this post. Thanks for the help.

  • But the object is within the function. So, I imagine that every time it’s called, the object inside it should be reset, not, If so, then should I instantiate to zero the correct dchi and schi objects? That’s my big question. Every object created within a function must be instantiated to zero, avoiding the risk of such an object being used further forward if the function is called again?

  • @Ivanbezerraallaman in case you used += but forward yes you need to instate the object with a value

  • I edited adding a second option with the operator =+, but the best would be to instantiate the object, so that the object in memory always starts with the defined value.

  • Thanks Hudson for the explanations. Big hug.

  • ps. there is no "operator =+"...if you write "a =+ b" the meaning is "a = (+b)", which is the same thing as "a = b"

  • to initialize with zeros the dchi and schi arrays in the declaration the syntax is "Std::array<...> dchi = {}"...see here in the Soen

Show 2 more comments

Browser other questions tagged

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