How can we define the __mult__ method to return a Complex object?

In summary: Vector: def __init__(self, coord): self.coord = np.asarray(coord) self.norm2 = sqrt(sum(x**2 for x in self.coord))vec = Vector([1, 2, 3])print(vec.norm2)Now try your move code...In summary, the Vector class stores a tuple of the coordinates of the vector. The initialization function, __init__, takes a tuple as an argument. This tuple will be stored in the variable named coord
  • #1
mathmari
Gold Member
MHB
5,049
7
Hey! 😊

Construct a class named Vector that expresses the meaning of the vector of numbers. The initialization function, __init__ will take as a argument a tuple corresponding to the vector. This tuple will be stored in the variable named coord. Also, __init__ will calculate the Euclidean measure of the vector and store it in the variable norm2. How do we write the tuple as an argument of the function?

Do we write just :
Code:
class Vector : 
    
    def __init__(self, coord): 
         pass

? Or do we have to the elements there and insert these into the tuple?

:unsure:
 
Technology news on Phys.org
  • #2
Hi mathmari,

Ok so a tuple is an object type that is stored in round parentheses.

Here's an example of how this would work as a list. Can you make it a tuple?

Code:
class Vector :
    
    def __init__(self, coord):
         self.coord = coordvec = Vector([1,2,3])

print(type(vec.coord))
 
  • #3
Here's my solution to this:
Code:
from math import sqrt

class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector((1, 2, 3))
print(vec.norm2)
 
  • #4
I wish you a Happy New Year! 🎉

Jameson said:
Here's my solution to this:
Code:
from math import sqrt

class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector((1, 2, 3))
print(vec.norm2)

I got it!Next I want to write the method move (self, i, x). This method moves the vector by x in the direction of the i-th coordinate. That is, it simply adds the number x to the i-position of the coordinates and updates this variable with the new value. The variables should be updated at norm2. The method does not returns anything, just shifts the vector.

For that I wrote the following :

Code:
def move(self, i, x) :
        if (i < 0 or i > self.dim) :
            print("Error")
        else :
            self.coord[i] += x
            self.norm2 = sqrt(sum(x**2 for x in self.coord))

I defined as self.dim the dimension of the given vector inside the __init__
I get an error at "self.coord += x". Is that wrong to give the new value to the i-th coordinate of the vector?
Also when it is said to update the norm2, is it meant to write that again inside the method or is something else meant?

:unsure:After that I want to write the method __add __ (self, other). This (magic) method is called when the object is involved in algebraic addition expressions. When the variable other is a number then it is added in the vector coordinates and returns a new object of the Vector class. When the variable other is the object of the Vector class, then it is added by point of two vectors and the new vector is returned.

Example :
v = Vector((5,6,7))
w = Vector((1,2,3))
v+w = (6, 8, 10)
v+3 = (5, 6, 7)

For that I wrote :

Code:
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.coord + other.coord)
        else :
            return Vector(x + other for x in self.coord)

But that doesn't work. How can we write then to add each component of the first vector with the corresponding component of the second vector?:unsure:
 
Last edited by a moderator:
  • #5
Let's make one change from using tuples to using numpy arrays. Tuples are immutable, meaning cannot be changed, whereas numpy arrays are mutable.

Code:
from math import sqrt
import numpy as npclass Vector:
    def __init__(self, coord):
        self.coord = np.asarray(coord)
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector([1, 2, 3])

print(vec.norm2)

Now try your move code...
 
  • #6
Jameson said:
Let's make one change from using tuples to using numpy arrays. Tuples are immutable, meaning cannot be changed, whereas numpy arrays are mutable.

Code:
from math import sqrt
import numpy as npclass Vector:
    def __init__(self, coord):
        self.coord = np.asarray(coord)
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector([1, 2, 3])

print(vec.norm2)

Now try your move code...

Ahh ok! :geek: Since we haven't seen the numpy library yet, do we maybe do the changes of the tuples using lists? I mean to turn the tuple into a list then make the desired changes and then turn the result again into a tuple.

:unsure:
 
  • #7
Actually a list works the same way it seems. I removed the above numpy reference and this seems to work.

Code:
class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))
    
    def move(self, i, x):
        if (i < 0):
            print("Error")
        else :
            self.coord[i] += x
            self.norm2 = sqrt(sum(x**2 for x in self.coord))vec = Vector([1, 2, 3])

print(vec.norm2)
vec.move(1, 1)
print(vec.coord)
 
  • #8
mathmari said:
After that I want to write the method __add __ (self, other). This (magic) method is called when the object is involved in algebraic addition expressions. When the variable other is a number then it is added in the vector coordinates and returns a new object of the Vector class. When the variable other is the object of the Vector class, then it is added by point of two vectors and the new vector is returned.

Example :
v = Vector((5,6,7))
w = Vector((1,2,3))
v+w = (6, 8, 10)
v+3 = (5, 6, 7)

For that I wrote :

Code:
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.coord + other.coord)
        else :
            return Vector(x + other for x in self.coord)

But that doesn't work. How can we write then to add each component of the first vector with the corresponding component of the second vector?:unsure:

Ok for this part I would try something like this as a hint, if we are using lists to input.

Code:
    def __add__(self, other):
        if len(self.coord) != len(other.coord):
            print("Error")
        else:
            new_coord = []
            for i in range(len(self.coord)):

Loop over each Vector's coordinates and add them to the new list, then make that list part of a new Vector.
 
Last edited:
  • #9
I see! Now my code works properly! :geek: Now I want to construct a Point class that expresses the meaning of the point in the plane ($\mathbb{R}^2$). We can define it as a subclass of Vector. Point should additionally include the following methods:
- get_angle(self)
- get_polar(self)

So do we just call a Vector instance (x,y) for Point ? Or how do we define that? :unsure:
 
  • #10
You make subclasses in Python like this...
Code:
class Point(Vector):
    def __init__(self, coord):

You still need to initialize all the proper inputs, but if you write a subclass like this then Point should have a move() method based on inheriting from Vector.
 
  • #11
Jameson said:
You make subclasses in Python like this...
Code:
class Point(Vector):
    def __init__(self, coord):

You still need to initialize all the proper inputs, but if you write a subclass like this then Point should have a move() method based on inheriting from Vector.

Ah ok! So when we have saved both .py file in the same directory we can use also the functions that we defined at the class Vector for Point, right? :unsure:

So at this part of the exercise what do we have to define in __init__ ? Do we just write "pass" ? Or do we write "self.coord = coord" ? Or do we have the same __init__ as in the Vector class? And other than __init__ we just define the two methods "get_angle(self)" and "get_polar(self)", or not ? :unsure:
 
  • #12
The key word I saw that led me to use this idea was "subclass". One of the core functions of classes in Python is the ability to inherit from other classes into a subclass. Yes you will need to fill out the __init___ with all the key inputs, but it should auto carry over the methods that you wrote in Vector. So if you do this correctly, Point should have a move() method once you initialize it because it inherits that from Vector.

Try to finish the __init___ method and then test if you have a move method. There are multiple ways to do this but I don't want to make this too complicated. Then I would try to move on to writing get_angle() and get_polar(), yep.
 
  • #13
Jameson said:
The key word I saw that led me to use this idea was "subclass". One of the core functions of classes in Python is the ability to inherit from other classes into a subclass. Yes you will need to fill out the __init___ with all the key inputs, but it should auto carry over the methods that you wrote in Vector. So if you do this correctly, Point should have a move() method once you initialize it because it inherits that from Vector.

Try to finish the __init___ method and then test if you have a move method. There are multiple ways to do this but I don't want to make this too complicated. Then I would try to move on to writing get_angle() and get_polar(), yep.
I wrote that and it works! :giggle:
The angle is calculated as arctan(y/x), right? :unsure:

After that I want to do the following :

Construct a class Complex that expresses the meaning of the point in the complex plane (C). You can define this class as a subclass of Point. The Complex should implement the multiplication (__mul__) as the multiplication of complex numbers. Implement methods to get the real (self.re) and the imaginary (self.im) part of the number.

I have some questions about that.. For the multiplication do we return a tuple in the form [real part, imaginary part] ? I mean $[ac-bd, ad+bc]$ ? Or what should the __mul__ return? :unsure:

To give the real and the imaginary part do we not just give the first and the second coordinate? Or what should we do here exactly? :unsure:
 
  • #14
I'm not really sure why we want to make Complex a subclass of Point, but it seems for both they want to assume that the input space is $\mathbb{R}^2$. I would add a condition in the __init__ method to check for this perhaps, just to be safe.

After that yep you can made the __mult__ method and define it like you suggested. it should return a Complex object. When we add two Complex objects we return a new Complex object, and similarly so if we multiply them.
 

FAQ: How can we define the __mult__ method to return a Complex object?

What is the purpose of the __mult__ method in a Complex object?

The __mult__ method is used to define how two Complex objects can be multiplied together. It allows for custom behavior and calculations to be performed when multiplying two Complex objects.

How is the __mult__ method different from the regular multiplication operator in Python?

The __mult__ method is specific to the Complex object and allows for custom behavior, while the regular multiplication operator is a built-in Python operation that follows a specific set of rules for multiplying different data types.

What are the parameters for the __mult__ method and how are they used?

The __mult__ method typically takes in two parameters, which are the two Complex objects that are being multiplied together. These parameters are then used to perform the desired calculations and return a new Complex object as the result.

Can the __mult__ method be overridden in a subclass of the Complex object?

Yes, the __mult__ method can be overridden in a subclass of the Complex object. This allows for even further customization of the behavior when multiplying Complex objects.

How can we ensure that the __mult__ method returns a valid Complex object?

To ensure that the __mult__ method returns a valid Complex object, we can include error handling and validation to check that the input parameters are valid Complex objects and that the result of the calculations also meets the requirements of a Complex object.

Similar threads

Back
Top