0

I am new to c++ and I get this error “Invalid operands to binary expression (‘const Vector’ and ‘const Vector’)” and I have no idea where to look at in my own code.

The error appears at the line “{return __x < __y;}” in _functional_base:

    #if _LIBCPP_STD_VER > 11
template <class _Tp = void>
#else
template <class _Tp>
#endif
struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>
{
    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
    bool operator()(const _Tp& __x, const _Tp& __y) const
        {return __x < __y;}
};

But my real code looks like this:

//
//  MCP.cpp
//  Speciale
//
//  Created by Zaki G on 21/11/15.
//  Copyright © 2015 Zaki G. All rights reserved.
//

#include "mcp.h"
#include <cmath>
#include <string>
#include <iomanip>
#include "Vector.h"
#include "Particle.h"
#include "Detector.h"
#include "Cave.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <map>




MCP::MCP(char* name,Vector& dimension,Vector& QuartzDimension, int NumberSubQuartz, double ElectronicThickness, double Reflective_index, double z_axis_sign): Detector(name, dimension, 0)
    {
    MCP_Dimension = dimension;
    MCP_QuartDimension = QuartzDimension;
    MCP_NumberSubQuartz = NumberSubQuartz;
    MCP_ElectronicThickness = ElectronicThickness;
    MCP_Quartz_Reflective_index = Reflective_index;
    MCP_z_axis_sign = z_axis_sign;
    }

//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------


Vector MCP::Quartz_wall_Intersection(Detector& name, Vector &inter_front_quartz, Vector &path_photon, Vector &direction_vector, int reflection_on_off, Vector &Cherenkov_photon) //The direction vector is the vector against the normal vectors of the walls, and the Cherenkov_photon is only called to
                            //calculate the refelcted photon.

{             // Function for finding the intersection with the quartz walls and it can also calculated the reflected photon vector//

    Vector detector_posi = name.fPosition; // The position of the detector

    double Quartz_L_corner_x = detector_posi.GetX()-(0.053/2);
    double Quartz_L_corner_y = detector_posi.GetY()-(0.053/2);
    double Quartz_L_corner_z = detector_posi.GetZ();
    Vector loop_Quartz_Lcorner = (Quartz_L_corner_x, Quartz_L_corner_y, Quartz_L_corner_z); //The position of the Quartz down left corner.

    //Generating walls and roofs position for every sub MCP quartz.

    int number_of_walls =int(sqrt(MCP_NumberSubQuartz)); //4+1 walls in total remember "+1"

    int walls_position[number_of_walls+1];
    for (int i = 0; i<=number_of_walls; i++)
    {
        walls_position[i] = loop_Quartz_Lcorner.GetX()+i*(0.053/sqrt(MCP_NumberSubQuartz)); // 0.053 is the length and width of the MCP Quartz
    }

    int number_of_roof =int(sqrt(MCP_NumberSubQuartz));
    int roofs_position[number_of_roof+1];
    for (int i = 0; i<=number_of_roof; i++)
    {
        roofs_position[i] = loop_Quartz_Lcorner.GetY()+i*(0.053/sqrt(MCP_NumberSubQuartz));
    }

    //loop for which section (Divided quartz) is the generated particle close to.
    int en = 0;
    int to = 0;
    double x_array[2];
    double y_array[2];
    for (int i = 0; i<=number_of_walls; i++)
    {
        if ( abs(inter_front_quartz.GetX()) - abs(walls_position[i])<= (0.053/sqrt(MCP_NumberSubQuartz))){
            x_array[en] = walls_position[i];
            en =+1;
            if ( abs(inter_front_quartz.GetY()) - abs(roofs_position[i]) <= (0.053/sqrt(MCP_NumberSubQuartz))){
                y_array[to] = roofs_position[i];
                to =+1;
            }
        }
    }

    // Defining the four point in which the particle is incapsuled within the divided quartz:

    Vector position_array_one_zero = Vector(x_array[0], y_array[0], 0);
    Vector position_array_one_one = Vector(x_array[0], y_array[1], 0);
    Vector position_array_two_zero = Vector(x_array[1], y_array[0], 0);
    Vector position_array_two_one = Vector(x_array[1], y_array[1], 0);

    //Defining the four normal vectors for the incapsuled walls and roofs:

    //Walls normal vector:
    //Left:
    Vector normal_left = (position_array_one_one-position_array_one_zero).Cross(Vector(position_array_one_zero.GetX(),position_array_one_zero.GetY(),position_array_one_zero.GetZ()-0.020)-position_array_one_zero);

    //Right:
    Vector normal_right = (position_array_two_one-position_array_two_zero).Cross(Vector(position_array_two_zero.GetX(),position_array_two_zero.GetY(),position_array_two_zero.GetZ()-0.020)-position_array_two_one);


    //Roof normal vectors:
    //Top:
    Vector normal_top = (position_array_two_one-position_array_one_one).Cross(Vector(position_array_one_one.GetX(),position_array_one_one.GetY(),position_array_one_one.GetZ()-0.020)-position_array_one_one);
    //Bottom:
    Vector normal_bottom = (position_array_one_zero-position_array_two_zero).Cross(Vector(position_array_two_zero.GetX(),position_array_two_zero.GetY(),position_array_two_zero.GetZ()-0.020)-position_array_two_zero);


                                    // Putting the normal vectors in a array
    Vector normal_walls_roof[4]={normal_left,normal_right,normal_top,normal_bottom};


    //point on the surface for every normal vector which coresponds to the each surface
    map<Vector, Vector> quartz_surface_position;
    quartz_surface_position[normal_walls_roof[1]] =Vector(position_array_one_zero) + Vector(0, (0.053/8), (0.020/2)*MCP_z_axis_sign ) ; //Left
    quartz_surface_position[normal_walls_roof[2]] =Vector(position_array_two_zero) + Vector(0, (0.053/8), (0.020/2)*MCP_z_axis_sign ); //Right
    quartz_surface_position[normal_walls_roof[3]] =Vector(position_array_one_one)  + Vector((0.053/8), 0, (0.020/2)*MCP_z_axis_sign ); //Top
    quartz_surface_position[normal_walls_roof[4]] =Vector(position_array_two_one)  + Vector(-(0.053/8), 0, (0.020/2)*MCP_z_axis_sign );//Bottom

    Vector Quartz_wall_Intersection; //The intersection point on one of the walls

    Vector return_intersection_vector;

                                        //Looping over which wall it hits
    for (int i=0; i<=3; i++){
        double dot_normal = direction_vector.Dot(normal_walls_roof[i]);
        if (dot_normal < 10e-18)
        { //the dot product should be less than zero so the angle is stump (over 90 degree)

                                        //The intersection point on one of the walls
            Vector Quartz_wall_Intersection = path_photon-(((path_photon-quartz_surface_position[i]).Dot(normal_walls_roof[i])/dot_normal)*direction_vector);

            Vector w_quartz = Quartz_wall_Intersection - quartz_surface_position[i];

            // If the intersection of the plane falls outside window, return a
            // NAN vector.
            if (w_quartz.GetY() > name.GetHeight() || w_quartz.GetZ() > name.GetWidth())
            {
                return_intersection_vector =  Vector(NAN,NAN,NAN);
            }

            else
            {
                if (reflection_on_off==1) //If the reflected momentum is needed:
                {
                    // Refelction vector with in the quartz walls for the Cherenkov photons
                    Vector Reflection_vector_quartz = Cherenkov_photon -2.0*(Cherenkov_photon.Dot(normal_walls_roof[i]))*normal_walls_roof[i];
                    return_intersection_vector = Reflection_vector_quartz;
                }

                else
                {
                    return_intersection_vector = Quartz_wall_Intersection;
                }
            }
        }
    }
    return return_intersection_vector;
}

//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------


void MCP::Cherenkov_Photon_Generation(const Particle& pname, Vector &first_intersection, Vector &second_intersection, Vector pathPhoton_array[], Vector CherenkovPhoton_array[])
{
                            // Now we generates cherenkov photons along the particle path.//

    Vector particle_momentum = pname.GetMomentum();


    // The end_value is a constant, which describes the position where the particle is at the end of the quart plan.
    double end_value =(second_intersection.GetX()-first_intersection.GetX())/particle_momentum.GetX();

    // Generating the path for the particles where the photon should emits as Cherenkov light.


    for (int n=0; n<=1000; n++) //1000 Cherenkov photons per particle
    {
        srand( (unsigned int) time(0) );
        double random_number_d = ( double(rand()) / double(RAND_MAX))*end_value; // generate numbers between 0 and end_value.


        double path_photon_x =first_intersection.GetX() + random_number_d*particle_momentum.GetX();
        double path_photon_y =first_intersection.GetY() + random_number_d*particle_momentum.GetY();;
        double path_photon_z =first_intersection.GetZ() + random_number_d*particle_momentum.GetZ();

        Vector path_photon(path_photon_x,path_photon_y,path_photon_z);

        double random_angle = (rand()/RAND_MAX)* (2*M_PI); //Generate number between 0 and 2*Pi
        Vector velocity_vector = pname.GetVelocity();
        double v = velocity_vector.Length();

        double Cherenkov_Angle = acos((1.0)/(MCP_Quartz_Reflective_index*v));
        double x = (pname.GetMomentum()).Length()*sin(Cherenkov_Angle)*cos(random_angle); //random angle is from 0-2pi
        double y = (pname.GetMomentum()).Length()*sin(Cherenkov_Angle)*sin(random_angle);
        double z = (pname.GetMomentum()).Length()*cos(Cherenkov_Angle);

        Vector Cherenkov_photon(x,y,z);

        //pathPhoton_Cherenkov_array[path_photon] = Cherenkov_photon;
        pathPhoton_array[n] = path_photon;
        CherenkovPhoton_array[n] = Cherenkov_photon;

    }
    return;
}




//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------



Vector MCP::MCP_end_Intersection_for_particle(const Particle& pname, Vector &particle_pos, Detector& name)
{
    // Intersection with the end surface of the quartz//

    // end_position is the position of the end plan of the quartz.
    Vector front_quartz_position = name.fPosition;

    Vector end_position(front_quartz_position.GetX(),front_quartz_position.GetY(),front_quartz_position.GetZ()+(0.020*MCP_z_axis_sign));

    Vector particle_momentum = pname.GetMomentum();

    Vector normal_end_quartz(0, 0, MCP_QuartDimension.GetX()*MCP_QuartDimension.GetY()*MCP_z_axis_sign);

    double dot_end_quartz = particle_momentum.Dot(normal_end_quartz);

    if (dot_end_quartz > 10e-18)
    {
        return Vector(NAN,NAN,NAN);
    }

    // inter_end_quartz is the intersection point on the end surface of the quartz
    Vector inter_end_quartz = particle_pos-(((particle_pos-end_position).Dot(normal_end_quartz)/dot_end_quartz)*particle_momentum);

    Vector w_end_quartz = inter_end_quartz - end_position;

    // If the intersection of the plane falls outside window, return a
    // Zero vector.
    if (w_end_quartz.GetX() > MCP_QuartDimension.GetX() || w_end_quartz.GetY() > MCP_QuartDimension.GetY())
    {
        return Vector(NAN,NAN,NAN);
    }
    return inter_end_quartz;
}


//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------


Vector MCP::MCP_end_Intersection_for_Photon(Vector &Photon_momentum, Vector &particle_pos, Detector& name)
{
    // Intersection with the end surface of the quartz//

    // end_position is the position of the end plan of the quartz.
    Vector front_quartz_position = name.fPosition;

    Vector end_position(front_quartz_position.GetX(),front_quartz_position.GetY(),front_quartz_position.GetZ()+(0.020*MCP_z_axis_sign));

    Vector normal_end_quartz(0, 0, MCP_QuartDimension.GetX()*MCP_QuartDimension.GetY()*MCP_z_axis_sign);

    double dot_end_quartz = Photon_momentum.Dot(normal_end_quartz);

    if (dot_end_quartz > 10e-18)
    {
        return Vector(NAN,NAN,NAN);
    }

    // inter_end_quartz is the intersection point on the end surface of the quartz
    Vector inter_end_quartz = particle_pos-(((particle_pos-end_position).Dot(normal_end_quartz)/dot_end_quartz)*Photon_momentum);

    Vector w_end_quartz = inter_end_quartz - end_position;

    // If the intersection of the plane falls outside window, return a
    // Zero vector.
    if (w_end_quartz.GetX() > MCP_QuartDimension.GetX() || w_end_quartz.GetY() > MCP_QuartDimension.GetY())
    {
        return Vector(NAN,NAN,NAN);
    }
    return inter_end_quartz;
}



//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------



void MCP::MCP_Intersection(const Particle& pname, Vector &particle_pos, Detector& name, Vector intersection_array[], int array_size)
{

    //Intersection with the front surface of the MCP which is the quartz.//

    Vector particle_momentum = pname.GetMomentum(); //Momentum of the particle

    Vector front_quartz_position = name.fPosition; // position of the MCP on the FIT  (Husk nedeunder MCP flad position)

    Vector normal_front_quartz(0,0,MCP_QuartDimension.GetY()*MCP_QuartDimension.GetX());

    double dot_front_quartz = particle_momentum.Dot(normal_front_quartz);

    if (dot_front_quartz > 10e-18)
    {
        //return Vector(NAN, NAN, NAN);
    }



    // inter_front_quartz is the intersection point on the quartz
    Vector inter_front_quartz = particle_pos-(((particle_pos-front_quartz_position).Dot(normal_front_quartz)/dot_front_quartz)*particle_momentum);

    Vector w = inter_front_quartz - front_quartz_position;

    // If the intersection of the plane falls outside window, return a
    // Zero vector.
    if (w.GetX() > name.GetHeight() || w.GetY() > name.GetWidth())
    {
        //return Vector(NAN,NAN,NAN);
    }



    //---------------------------------------------------------------------

                                // Intersection with the end surface of the quartz//

    // end_position is the position of the end plan of the quartz.  ---------.men hvad med protonen flyver den videre igennem MCP?!!!

    Vector end_position(front_quartz_position.GetX(),front_quartz_position.GetY(),front_quartz_position.GetZ()+(0.020*MCP_z_axis_sign));


    Vector normal_end_quartz(0, 0, MCP_QuartDimension.GetX()*MCP_QuartDimension.GetY()*MCP_z_axis_sign);

    double dot_end_quartz = particle_momentum.Dot(normal_end_quartz);

    if (dot_end_quartz > 10e-18) // If it does not intersect with the end panel, then it must intersect with the walls of the MCP.
    {
                                    //Here I find the wall intersection
        Vector zero_vector(NAN,NAN,NAN);

        Vector particle_intersection_with_wall = Quartz_wall_Intersection(name, inter_front_quartz, particle_pos , particle_momentum, 0 , zero_vector);

        //Defining the two arrays for path of the photons and the cherenkov photon vector:

        Vector pathPhoton_array[1000];
        Vector CherenkovPhoton_array[1000];

        Cherenkov_Photon_Generation(pname, inter_front_quartz, particle_intersection_with_wall, pathPhoton_array, CherenkovPhoton_array);

        //slette Vector array_path_cherenkov_photon = Cherenkov_Photon_Generation(pname, inter_front_quartz, particle_intersection_with_wall);

        static Vector intersection_array[1000];

                                    //Here it finds out that the photon intersect with the walls or not.
        for (int i = 0; i <= sizeof(pathPhoton_array); i++)
        {
            Vector photon_intersection_with_wall = Quartz_wall_Intersection(name, inter_front_quartz, pathPhoton_array[i] , CherenkovPhoton_array[i], 0, zero_vector);



            if (photon_intersection_with_wall.GetX() != zero_vector.GetX()) //If the photon interc. with the wall:
            {
                // Here the reflected photon is found:
                Vector reflected_photon = Quartz_wall_Intersection(name, inter_front_quartz, pathPhoton_array[i] , CherenkovPhoton_array[i], 1, CherenkovPhoton_array[i]);

                //The reflected photon is intersected with MCP
                Vector intersection_with_end_MCP = MCP_end_Intersection_for_Photon(reflected_photon, photon_intersection_with_wall, name);

                intersection_array[i] = intersection_with_end_MCP;

                //return Intersection; // tænk lige over det

            }

            else // If the photon do not intersect with the wall then:
            {
                Vector intersection_with_end_MCP = MCP_end_Intersection_for_Photon(CherenkovPhoton_array[i], pathPhoton_array[i], name);

                //Intersection[] = intersection_with_end_MCP;

                intersection_array[i] = intersection_with_end_MCP;
                //return Intersection; // tænk lige over det
            }
        }
    }

    //The particle intersection with the MCP directly

    Vector intersection_with_end_MCP = MCP_end_Intersection_for_particle(pname, particle_pos, name);

    //Intersection[] = intersection_with_end_MCP; 

                                        //Generate Cherenkov photon in 2D array
    Vector pathPhoton_array[1000] = {};
    Vector CherenkovPhoton_array[1000] = {};

    Cherenkov_Photon_Generation(pname, inter_front_quartz, intersection_with_end_MCP, pathPhoton_array, CherenkovPhoton_array);

    Vector zero_vector(NAN,NAN,NAN);

    for (int i = 0; i <= sizeof(CherenkovPhoton_array); i++)
    {
        Vector photon_intersection_with_wall = Quartz_wall_Intersection(name, inter_front_quartz, pathPhoton_array[i], CherenkovPhoton_array[i], 0, zero_vector);
        if (photon_intersection_with_wall.GetX()!= NAN) //If the photon interc. with the wall:
        {
            // Here the reflected photon is found:
            Vector reflected_photon = Quartz_wall_Intersection(name, inter_front_quartz, pathPhoton_array[i] , CherenkovPhoton_array[i], 1, CherenkovPhoton_array[i]);

            //The reflected photon is intersected with MCP
            Vector intersection_with_end_MCP = MCP_end_Intersection_for_Photon(reflected_photon, photon_intersection_with_wall, name);


            intersection_array[i] = intersection_with_end_MCP;
        }

        else
        {
            Vector intersection_with_end_MCP = MCP_end_Intersection_for_Photon(CherenkovPhoton_array[i], pathPhoton_array[i], name);

            intersection_array[i] = intersection_with_end_MCP;
        }
    }
}

Hope someone can figure this out.

#ifndef _VECTOR_H
#define _VECTOR_H

//class ostream;
using namespace std;

class Vector 
{
private:
  double fX;
  double fY;
  double fZ;
public:
  Vector(double x=0, double y=0, double z=0);

  double Length(void) const;
  void   SetX(double x) { fX= x; }
  void   SetY(double y) { fY= y; }
  void   SetZ(double z) { fZ= z; }
  double GetX(void) const { return fX; }
  double GetY(void) const { return fY; }
  double GetZ(void) const { return fZ; }

  Vector Cross(const Vector& v) const;
  double Dot(const Vector& v) const;

  Vector operator+(const Vector& v);
  Vector operator-(const Vector& v);
  Vector operator=(const Vector& v);



    bool operator() (const Vector& lhs, const Vector& rhs) const
    {
        return (lhs.GetX(),lhs.GetY(),lhs.GetZ()) < (rhs.GetX(),rhs.GetY(),rhs.GetZ());
    }



}
;

// Global functions 
Vector operator*(const double  a, const Vector& v);
Vector operator*(const Vector& v, const Vector& u);
std::ostream& operator<<(std::ostream& o, const Vector& v);

#endif
11
  • I created a class called Vector : (double x, double y,double z) Commented Feb 19, 2016 at 10:51
  • 2
    and you define operator < for it? Commented Feb 19, 2016 at 10:52
  • The error message is clear, there's no operator< for Vector. Commented Feb 19, 2016 at 10:52
  • No I haven’t..But it doesn’t makes sense since vector.GetX() should just return a double number... Commented Feb 19, 2016 at 10:55
  • 1
    Which line did you get the error? You should provide a mcve. Commented Feb 19, 2016 at 10:59

1 Answer 1

2

The problem, as pointed out in the last comment, is map<Vector, Vector>. This is a sorted associative container. Its Key is a Vector, and the default order is std::less<Vector>. The compiler duly instantiates std::less<Vector>, finds no specializations, and fails on <. You'll need to provide one, but it can be simple: return std::tie(r.x, r.y, r.z) < std::tie(l.x, l.y, l.z).

PS. normal_walls_roof[] runs from [0] to [3], not [1] to [4].

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your reply. when you say “You'll need to provide one, but it can be simple: return std::tie(r.x, r.y, r.z) < std::tie(l.x, l.y, l.z).” Do you mean that I should provide it in the class description of Vector?
He means specialise std::less<Vector> to do what you want. Read up documentation to work out how.
explicitly specializing std::less is much cleaner than overloading operator < . Good answer!
I have trying to explicitly specializing std::less, but i dont know how to do it..
@zack_ii: Not surprisingly, the answer is already on StackOverflow : stackoverflow.com/questions/2282349/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.