2012-06-06 95 views
7

Estoy intentando escribir un programa con una función double_product(vector<double> a, vector<double> b) que calcule el producto escalar de dos vectores. El producto escalar esCalcular el producto escalar de dos vectores en C++

$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$. 

Esto es lo que tengo. Es un desastre, ¡pero lo estoy intentando!

#include <iostream> 
#include <vector> 

using namespace std; 

class Scalar_product 
{ 
    public: 
    Scalar_product(vector<double> a, vector<double> b); 
}; 
double scalar_product(vector<double> a, vector<double> b) 
{ 
    double product = 0; 
    for (int i = 0; i <= a.size()-1; i++) 
     for (int i = 0; i <= b.size()-1; i++) 
      product = product + (a[i])*(b[i]); 
    return product; 
} 

int main() { 
    cout << product << endl; 
    return 0; 
} 
+1

¿Hay alguna pregunta aquí? –

+0

¿Qué es "bouble"? – jakebird451

+0

Su pregunta no es muy clara. Lo conseguimos que es tu tarea. Pero, ¿qué pregunta está tratando de resolver y agregar un pequeño detalle sobre el problema que está enfrentando? – Ankit

Respuesta

10

Puede eliminar el class que ha definido. No lo necesitas.

En su función scalar_product:

double scalar_product(vector<double> a, vector<double> b) 
{ 
    double product = 0; 
    for (int i = 0; i <= a.size()-1; i++) 
     for (int i = 0; i <= b.size()-1; i++) 
      product = product + (a[i])*(b[i]); 
    return product; 
} 

Es casi allí. No necesitas 2 bucles Solo uno.

double scalar_product(vector<double> a, vector<double> b) 
{ 
    if(a.size() != b.size()) // error check 
    { 
     puts("Error a's size not equal to b's size") ; 
     return -1 ; // not defined 
    } 

    // compute 
    double product = 0; 
    for (int i = 0; i <= a.size()-1; i++) 
     product += (a[i])*(b[i]); // += means add to product 
    return product; 
} 

ahora a llamada esta función, es necesario crear 2 objetos vectoriales en su main(), llenarlos con los valores, (el mismo número de valores por supuesto!) Y luego llamar scalar_product(first_vector_that_you_create, second_vector_object);

+1

El manejo de errores en esta implementación es peligroso. -1 no representa indefinido en el producto escalar. Ese puede muy bien aparecer a veces. Se ha impreso una advertencia, pero esto puede descartarse fácilmente, especialmente para los programas grandes en los que el texto puede estar oculto, o si hay mucho texto impreso. Pruebe en su lugar * numeric_limits :: quiet_NaN(); * Cuál devuelve nan. – patrik

+1

Yo nunca, nunca, nunca, voluntariamente [presentaré NaN] (http://stackoverflow.com/a/18283170/111307) en mi programa. NaN es tóxico (NaN * número = NaN, NaN + número = NaN), por lo que se propaga a través de su programa, y ​​averiguar dónde se produjo el NaN es realmente difícil (a menos que el depurador se pueda romper inmediatamente en la producción de NaN). Dicho esto, un misterioso -1 podría no ser fácil de rastrear como un 0 misterioso, así que podría cambiar ese -1 a un 0. Si no monitoreas el resultado de texto de tu programa regularmente, probablemente también agregue un ASSERT en esa condición. Pero __never__ devuelve NaN. – bobobobo

+0

Rastreando un NaN que no fue el resultado de una operación de división, espero que sea doblemente difícil. – bobobobo

0

Usted parece querer hacer una clase específicamente para vectores. La clase que hice en mi ejemplo está hecha a medida para 3 vectores dimensionales, pero puede cambiarla a otra si así lo desea. La clase tiene i, j, k pero también puede conducir productos escalares basados ​​en otros MathVectors. El otro vector se pasa a través de una referencia de C++. Es difícil deducir cuál fue la pregunta, pero creo que esto podría responderla.

#include <iostream> 

using namespace std; 

class MathVector 
{ 
private: 
    double i,j,k; 
public: 
    MathVector(double i,double j,double k) 
    { 
     this->i=i; 
     this->j=j; 
     this->k=k; 
    } 
    double getI(){return i;} 
    double getJ(){return j;} 
    double getK(){return k;} 
    double scalar(MathVector &other) 
    { 
     return (i*other.getI())+(j*other.getJ())+(k*other.getK()); 
    } 
}; 

int main(int argc, char **argv) 
{ 
    MathVector a(1,2,5), b(2,4,1); 

    cout << a.scalar(b) << endl; 

    return 0; 
} 
1

Aquí está el código que debe tener. Veo que usaste clase en tu código, que realmente no necesitas aquí. Avíseme si la pregunta requirió que use la clase.

Como es nuevo y este código puede asustarlo. Entonces, intentaré explicar esto a medida que avance. Busque comentarios en el código para comprender lo que se está haciendo y pregúntele si no comprende.

//Scalar.cpp 
#include <stdlib.h> 
#include <iostream> 
#include <vector> 

using namespace std; 

/** 
This function returns the scalar product of two vectors "a" and "b" 
*/ 
double scalar_product(vector<double> a, vector<double> b) 
{ 
    //In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0. 
    double product = 0; 
    //Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product. 
    if(a.size()!=b.size()){ 
     cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl; 
     return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above. 
    } 

    //you loop through the vectors. As bobo also pointed you do not need two loops. 
    for (int i = 0; i < a.size(); i++) 
    { 
     product = product + a[i]*b[i]; 
    } 

    //finally you return the product 
    return product; 
} 


//This is your main function that will be executed before anything else. 
int main() { 
    //you declare two vectors "veca" and "vecb" of length 2 each 
    vector<double> veca(2); 
    vector<double> vecb(2); 

    //put some random values into the vectors 
    veca[0] = 1.5; 
    veca[1] = .7; 
    vecb[0] = 1.0; 
    vecb[1] = .7; 

    //This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple! 
    cout << scalar_product(veca,vecb) << endl; 
} 

Si está utilizando un IDE, simplemente compile y ejecute. Si está utilizando la línea de comandos en un sistema basado en Unix con el compilador g ++, esto es lo que va a hacer (donde Scalar.cpp es el código que contiene el archivo):

g++ Scalar.cpp -o scalar 

para ejecutarlo simplemente escriba

./scalar 

Debe obtener 1.99 como resultado del programa anterior.

+0

Gracias, agradezco su ayuda: D – HowardRoark

33

A menos que usted tiene que hacer esto por su cuenta (por ejemplo, la escritura es la tarea), que realmente debe utilizar el algoritmo estándar que ya está escrito para hacer exactamente lo que quiere:

#include <iostream> 
#include <numeric> 

int main() { 
    double a[] = {1, 2, 3}; 
    double b[] = {4, 5, 6}; 

    std::cout << "The scalar product is: " 
       << std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0); 
    return 0; 
} 

Tenga en cuenta que mientras que el begin(a), end(a) es nuevo en C++ 11, std::inner_product ha estado disponible desde C++ 98.

+8

+1 por enseñarme sobre 'inner_product'. –

3

Si bien se le ha presentado muchas soluciones que funcionan, me deja girar otra variación de introducir un par de conceptos que deben ayudarle a escribir mejor código:

  • class sólo son necesarios para empaquetar datos junto
  • una función debe comprobar sus condiciones previas, tan pronto como sea posible, debe ser documentado los
  • una función debe tener condiciones posteriores, esos deben ser documentados
  • la reutilización de código es la piedra angular de los programas de mantenible

Con esto en mente:

// Takes two vectors of the same size and computes their scalar product 
// Returns a positive value 
double scalar_product(std::vector<double> const& a, std::vector<double> const& b) 
{ 
    if (a.size() != b.size()) { throw std::runtime_error("different sizes"); } 

    return std::inner_product(a.begin(), a.end(), b.begin(), 0.0); 
} // scalar_product 

Se podría decidir utilizar el algoritmo inner_product directamente, pero seamos realistas:

  • que requiere cuatro argumentos, no dos
  • lo hace no verifique que sus argumentos sean del mismo tamaño

así que es mejor envolverlo.

Nota: utilicé const& para indicar al compilador que no copie los vectores.

+0

¡Gracias! Realmente lo aprecio. – HowardRoark

Cuestiones relacionadas