国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Python | 實(shí)現(xiàn)四元數(shù)的運(yùn)算

構(gòu)建四元數(shù)對(duì)象

四元數(shù)是一個(gè)代數(shù)概念,通常用于描述旋轉(zhuǎn),特別是在3D建模和游戲中有廣泛的應(yīng)用。

下面就一步一步演示此對(duì)象的創(chuàng)建方法,特別要關(guān)注雙下劃線開(kāi)始和結(jié)束的那些特殊方法。

class Quaternion: def __init__(self, w, x, y, z): self.w = w self.x = x self.y = y self.z = z

這是首先定義了__init__初始化方法,通過(guò)這個(gè)方法,在創(chuàng)建實(shí)例時(shí)將 分別定義為實(shí)數(shù)。

>>> q1 = Quaternion(1, 2, 3, 4)>>> q1<__main__.Quaternion at 0x7f4210f483c8>

貌似一個(gè)四元數(shù)對(duì)象定義了。但是,它沒(méi)有友好的輸出。接下來(lái)可以通過(guò)定義__repr__和__str__,讓它對(duì)機(jī)器或者開(kāi)發(fā)者都更友好。繼續(xù)在類(lèi)中增加如下方法:

class Quaternion: def __init__(self, w, x, y, z): self.w = w self.x = x self.y = y self.z = z def __repr__(self): return 'Quaternion({}, {}, {}, {})'.format( self.w, self.x, self.y, self.z) def __str__(self): return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format( self.w, self.x, self.y, self.z)

對(duì)于這兩方法,在前面的《Python中的5對(duì)必知的魔法方法》中已經(jīng)有介紹,請(qǐng)參考。

>>> q1          # calls q1.__repr__Quaternion(1, 2, 3, 4)>>> print(q1)   # calls q1.__str__Q = 1.00 + 2.00i + 3.00j + 4.00k

實(shí)現(xiàn)代數(shù)運(yùn)算

上述類(lèi)已經(jīng)能實(shí)現(xiàn)實(shí)例化了,但是,該對(duì)象還要參與計(jì)算,比如加、減法等。這類(lèi)運(yùn)算如何實(shí)現(xiàn)?

加法

class Quaternion: def __init__(self, w, x, y, z): self.w = w self.x = x self.y = y self.z = z def __repr__(self): return 'Quaternion({}, {}, {}, {})'.format( self.w, self.x, self.y, self.z) def __str__(self): return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format( self.w, self.x, self.y, self.z) def __add__(self, other): w = self.w + other.w x = self.x + other.x y = self.y + other.y z = self.z + other.z return Quaternion(w, x, y, z)

__add__是用于實(shí)現(xiàn)對(duì)象的加法運(yùn)算的特殊方法。這樣就可以使用+運(yùn)算符了:

>>> q1 = Quaternion(1, 2, 3, 4)>>> q2 = Quaternion(0, 1, 3, 5)>>> q1 + q2Quaternion(1, 3, 6, 9)

減法

類(lèi)似地,通過(guò)__sub__實(shí)現(xiàn)減法運(yùn)算,不過(guò),這次用一行代碼實(shí)現(xiàn)。

class Quaternion: def __init__(self, w, x, y, z): self.w = w self.x = x self.y = y self.z = z def __repr__(self): return 'Quaternion({}, {}, {}, {})'.format( self.w, self.x, self.y, self.z) def __str__(self): return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format( self.w, self.x, self.y, self.z) def __add__(self, other): w = self.w + other.w x = self.x + other.x y = self.y + other.y z = self.z + other.z return Quaternion(w, x, y, z) def __sub__(self, other): return Quaternion(*list(map(lambda i, j: i - j, self.__dict__.values(), other.__dict__.values())))

有點(diǎn)酷。這里使用了實(shí)例對(duì)象的__dict__屬性,它以字典形式包含了實(shí)例的所有屬性,

乘法

乘法,如果了解一下線性代數(shù),會(huì)感覺(jué)有點(diǎn)復(fù)雜。其中常見(jiàn)的一個(gè)是“點(diǎn)積”,自從Python3.5以后,用@符號(hào)調(diào)用__matmul__方法實(shí)現(xiàn),對(duì)于四元數(shù)對(duì)象而言不能,就是元素與元素對(duì)應(yīng)相乘。

對(duì)于四元數(shù)而言——本質(zhì)就是向量,也可以說(shuō)是矩陣,其乘法就跟矩陣乘法類(lèi)似,比如,同樣不遵守互換率: 。

class Quaternion:    def __init__(self, w, x, y, z):        self.w = w        self.x = x        self.y = y        self.z = z        def __repr__(self):        return 'Quaternion({}, {}, {}, {})'.format(            self.w, self.x, self.y, self.z)    def __str__(self):        return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format(            self.w, self.x, self.y, self.z)        def __add__(self, other):        w = self.w + other.w        x = self.x + other.x        y = self.y + other.y        z = self.z + other.z        return Quaternion(w, x, y, z)            def __sub__(self, other):        return Quaternion(*list(map(lambda i, j: i - j, self.__dict__.values(), other.__dict__.values())))            def __mul__(self, other):        if isinstance(other, Quaternion):            w = self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z            x = self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y            y = self.w * other.y + self.y * other.w + self.z * other.x - self.x * other.z            z = self.w * other.z + self.z * other.w + self.x * other.y - self.y * other.x            return Quaternion(w, x, y, z)        elif isinstance(other, (int, float)):            return Quaternion(*[other * i for i in self.__dict__.values()])        else:            raise TypeError('Operation undefined.')

在__mul__方法中,如果other引用一個(gè)四元數(shù)對(duì)象,那么就會(huì)計(jì)算Hamilton積,并返回一個(gè)新的對(duì)象;如果other是一個(gè)標(biāo)量(比如整數(shù)),就會(huì)與四元數(shù)對(duì)象中的每個(gè)元素相乘。

如前所述,四元數(shù)的乘法不遵循交換律,但是,如果執(zhí)行2 * q1這樣的操作,按照上面的方式,會(huì)報(bào)錯(cuò)——在上面的__mul__方法中解決了q1 * 2的運(yùn)算,而一般我們認(rèn)為這兩個(gè)計(jì)算是相同的。為此,定義了·rmul·來(lái)解決此問(wèn)題:

class Quaternion: def __init__(self, w, x, y, z): self.w = w self.x = x self.y = y self.z = z def __repr__(self): return 'Quaternion({}, {}, {}, {})'.format( self.w, self.x, self.y, self.z) def __str__(self): return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format( self.w, self.x, self.y, self.z) def __add__(self, other): w = self.w + other.w x = self.x + other.x y = self.y + other.y z = self.z + other.z return Quaternion(w, x, y, z) def __sub__(self, other): return Quaternion(*list(map(lambda i, j: i - j, self.__dict__.values(), other.__dict__.values()))) def __mul__(self, other): if isinstance(other, Quaternion): w = self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z x = self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y y = self.w * other.y + self.y * other.w + self.z * other.x - self.x * other.z z = self.w * other.z + self.z * other.w + self.x * other.y - self.y * other.x return Quaternion(w, x, y, z) elif isinstance(other, (int, float)): return Quaternion(*[other * i for i in self.__dict__.values()]) else: raise TypeError('Operation undefined.') def __rmul__(self, other): if isinstance(other, (int, float)): return self.__mul__(other) else: raise TypeError('Operation undefined.')

相等

比較兩個(gè)四元數(shù)是否相等,可以通過(guò)定義__eq__方法來(lái)實(shí)現(xiàn)。

class Quaternion:    def __init__(self, w, x, y, z):        self.w = w        self.x = x        self.y = y        self.z = z        def __repr__(self):        return 'Quaternion({}, {}, {}, {})'.format(            self.w, self.x, self.y, self.z)    def __str__(self):        return 'Q = {:.2f} + {:.2f}i + {:.2f}j + {:.2f}k'.format(            self.w, self.x, self.y, self.z)        def __add__(self, other):        w = self.w + other.w        x = self.x + other.x        y = self.y + other.y        z = self.z + other.z        return Quaternion(w, x, y, z)            def __sub__(self, other):        return Quaternion(*list(map(lambda i, j: i - j, self.__dict__.values(), other.__dict__.values())))            def __mul__(self, other):        if isinstance(other, Quaternion):            w = self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z            x = self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y            y = self.w * other.y + self.y * other.w + self.z * other.x - self.x * other.z            z = self.w * other.z + self.z * other.w + self.x * other.y - self.y * other.x            return Quaternion(w, x, y, z)        elif isinstance(other, (int, float)):            return Quaternion(*[other * i for i in self.__dict__.values()])        else:            raise TypeError('Operation undefined.')                def __rmul__(self, other):        if isinstance(other, (int, float)):            return self.__mul__(other)        else:            raise TypeError('Operation undefined.')                def __eq__(self, other):        r = list(map(lambda i, j: abs(i) == abs(j), self.__dict__.values(), other.__dict__.values()))        return sum(r) == len(r) 

其他運(yùn)算

下面的方法,也可以接續(xù)到前面的類(lèi)中,不過(guò)就不是特殊放方法了。

from math import sqrtdef norm(self): return sqrt(sum([i**2 for i in self.__dict__.values()))def conjugate(self): x, y, z = -self.x, -self.y, -self.z return Quaterion(self.w, x, y, z)def normalize(self): norm = self.norm() return Quaternion(*[i / norm for in self.__dict__.values()])def inverse(self): qconj = self.conjugate() norm = self.norm() return Quaternion(*[i / norm for i in qconj.__dict__.values()])

用這些方法實(shí)現(xiàn)了各自常見(jiàn)的操作。

通過(guò)本文的這個(gè)示例,可以更深刻理解雙下劃線的方法為編程帶來(lái)的便捷。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Python編程中需要注意的一些事
python實(shí)現(xiàn)的NoSql數(shù)據(jù)庫(kù)系列
Python 和 JS 有什么相似?
day22總結(jié)
Json概述以及python對(duì)json的相關(guān)操作
Python處理JSON
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服