【学Rust写CAD】16 0、1、-1代数单位元(algebraic_units.rs)

前文曾经叙述的常量类(Const)包含了本程序的功能,但它目前必须在夜版rust下编译。考虑2D CAD使用需要相对简单,过渡期采用本程序。待rust稳定版可以实现常量类或有3D需求时改用常量类。

源码

//algebraic_units.rs 代数单位元
use std::ops::{Add, Mul, Neg};/// 零元素 (加法单位元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Zero;/// 单位元 (乘法单位元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct One;/// 负单位元 (乘法逆元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DecOne;// ========== Zero 的实现 ==========// Zero + T = T
impl<T> Add<T> for Zero {type Output = T;fn add(self, rhs: T) -> T {rhs}
}// Zero * Zero = Zero
impl Mul for Zero {type Output = Zero;fn mul(self, _: Self) -> Self {Zero}
}// Zero * T = Zero
impl<T> Mul<T> for Zero {type Output = Zero;fn mul(self, _: T) -> Self {Zero}
}// T * Zero = Zero
impl<T> Mul<Zero> for T {type Output = Zero;fn mul(self, _: Zero) -> Zero {Zero}
}// ========== One 的实现 ==========// One * One = One
impl Mul for One {type Output = One;fn mul(self, _: Self) -> Self {One}
}// One * T = T
impl<T> Mul<T> for One {type Output = T;fn mul(self, rhs: T) -> T {rhs}
}// T * One = T
impl<T> Mul<One> for T {type Output = T;fn mul(self, _: One) -> T {self}
}// One + T = T + 1 (需要 T 支持 Add<i32>)
impl<T: Add<i32, Output = T>> Add<T> for One {type Output = T;fn add(self, rhs: T) -> T {rhs + 1}
}// ========== DecOne 的实现 ==========// DecOne * DecOne = One
impl Mul for DecOne {type Output = One;fn mul(self, _: Self) -> One {One}
}// DecOne * T = -T (需要 T 支持 Neg)
impl<T: Neg<Output = T>> Mul<T> for DecOne {type Output = T;fn mul(self, rhs: T) -> T {-rhs}
}// T * DecOne = -T (需要 T 支持 Neg)
impl<T: Neg<Output = T>> Mul<DecOne> for T {type Output = T;fn mul(self, _: DecOne) -> T {-self}
}// DecOne + T = T - 1 (需要 T 支持 Sub<i32>)
impl<T: Sub<i32, Output = T>> Add<T> for DecOne {type Output = T;fn add(self, rhs: T) -> T {rhs - 1}
}// ========== 其他组合运算 ==========// One * DecOne = DecOne
impl Mul<DecOne> for One {type Output = DecOne;fn mul(self, rhs: DecOne) -> DecOne {rhs}
}// DecOne * One = DecOne
impl Mul<One> for DecOne {type Output = DecOne;fn mul(self, _: One) -> DecOne {self}
}// Zero * DecOne = Zero (已由 Zero 的通用实现覆盖)
// DecOne * Zero = Zero (已由 Zero 的通用实现覆盖)#[cfg(test)]
mod tests {use super::*;#[test]fn test_zero_operations() {let z = Zero;// 加法测试assert_eq!(z + 5, 5);       // 0 + 5 = 5assert_eq!(z + (-3), -3);  // 0 + (-3) = -3assert_eq!(z + "hello", "hello"); // 0 + 非数字类型// 乘法测试assert_eq!(z * z, z);       // 0 * 0 = 0assert_eq!(z * 10, z);      // 0 * 10 = 0assert_eq!(10 * z, z);      // 10 * 0 = 0assert_eq!(z * One, z);     // 0 * 1 = 0assert_eq!(One * z, z);     // 1 * 0 = 0assert_eq!(z * DecOne, z);  // 0 * -1 = 0assert_eq!(DecOne * z, z);  // -1 * 0 = 0}#[test]fn test_one_operations() {let o = One;// 乘法测试assert_eq!(o * o, o);       // 1 * 1 = 1assert_eq!(o * 7, 7);       // 1 * 7 = 7assert_eq!(7 * o, 7);       // 7 * 1 = 7assert_eq!(o * DecOne, DecOne); // 1 * -1 = -1assert_eq!(DecOne * o, DecOne); // -1 * 1 = -1// 加法测试assert_eq!(o + 3, 4);       // 1 + 3 = 4assert_eq!(o + (-2), -1);   // 1 + (-2) = -1}#[test]fn test_dec_one_operations() {let d = DecOne;// 乘法测试assert_eq!(d * d, One);     // -1 * -1 = 1assert_eq!(d * 4, -4);      // -1 * 4 = -4assert_eq!(4 * d, -4);      // 4 * -1 = -4assert_eq!(d * One, d);     // -1 * 1 = -1assert_eq!(One * d, d);     // 1 * -1 = -1// 加法测试assert_eq!(d + 5, 4);       // -1 + 5 = 4assert_eq!(d + (-3), -4);   // -1 + (-3) = -4}#[test]fn test_mixed_operations() {// 混合类型运算assert_eq!(One * (DecOne * 3), -3); // 1 * (-1 * 3) = -3assert_eq!((Zero + One) * DecOne, DecOne); // (0 + 1) * -1 = -1assert_eq!(DecOne * (One + 1), -2); // -1 * (1 + 1) = -2}#[test]fn test_commutative_law() {// 验证交换律let a = 5;assert_eq!(a * One, One * a);assert_eq!(a * DecOne, DecOne * a);assert_eq!(a * Zero, Zero * a);}#[test]fn test_associative_law() {// 验证结合律 (注意:加法实现不满足严格结合律)assert_eq!((One * DecOne) * DecOne, One * (DecOne * DecOne)); // (-1) * -1 = 1}#[test]fn test_distributive_law() {// 验证分配律 (a + b) * c = a*c + b*clet a = 2;let b = 3;let c = DecOne;assert_eq!((a + b) * c, a * c + b * c); // 5 * -1 = -2 + -3}
}

代码分析

这段代码定义了几个表示数学概念的单元类型(Zero、One、DecOne)并实现了它们的运算规则。下面将详细解释:

  1. 类型定义
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Zero;  // 表示加法单位元(0)
#[derive(Clone, Debug, Default, PartialEq, Eq)] 
pub struct One;   // 表示乘法单位元(1)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DecOne; // 表示乘法逆元(-1)
  1. Zero 的实现
    实现了加法单位元的性质:
  • Zero + T = T:任何数加0等于它本身

  • Zero * T = Zero:任何数乘0等于0

  • T * Zero = Zero:乘法交换律

  1. One 的实现
    实现了乘法单位元的性质:
  • One * T = T:任何数乘1等于它本身

  • T * One = T:乘法交换律

  • One + T = T + 1:特殊的加法实现(需要T支持加整数)

  1. DecOne 的实现
    实现了乘法逆元的性质:
  • DecOne * DecOne = One:-1 * -1 = 1

  • DecOne * T = -T:任何数乘-1等于它的负数

  • T * DecOne = -T:乘法交换律

  • DecOne + T = T - 1:特殊的加法实现(需要T支持减整数)

  1. 其他组合运算
    处理了这些类型之间的交互运算,如:
  • One * DecOne = DecOne

  • DecOne * One = DecOne

  1. 测试部分
    包含详尽的测试用例验证:
  • 基本运算的正确性

  • 混合运算的正确性

  • 数学定律(交换律、结合律、分配律)的验证

关键点

  1. 这些类型都是零大小的单元类型,仅用作标记

  2. 通过Rust的trait系统实现了运算符重载

  3. 实现了数学中单位元的抽象概念:

  • Zero是加法的单位元

  • One是乘法的单位元

  • DecOne是乘法的逆元

  1. 泛型实现使得这些运算可以适用于多种类型

这种实现方式在代数系统、线性代数库或符号计算中很有用,可以优雅地表示数学概念而不引入运行时开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/43283.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++Primer学习(14.1 基本概念)

当运算符作用于类类型的运算对象时&#xff0c;可以通过运算符重载重新定义该运算符的含义。明智地使用运算符重载能令我们的程序更易于编写和阅读。举个例子&#xff0c;因为在Sales_item类中定义了输入、输出和加法运算符&#xff0c;所以可以通过下述形式输出两个Sales_item…

循相似之迹:解锁协同过滤的核心推荐逻辑

目录 一、引言二、协同过滤的基本原理三、协同过滤的算法类型&#xff08;一&#xff09;基于用户的协同过滤&#xff08;二&#xff09;基于物品的协同过滤 四、协同过滤的应用案例&#xff08;一&#xff09;电商平台的商品推荐&#xff08;二&#xff09;音乐平台的歌曲推荐…

RuoYi基础学习

1 若依搭建 前后端分离版本&#xff1a;RuoYi-Vue利用SpringBoot作为后端开发框架&#xff0c;与Vue.js结合&#xff0c;实现了前后端分离的开发模式。这种架构有助于提高开发效率&#xff0c;前后端可以独立开发和部署&#xff0c;更适合现代化的Web应用开发。 RuoYi-Vue3&a…

Docker 安装部署Harbor 私有仓库

Docker 安装部署Harbor 私有仓库 系统环境:redhat x86_64 一、首先部署docker 环境 定制软件源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repoyum install -y yum-utils device-mapper-persistent-data lvm2…

【Basys3】外设-灯和数码管

灯 约束文件 set_property PACKAGE_PIN W5 [get_ports CLK] set_property PACKAGE_PIN U18 [get_ports rst] set_property PACKAGE_PIN U16 [get_ports {led[0]}] set_property PACKAGE_PIN E19 [get_ports {led[1]}] set_property PACKAGE_PIN U19 [get_ports {led[2]}] set…

【Django】教程-1-安装+创建项目+目录结构介绍

欢迎关注我&#xff01;后续会更新django教程。一周2-3更&#xff0c;欢迎跟进&#xff0c;本周会更新第一个Demo的单独一个模块的增删改查【Django】教程-4-一个增删改查的Demo【Django】教程-2-前端-目录结构介绍【Django】教程-3-数据库相关介绍 1.项目创建 1.1 安装 Djan…

蓝桥杯 之 二分

文章目录 习题肖恩的n次根分巧克力2.卡牌 二分是十分重要的一个算法&#xff0c;常常用于求解一定范围内&#xff0c;找到满足条件的边界值的情况主要分为浮点数二分和整数二分二分问题&#xff0c;最主要是写出这个check函数&#xff0c;这个check函数最主要就是使用模拟的方法…

SpringBoot集成腾讯云OCR实现身份证识别

OCR身份证识别 官网地址&#xff1a;https://cloud.tencent.com/document/product/866/33524 身份信息认证&#xff08;二要素核验&#xff09; 官网地址&#xff1a;https://cloud.tencent.com/document/product/1007/33188 代码实现 引入依赖 <dependency><…

2025年3月电子学会c++五级真题

结绳 #include <bits/stdc.h> using namespace std;int n,a[10010];int main() {cin>>n;for(int i 0;i<n;i){cin>>a[i];}sort(a0,an);//将a数组从小到大排序double sum 0;for(int i 0;i<n;i){sum (suma[i])/2;}cout<<(int)sum;return 0; } 最…

Typora使用Gitee作为图床

Typora使用Gitee作为图床 文章目录 Typora使用Gitee作为图床Gitee准备图床仓库下载安装软件安装插件 配置Typora Gitee准备图床仓库 新建一个仓库右上角下拉->设置->安全设置->私人令牌->生成新令牌&#xff0c;注意将令牌保存&#xff08;只会出现一次&#xff0…

QT音乐播放器(1):数据库保存歌曲

实现功能&#xff1a;用数据库保存本地导入和在线搜索的歌曲记录 目录 一. 保存本地添加的歌曲 1. 使用QSettings &#xff08;1&#xff09;在构造函数中&#xff0c;创建对象。 &#xff08;2&#xff09;在导入音乐槽函数中&#xff0c;保存新添加的文件路径&#xff0c…

SQLAlchemy关键词搜索技术深度解析:从基础过滤到全文检索

在数据驱动的应用开发中&#xff0c;基于关键词的模糊查询是常见的业务需求。SQLAlchemy作为Python生态中最流行的ORM框架&#xff0c;提供了多种实现关键词搜索的技术方案。本文将从性能、适用场景和技术复杂度三个维度&#xff0c;系统对比分析SQLAlchemy中关键词搜索的最佳实…

css属性列举

介绍 CSS word-spacing 属性&#xff0c;用于指定段字之间的空间&#xff0c;例如&#xff1a; p {word-spacing:30px; }word-spacing属性增加或减少字与字之间的空白。 注意&#xff1a; 负值是允许的。 浏览器支持 表格中的数字表示支持该属性的第一个浏览器版本号。 属…

python实现股票数据可视化

最近在做一个涉及到股票数据清洗及预测的项目&#xff0c;项目中需要用到可视化股票数据这一功能&#xff0c;这里我与大家分享一下股票数据可视化的一些基本方法。 股票数据获取 在经过多次尝试后&#xff0c;发现了一个

从 JDK 11 到 JDK 17:OpenRewrite 实战 Spring Boot 升级指南

一、为什么选择 OpenRewrite 升级&#xff1f; 在 Spring Boot 项目升级 JDK 的过程中&#xff0c;我们面临两个核心痛点&#xff1a; 语法兼容性问题&#xff08;如废弃的 API、新的关键字&#xff09;依赖版本冲突&#xff08;特别是 Spring Boot 与 JDK 版本的匹配&#x…

交换技术综合实验

一、实验拓扑 二、实验要求 内网IP地址使用172.16.0.0/16分配。 SW1和SW2之间互为备份。 VRRP/STP/VLAN/Eth-trunk均使用。 所有PC通过DHCP获取IP地址。 ISP只能配置IP地址。 所有电脑可以正常访问ISP路由器。 三、实验步骤 基于172.16.0.0/16进行划分 172.16.2.0/24&…

【Linux】了解基础指令(超详细)

目录 【whoami】指令【pwd】指令【mkdir】指令【touch】指令【ls】指令文件的扩展内容 【cd】指令相对路径和绝对路径(.和..存在的原因)绝对路径相对路径 【rm】指令【man】命令【less】指令echo指令重定向操作追加重定向 cat 指令输入重定向 管道操作(组合指令)查找三剑客find…

基于改进粒子群算法的多目标分布式电源选址定容规划(附带Matlab代码)

通过分析分布式电源对配电网的影响&#xff0c;以有功功率损耗、电压质量及分布式电源总容量为优化目标&#xff0c;基于模糊理论建立了分布式电源在配电网中选址定容的多目标优化模型&#xff0c;并提出了一种改进粒子群算法进行求解。在算例仿真中&#xff0c;基于IEEE-14标准…

26_ajax

目录 了解 接口 前后端交互 一、安装服务器环境 nodejs ajax发起请求 渲染响应结果 get方式传递参数 post方式传递参数 封装ajax_上 封装ajax下 了解 清楚前后端交互就可以写一些后端代码了。小项目 现在写项目开发的时候都是前后端分离 之前都没有前端这个东西&a…