Using sqrt() with arrays of vectors to determine magnitude

I need assistance. I am in intro to C++ and I'm writing a program that uses arrays to do vector math. My first function is a magnitude function.

mag: var = (<a*a, b*b, c*c>)^1/2

I'm not sure I know how to use the sqrt() fnct, or if my code will produce the correct result, because I cannot get it to compile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  void magnitude(double vec_1[], double vec_2[], double vec_result[])
{
  if(twoVecs == true)
  {
    double sqrt (double &vec_1, double &vec_2); //skipped until I can get one vec_result to work
  }
  else
  {
    double sqrt (double &vec_result);
    vec_1[0] *= vec_1[0] = vec_result[0];
    vec_1[1] *= vec_1[1] = vec_result[1];
    vec_1[2] *= vec_1[2] = vec_result[2];
    sqrt(vec_result) = magnitude_Vector1;
    cout<<"The magnitude of Vector 1 is: "<<magnitude_Vector1;
  }
}
Last edited on
when you do a = b; you are assigning the value of b into a.
Think of it like: a ← b; // (not actual syntax)

sqrt(vec_result) is not a named variable, it's the result of a function, so you can't assign something to it.

Let's start from scratch: You have some 3D vector, which you represent as an array of doubles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Example program
#include <iostream>
#include <cmath> // std::sqrt
using namespace std;

double magnitude(double vec[])
{
    double magn_squared =
        vec[0] * vec[0] +
        vec[1] * vec[1] +
        vec[2] * vec[2];
        
    return sqrt(magn_squared);
}

int main()
{
    double vec[] = {3, 2, 1};
    
    // sqrt(3*3 + 2*2 + 1*1) = sqrt(14) ~= 3.74
    cout << magnitude(vec) << '\n';
}

3.74166
Last edited on
I've been working on it while waiting for a response. I have broken it down very simply but, the code is long relative to what you have done. I got mine working, which helped me to understand the basic operation. What you have given as an example seems so simple once I understand the logic. Thank you!

I will continue with my program and implement what you have taught me. I will post an update later this evening or tomorrow.
I've been working on the program and I believe I have the logic correct however, I cannot get it to compile. Still! I keep getting the message:

main.cpp:144:7: error: no matching function for call to
'magnitude'
magnitude((vec_1)[3]);

I have to be missing something.

UPDATE: I just added the &(by reference) to all of the fnct references and it compiled! Next update after I run the program and test the logic.

SECOND UPDATE: There is a problem with the logic. Below is the output. The magnitude should be 3.4641

You have entered:

Vector 1: <2, 2, 2>



VECTOR OPTIONS

1. Enter vector(s)
2. Sum
3. Magnitude
4. Dot Product
5. Cross Product
6. Quit

Please enter your selection (1-6): 3

Case 3 Success!

The magnitude of Vector 1 is: 0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//sample program
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

//Determine the magnitude of the Vector(s)                                      //magnitude fnct
double magnitude(double (&vec_1)[3])
{
  bool twoVecs;
  if(twoVecs == true)
  {
    cout<<"\n\ntwoVecs Success!!"<<endl;
  }
  else
  {
    double magn_sqrd = vec_1[0] * vec_1[0] + vec_1[1] * vec_1[1] + vec_1[2] * vec_1[2];

    cout<<"The magnitude of Vector 1 is: "<<sqrt(magn_sqrd);

    return sqrt(magn_sqrd);
  }
}

//Switch fnct                                     //Switch worked great before I added this fnct
void switchCase(bool &Quit, char &menu_choice, bool &choice1)
{
  bool twoVecs = false;

  switch(menu_choice)
  {
  //Option 1:
    case '1':
      bool vecsEntered;
      enterVectors(vecsEntered);
      choice1 = true;
    break;
  
  //Option 2: 
    case '2':
      if(twoVecs == true)
      {
        cout<<"\n\t\t\t\tCase 2 Success!\n"<<endl;
        //void sumVectors(int vec_1[], int vec_2[], int vec_result[]);
      }
      else
      {
        cout<<"\n\n\t\t\t\t\tERROR!";
        cout<<"\n(You must enter 2 Vectors to use this menu option.)";  
        cout<<"\n\t\t\t\t  Try Again."<<endl;
      } 
    break;

  //Option 3:
    case '3':
    double vec_1[3];
      cout<<"\n\t\t\t\tCase 3 Success!\n"<<endl;
      magnitude((&vec_1)[3]);
    break;
 
  //Option 4:
    case '4':
      if(twoVecs == true)
      {
        cout<<"\n\t\t\t\tCase 4 Success!\n"<<endl;
        //void dotProduct(int vec_1[], int vec_2[], int vec_result[]);
      }
      else
      {
        cout<<"\n\n\t\t\t\t\tERROR!";
        cout<<"\n(You must enter 2 Vectors to use this menu option.)";  
        cout<<"\n\t\t\t\t  Try Again."<<endl;
      }

    break;
  
  //Option 5:
    case '5':
      if(twoVecs == true)
      {
        cout<<"\n\t\t\t\tCase 5 Success!\n"<<endl;
        //void crossProduct(int vec_1[], int vec_2[], int vec_result[]);
      }
      else
      {
        cout<<"\n\n\t\t\t\t\tERROR!";
        cout<<"\n(You must enter 2 Vectors to use this menu option.)";  
        cout<<"\n\t\t\t\t  Try Again."<<endl;
      }
    break;
  
  //Option 6:
    case '6':
      cout<<"\n\n\t\t\t\t\tExiting!"<<endl;
      signOff();
      Quit = true;
    break;

  //Default message for invalid input in the switch case
    default:
      cout<<"\t\t\tInvalid input. Try again."<<endl<<endl;
  }//End of switchCase
}

//Description:
//Pre-condition:
//Post-condition:
double magnitude(double (&vec_1)[3]);                                          //fnct prototype


Last edited on
@OP Whoever is teaching you about vectors appears not to be doing it very well.

The magnitude of 2 vectors is almost meaningless without clarification.

Is it the 2 separate magnitudes represented by 2 separate position vectors? In which case a simple function of a single vector parameter without all the bool stuff is all that's required.

Or is it the magnitude (length) of the line between the 2 separate position vectors? In which case you use a 2 vector parameter polymorphic function, and still not needing any bool stuff.

As a suggestion dump most of the \n \t rubbish, that's the least/last of the problem.

Maybe you could also copy the assignment question here too. Up to you ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cmath>

double magnitude(double* vec)
{
    double mag_sqd{0};
    
    for(int i = 0; i < 3; ++i)
        mag_sqd += vec[i]*vec[i];
    
    return sqrt(mag_sqd);
}

double magnitude(double* vec_A, double* vec_B )
{
    double mag_sqd{0};
        
    for(int i = 0; i < 3; ++i)
    {
        double difference = vec_B[i] - vec_A[i];
        mag_sqd += difference * difference;
    }
    
    return sqrt(mag_sqd);
}

double* sum(double* vec_A, double* vec_B)
{
    double* answer = new double[3];
    for(int i = 0; i < 3; ++i)
        answer[i] = vec_A[i] + vec_B[i];
    
    return answer;
}

int main()
{
    double v1[3]{3,4,5};
    double v2[3]{9,12,1};
    
    std::cout << "Magnitude of v1 = " << magnitude(v1) << '\n';
    std::cout << "Magnitude of v2 = " << magnitude(v2) << '\n';
    std::cout << "Magnitude of v1 & v2 = " << magnitude(v1, v2) << '\n';
    
    double* result = nullptr;
    result = sum(v1, v2);
    
    std::cout << "Vector sum of v1 and v2: ";
    for(int i = 0; i < 3; ++i)
        std::cout << result[i] << ' ';
    
    std::cout << '\n';
    
    delete[] result;
}
Last edited on
For this assignment you will submit (in the usual way) multiple files. These files will contain a C++ program that you have named appropriately,
each file with an appropriate name and appropriate extension. Be sure that your program compiles using the g++ compiler (like repl.it uses)
before you submit it in Canvas. To compile a program with multiple files, use the usual g++ command but instead of the single file you compiled before,
compile *.cpp and the compiler will "grab" all the cpp files in that directory. So, you see, it's important that you put all the files for a particular
program in their own directory! You don't have to list the header files; that will happen automatically.

Background: As you all know, Lisa Simpson is the brains of the "operation" there in Springfield on Evergreen Terrace. She is a very precocious child:
being only ~10 yrs old and in ~3rd grade, yet more intelligent than all the other characters in the show combined.

1 So, now Lisa is studying vectors in her math class and she is asking Marge to help her with her math homework. Since Marge is pretty much at the same
intellectual level as her nimrod husband, she is needing your help - to write a program that will read in vector values from the user and then compute several
vector calculations.

So now you're thinking, "Oh no, Lisa is smarter than I am! I don't know the first thing about vectors!" Well, don't despair, here's a short tutorial on how
vectors work. A vector is quite simply an ordered set of real numbers. In our case, an ordered triple. They are often represented like this:
v = <a,b,c>, where a, b, and c are real numbers. The values a, b, and c are called the elements of v. The sum of two vectors, v + u, is another vector whose
elements are the sums of the corresponding elements of v and u. Letting v = <a,b,c> and u = <d,e,f>, v + u = <a+d,b+e,c+f>. The "dot product" of two vectors,
v and u, is a single real number that is the sum of the products of the corresponding elements. We'll use * for our "dot". Thus, v*u = <a,b,c> * <d,e,f>
= ad+be+cf. The magnitude of a (single) vector is the square root of the sum of the squares of its elements. We use |v| to signify magnitude. So, |v| =
[a2+b2+c2]1/2. The cross product of a vector with another vector is a resultant vector.

v X u = <a,b,c> X <d,e,f> = <bf-ec, dc-af, ae-db>.

Specifications: Your program is to be menu driven. It should look something like:

Vector Options
1. Enter vector(s)
2. Sum
3. Magnitude
4. Dot Product
5. Cross Product
6. Quit

When option 1 is chosen, the program should ask the user if they want to enter one or two vectors and then proceed accordingly. With each other option,
the so named value should be presented (output to the user) and the menu returned until 'quit' is chosen. Be sure to make your output pretty. Output a
vector in the < x, y, z > format.

You need to pay attention to how your menu works. So suppose a user (Marge, presumably) enters just one vector. If she chooses options 2, 4, or 5, then
she should be presented with an error message stating that she only has one vector entered, and then the menu should be presented again. Think boolean
flags to implement this functionality.

When coding this program, use an array to store your vector data. If you know what it is, do not use the STL Vector class. (If you don't know what it is,
also don't use it.) Just say no! You will need to be able to calculate a square root. You can use the sqrt() function supplied by the compiler for this
program. It is in the library called cmath. Thus, you will need to put #include <cmath> at the beginning of your program (with your other includes). Then
you need to know that sqrt() takes a double and returns a double. (Remember, if you pass an int or float to a function that takes a double, it will
automatically promote it to a double.)

You are required to use functions to code up this program (what did you think was going into those other two files?!). It is up to you how to break up your
code to accomplish the above tasks. I think the choices should be fairly simple to make. But remember, each function should have a dedicated purpose. I can
see functions named the same as options 1 through 5 above. But there should be more. One function clearly should be a print_vector function. I highly
recommend that you first define a vector array and define a print_vector function, declare a vector and give it values, then print it so you can see that you
are actually creating what you think you are. Then start coding up your functions. And remember to comment your functions (and code in general).

Check: You may want to check your behavior with a sequence like the following

choose option 3 (should generate an error from your program)
choose option 1 and enter a single vector like <1,2,3>
choose option 2 (should also generate an error message)
choose option 3
choose option 1 and enter two vectors like < 1,2,3 > and < 4,5,6 >
choose option 4
choose option 5
quit
As usual, be sure to ask if have questions. (Best to ask me, not your program - it better not talk back!)

1Lisa has been exactly the same for about 23 years. So one could argue against the "precocious" label. But, oh well.....
OK, so there we go. The vectors ( BTW NOT STL <vector>'s) are position vectors. But the important thing is you've been given the formula in each case and you use C-style arrays.

v<5.1,10.78,3.9> means in your C++ v[0] = 5.1, v[1] = 10.78 and v[2] = 3.9

The magnitude function takes one parameter which would be a pointer to the array describing the vector being passed.

The sum function takes 2 vector pointers ...

So, keeping a lot of what you have done, just re-arrange it so the sum returns a pointer to the result, ie a new vector, after you pass the 2 vectors to be added as parameters. See what I did above.

Now, in the switch statement only 'activate' the sum function when the 2-vecs flag is true. Otherwise display an error message 'not enough vectors' and return to the menu.

Same for cross product.

Tip: avoid displaying (cout) info in the functions. Do that in main. That way your functions don't rely on the console, or a window or whatever display method. "just give me the answer" and handle it elsewhere ...

There's a similar menu and bool sorter including a few variations on approach here:

http://www.cplusplus.com/forum/beginner/271554/#msg1170697



Last edited on
Topic archived. No new replies allowed.