A/B测试之t-test

本文探讨了使用贝叶斯t检验进行A/B测试的情况,特别是在分析药物对IQ影响的实验中。通过导入数据并使用t分布拟合模型,结果显示药物可能有效且增加IQ波动。对比传统频率学派的t检验,贝叶斯方法对异常值更敏感,得出了不同的结论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贝叶斯的t检验可以参考John K. Kruschke的著作Doing Bayesian Data Analysis的第16章。

本文的例子使用的数据集可以从github取得:

Doing-Bayesian-Data-Analysis-in-brms-and-the-tidyverse/TwoGroupIQ.csv at master · ASKurz/Doing-Bayesian-Data-Analysis-in-brms-and-the-tidyverse · GitHub

这是关于某种药物能否影响IQ的实验。

首先,导入数据并拟合模型

library(tidyverse)
library(tidybayes)
library(brms)

my_data <- read_csv("TwoGroupIQ.csv")
(mean_y <- mean(my_data$Score))
(sd_y <- sd(my_data$Score))
stanvars <- 
  stanvar(mean_y, name = "mean_y") + 
  stanvar(sd_y,   name = "sd_y") + 
  stanvar(1/29,   name = "one_over_twentynine")
fi
There is an explosion of interest in Bayesian statistics, primarily because recently created computational methods have finally made Bayesian analysis tractable and accessible to a wide audience. Doing Bayesian Data Analysis, A Tutorial Introduction with R and BUGS, is for first year graduate students or advanced undergraduates and provides an accessible approach, as all mathematics is explained intuitively and with concrete examples. It assumes only algebra and ‘rusty’ calculus. Unlike other textbooks, this book begins with the basics, including essential concepts of probability and random sampling. The book gradually climbs all the way to advanced hierarchical modeling methods for realistic data. The text provides complete examples with the R programming language and BUGS software (both freeware), and begins with basic programming examples, working up gradually to complete programs for complex analyses and presentation graphics. These templates can be easily adapted for a large variety of students and their own research needs.The textbook bridges the students from their undergraduate training into modern Bayesian methods. Accessible, including the basics of essential concepts of probability and random sampling Examples with R programming language and BUGS software Comprehensive coverage of all scenarios addressed by non-bayesian textbooks- t-tests, analysis of variance (ANOVA) and comparisons in ANOVA, multiple regression, and chi-square (contingency table analysis). Coverage of experiment planning R and BUGS computer programming code on website Exercises have explicit purposes and guidelines for accomplishment 作者从概率统计和编程两方面入手,由浅入深地指导读者如何对实际数据进行贝叶斯分析。全书分成三部分,第一部分为基础篇:关于参数、概率、贝叶斯法则及R软件,第二部分为二元比例推断的基本理论,第三部分为广义线性模型。内容包括贝叶斯统计的基本理论、实验设计的有关知识、以层次模型和MCMC为代表的复杂方法等。同时覆盖所有需要用到非贝叶斯方法的情况,其中包括:t检验,方差分析(ANOVA)和ANOVA中的多重比较法,多元线性回归,Logistic回归,序列回归和卡方(列联表)分析。针对不同的学习目标(如R、BUGS等)列出了相应的重点章节;整理出贝叶斯统计中某些与传统统计学可作类比的内容,方便读者快速学习。本中提出的方法都是可操作的,并且所有涉及数学理论的地方都已经用实际例子非常直观地进行了解释。由于并不对读者的统计或编程基础有较高的要求,因此本书非常适合社会学或生物学研究者入门参考,同时也可作为相关科研人员的参考书。
#include <stdio.h> #include <stdlib.h> // 椭圆曲线点结构(包含无穷远点标识) typedef struct { int x; int y; int is_infinite; // 1表示无穷远点O,0为正常点 } ECPoint; // 椭圆曲线参数结构 typedef struct { int p; // 素数域 int a, b; // 曲线方程y^2 = x^3 + a*x + b ECPoint G; // 生成元基点 int n; // 基点G的阶数(可选) } ECCurve; //----------------------------------- // 学生需实现的函数(下方空白处编码) //----------------------------------- // 模运算(确保结果非负) int mod(int a, int p) { // TODO: 实现取模运算,处理负数情况 } // 模逆元(扩展欧几里得算法) int mod_inverse(int a, int p) { // TODO: 返回a mod p的逆元,若无解返回-1 } // 判断点是否在曲线上 int is_point_on_curve(ECPoint P, ECCurve curve) { // TODO: 若P是无穷远点返回1,否则验证是否满足方程 } // 椭圆曲线点加法 ECPoint ec_point_add(ECPoint P, ECPoint Q, ECCurve curve) { // TODO: 处理P=O, Q=O, P=-Q等情况,返回P+Q } // 椭圆曲线标量乘法(double-and-add) ECPoint ec_scalar_mult(int k, ECPoint P, ECCurve curve) { // TODO: 返回k*P的结果 } //----------------------------------- // 主函数与测试案例(已实现部分) //----------------------------------- int main() { // 示例曲线参数(简化版) ECCurve test_curve = { .p = 17, .a = 2, .b = 3, .G = {5, 6, 0}, // 合法基点(5,6) .n = 19 }; printf("=== ECC基础运算测试 ===\n"); // 测试用例1:点加法-计算G + G ECPoint G_plus_G = ec_point_add(test_curve.G, test_curve.G, test_curve); printf("G + G = (%d, %d)\t\n", G_plus_G.x, G_plus_G.y); // 测试用例2:标量乘法-计算3*G ECPoint threeG = ec_scalar_mult(3, test_curve.G, test_curve); printf("3G = (%d, %d)\t\n", threeG.x, threeG.y); return 0; }
最新发布
03-20
<think>好的,用户想要在C语言中实现椭圆曲线加密的几个关键函数:mod、mod_inverse、is_point_on_curve、ec_point_add和ec_scalar_mult。我需要仔细考虑每个函数的具体实现步骤,同时确保符合椭圆曲线的数学规则。 首先,关于mod函数。C语言中负数取模的问题需要注意,因为标准运算符%在处理负数时可能返回负余数。因此,需要调整结果使其始终为正。例如,-5 % 3在C中是-2,但我们需要返回1。所以,mod函数应该计算(a % n + n) % n,确保结果非负。 然后是mod_inverse函数,即模逆元。这里需要使用扩展欧几里得算法。算法的主要步骤是找到x使得(a * x) mod n = 1。需要注意处理a和n是否互质的情况,如果不互质,逆元不存在,需要返回错误或特定值。此外,算法实现时需要维护必要的变量,如old_r, r, old_s, s等,并在循环结束后检查gcd是否为1,如果是,则调整s的符号并返回mod(s, n)以确保结果正确。 接下来是is_point_on_curve函数。椭圆曲线的一般形式是y² ≡ x³ + ax + b (mod p)。给定点P(x, y),需要验证左右两边的等式是否成立。计算左边y² mod p,右边计算x³ + a*x + b mod p,然后比较两者是否相等。注意处理无穷远点的情况,通常用(0, 0)或其他特定值表示,需要根据具体实现判断。 点加法函数ec_point_add需要考虑几种情况:两个点是否相同(需要双倍加),其中一个是否是无穷远点,或者两点是否关于x轴对称(结果为无穷远点)。对于不同的情况,计算斜率λ的方式也不同。例如,当两点不同且不互为逆元时,λ = (y2 - y1)/(x2 - x1) mod p;而当两点相同时,使用导数公式λ = (3x1² + a)/(2y1) mod p。每一步计算都需要进行模运算,避免中间结果溢出,特别是分母的模逆元计算需要正确实现。 标量乘法ec_scalar_mult通常采用双倍加算法,类似于快速幂的方法。将标量k表示为二进制,逐位处理,通过双倍和加法来累积结果。需要处理无穷远点作为初始值,并在每一步更新当前点的位置。需要注意的是,标量乘法中的加法实际上是点加法,必须正确调用ec_point_add函数,并且处理可能的无穷远点情况。 在实现过程中,数据结构的定义也很重要。例如,点可以用结构体表示,包含x和y坐标,以及可能的标志位表示无穷远点。此外,所有的中间计算步骤都要确保使用模运算,避免整数溢出,可能需要使用大整数库或者限制椭圆曲线的参数大小。 还需要考虑测试用例,例如使用已知的椭圆曲线参数和点,验证各函数的正确性。例如,NIST标准曲线中的参数可以用来测试mod_inverse是否正确,点加法和标量乘法是否符合预期结果。 可能遇到的问题包括:模逆元在a和p不互质时的处理,点加法中斜率计算时的除零错误,以及标量乘法中无穷远点的正确处理。因此,在代码中加入必要的错误检查和边界条件处理是重要的。 最后,代码的效率和可读性需要平衡。例如,在标量乘法中使用循环而不是递归,以避免栈溢出,同时合理利用辅助函数来简化代码结构。</think>### 1. 模运算实现 (mod函数) ```c // 处理负数的取模问题 int mod(int a, int p) { int result = a % p; return (result < 0) ? (result + p) : result; } ``` ### 2. 模逆元实现 (mod_inverse函数) 使用扩展欧几里得算法实现[^1]: ```c int mod_inverse(int a, int p) { int old_r = a, r = p; int old_s = 1, s = 0; while (r != 0) { int quotient = old_r / r; int temp = r; r = old_r - quotient * r; old_r = temp; temp = s; s = old_s - quotient * s; old_s = temp; } if (old_r != 1) return -1; // 逆元不存在 return mod(old_s, p); } ``` ### 3. 点验证函数 (is_point_on_curve) ```c typedef struct { int x; int y; } EC_Point; int is_point_on_curve(EC_Point P, int a, int b, int p) { if (P.x == 0 && P.y == 0) return 1; // 无穷远点 int lhs = mod(P.y * P.y, p); int rhs = mod((P.x * P.x * P.x) + a * P.x + b, p); return lhs == rhs; } ``` ### 4. 点加法实现 (ec_point_add) ```c EC_Point ec_point_add(EC_Point P, EC_Point Q, int a, int p) { EC_Point R; // 处理特殊情况 if (P.x == 0 && P.y == 0) return Q; if (Q.x == 0 && Q.y == 0) return P; if (P.x == Q.x) { if (mod(P.y + Q.y, p) == 0) { R.x = R.y = 0; // 无穷远点 return R; } } // 计算斜率λ int lambda; if (P.x != Q.x) { int numerator = mod(Q.y - P.y, p); int denominator = mod(Q.x - P.x, p); int inv_denominator = mod_inverse(denominator, p); lambda = mod(numerator * inv_denominator, p); } else { int numerator = mod(3 * P.x * P.x + a, p); int denominator = mod(2 * P.y, p); int inv_denominator = mod_inverse(denominator, p); lambda = mod(numerator * inv_denominator, p); } // 计算新坐标 R.x = mod(lambda * lambda - P.x - Q.x, p); R.y = mod(lambda * (P.x - R.x) - P.y, p); return R; } ``` ### 5. 标量乘法实现 (ec_scalar_mult) ```c EC_Point ec_scalar_mult(int k, EC_Point P, int a, int p) { EC_Point R = {0, 0}; // 无穷远点 while (k > 0) { if (k % 2 == 1) { R = ec_point_add(R, P, a, p); } P = ec_point_add(P, P, a, p); k = k / 2; } return R; } ``` ### 关键实现要点 1. 模运算处理负数时通过加法修正结果 2. 扩展欧几里得算法中维护`old_r`和`old_s`追踪贝祖系数[^1] 3. 点加法中处理三种特殊情形: - 任意一点是无穷远点时直接返回另一点 - 两点相同时使用切线规则(双倍加) - 两点x坐标相同时需要判断是否为逆元
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值