- 金融科技
- 科学计算
【免费下载链接】tf-quant-finance
High-performance TensorFlow library for quantitative finance.
convert_to_tensor_or_func是 tf-quant-finance 的tff.math.piecewise模块中一个精巧的入参预处理函数:它把"要么是常数Tensor、要么是随时间变化的分段常数函数PiecewiseConstantFunc"的两种输入统一归一化,并返回一个布尔标记供调用方决定后续走"常数分支"还是"时变分支"。本篇将结合仓库源码(piecewise.py、univariate_geometric_brownian_motion.py 等)与测试用例,讲解其 API 签名、内部实现、返回值语义,以及它在几何布朗运动(GBM)、Heston、Hull-White 等定价模型中的真实调用方式,帮助你掌握如何在自定义定价模型中复用这套"统一入参"范式。
函数签名与官方文档定位
该函数的官方 API 文档位于 convert_to_tensor_or_func.md,完整的调用签名为:
tf_quant_finance.math.piecewise.convert_to_tensor_or_func( x, dtype=None, name=None )文档对其功能的描述是一句话:"Returns either aPiecewiseConstantFuncor x converted to aTensor."——即:除非输入已经是PiecewiseConstantFunc类型的实例(此时原样返回),否则一律把输入转换为Tensor。其设计目的正是帮助定价模型预处理"可以是常数、也可以是随时间变化的函数"的模型参数。
在 tf-quant-finance 的模块体系中,该函数与PiecewiseConstantFunc类、find_interval_index函数一同被归入tff.math.piecewise子模块(见 piecewise.md 的模块索引),并由 math/init.py 统一导出。
参数详解
官方文档(convert_to_tensor_or_func.md)对该函数三个参数的定义如下:
| 参数 | 类型与含义 | 默认值 |
|---|---|---|
x | 要么是一个Tensor,要么是一个PiecewiseConstantFunc实例 | 必填 |
dtype | 将值转换为Tensor时使用的默认 dtype;为None时使用 TensorFlow 自行推断的默认 dtype | None |
name | Python 字符串,为创建的 ops 命名;为None时使用默认名'PiecewiseConstantFunc_tensor_or_func' | None |
从源码实现(piecewise.py 中的convert_to_tensor_or_func定义)可以确认这三个参数的底层语义:
- 参数
x是唯一决定分支走向的输入:它是PiecewiseConstantFunc实例就原样返回,否则交给tf.convert_to_tensor; - 参数
dtype会直接透传给tf.convert_to_tensor(x, dtype=dtype, name=name),因此它只在"非 PiecewiseConstantFunc 分支"生效,对已经是PiecewiseConstantFunc的输入没有影响; - 参数
name会同时作为生成的tf.Tensor的 op 名称,以及(在未指定时)作为函数内部默认命名'PiecewiseConstantFunc_tensor_or_func'。
返回值语义:(y, flag)二元组
该函数返回一个二元组(y, flag),语义如下:
y:转换后的结果,要么是Tensor,要么是原封不动的PiecewiseConstantFunc;flag(布尔标记):False表示x是PiecewiseConstantFunc类型,True表示x是普通常数输入(即被转换成了Tensor)。
这个标记是调用方后续分派逻辑的关键。例如在 GBM 的实现中,drift_is_constant()与volatility_is_constant()这两个访问器直接由该标记驱动(见 univariate_geometric_brownian_motion.py):
def drift_is_constant(self): """Returns True if the drift of the process is a constant.""" return self._mean_is_constant def volatility_is_constant(self): """Returns True is the volatility of the process is a constant.""" return self._volatility_is_constant标记为True(常数)时走_constant_fn分支、标记为False(时变)时走_piecewise_fn分支,二者都返回形如_mean * x或_mean(t) * x的可调用对象,从而做到"同一定价模型同时支持常数与时变参数"。
与 PiecewiseConstantFunc 的配合:先构造分段常数函数
理解该函数的入口条件,首先要掌握其前置类型PiecewiseConstantFunc。它同样是tff.math.piecewise的核心成员(详见 PiecewiseConstantFunc.md),构造方式为:
tf_quant_finance.math.piecewise.PiecewiseConstantFunc( jump_locations, values, dtype=None, name=None )其核心思想是:jump_locations把实数轴分割成若干区间[-inf, jump_locations[..., 0]]、[jump_locations[..., i], jump_locations[..., i+1]]、[jump_locations[..., -1], inf],函数在每一段上取values中对应的常数值。官方文档给出过一个最简单的标量示例(piecewise.py):
jump_locations = [0.1, 10] values = [3, 4, 5] piecewise_func = piecewise.PiecewiseConstantFunc(jump_locations, values, dtype=dtype) # 在 x = [0., 0.1, 2., 11.] 处求值(左连续) x = np.array([0., 0.1, 2., 11.]) value = piecewise_func(x) # 期望结果: [3, 3, 4, 5] integral = piecewise_func.integrate(x, x + 1) # 期望积分: [3.9, 4, 4, 5]要点归纳(来自 PiecewiseConstantFunc.md):
jump_locations:实数Tensor,形状为batch_shape + [num_jump_points],沿最后一维有序,允许重复值(但需用户自行保证values同步重复);values:与jump_locations同 dtype,形状为batch_shape + [num_jump_points + 1] + event_shape,区间数恰好比跳点个数多 1(对应最左侧开区间与最右侧闭区间);event_shape的存在意味着支持矩阵/向量值分段常数函数;dtype缺省时从jump_locations推断;- 构造时会校验 batch shape 与 event shape,不符时抛出
ValueError(源码 piecewise.py 的初始化逻辑中即可看到相关检查)。
由此,convert_to_tensor_or_func的两条路径正好覆盖了模型参数建模的两种典型形态:
- 常数参数:直接传 Python 标量 / numpy 数组 /
tf.Tensor,函数负责把它变成规范的Tensor; - 时变参数:先用
jump_locations+values构造出PiecewiseConstantFunc,函数识别后原样放行。
源码级实现剖析
该函数在 piecewise.py 中的实现非常简洁,核心逻辑只有三行:
def convert_to_tensor_or_func(x, dtype=None, name=None): name = name or ('PiecewiseConstantFunc_tensor_or_func') if isinstance(x, PiecewiseConstantFunc): return x, False return tf.convert_to_tensor(x, dtype=dtype, name=name), True从中可以确认几个实现事实:
- 类型判定基于
isinstance:只要x是PiecewiseConstantFunc的实例就原样返回,不做拷贝、不做 dtype 转换——这与文档中"input is returned unchanged"的描述完全一致; - 分支的代价极低:非分段常数输入仅是一次
tf.convert_to_tensor调用,整个函数没有任何多余的计算开销,因此非常适合在模型__init__中批量调用; - 标记与类型一一对应:
flag本质上是"输入是否为PiecewiseConstantFunc"的布尔反码,调用方可以用它直接驱动后续的分支选择。
值得补充的是,PiecewiseConstantFunc类在构造时还会设置一个is_piecewise_constant = True属性(见 piecewise.py)。这一"鸭子类型"标记被 Hull-White 等模型的采样框架用于识别分段常数参数:例如 vector_hull_white.py 中的_input_type与_get_times_grid逻辑会通过hasattr(param, 'is_piecewise_constant')判断参数形态,并据此把分段常数参数的跳点并入采样时间网格。这与convert_to_tensor_or_func的flag机制互为补充:前者用于构建期统一入参,后者用于采样期识别参数特征。
完整用法示例:在定价模型中预处理入参
官方文档给出的使用示例是几何布朗运动模型(piecewise.py):
class GeometricBrownianMotion(object) def __init__(self, mu, sigma): self._mu, self._mu_is_constant = piecewise.convert_to_tensor_or_func( mu) self._sigma, self._sigma_is_constant = piecewise.convert_to_tensor_or_func(sigma)而在仓库的真实实现中,这一模式被完整落地于 univariate_geometric_brownian_motion.py:
self._mean, self._mean_is_constant = pw.convert_to_tensor_or_func( mean, dtype=dtype, name='mean') self._dtype = dtype or self._mean.dtype ( self._volatility, self._volatility_is_constant ) = pw.convert_to_tensor_or_func(volatility, dtype=self._dtype, name='volatility')可以看到真实实现比文档示例多做了两件事,值得借鉴:
- 显式传递
dtype并贯通给后续参数:先对mean调用并取出其 dtype 作为self._dtype,再以self._dtype作为volatility转换的 dtype,保证两个参数类型一致; - 显式指定
name:分别为mean、volatility的转换 op 命名,便于在 TensorFlow 计算图中定位。
转换完成后,模型在积分/采样环节会依据_mean_is_constant与_volatility_is_constant标记选择计算路径。GBM 内部有一个_integrate_parameter辅助函数(见 univariate_geometric_brownian_motion.py),把"常数参数"与"分段常数参数"的积分统一成一行:
return x * (t1 - t0) if x_is_constant else x.integrate(t0, t1, name)即:常数参数直接x * (t1 - t0)解析求积;分段常数参数则调用PiecewiseConstantFunc.integrate按跳点精确积分。在_sample_paths中,mean_integral与volatility_sq_integral正是通过这个辅助函数计算,再用于构造对数增量log_increments(见 univariate_geometric_brownian_motion.py)。
测试用例印证
tf_quant_finance/math/piecewise_test.py 为该函数提供了两个针对性测试,分别覆盖两条分支:
1. 常数输入 → Tensor 分支(test_convert_to_tensor_or_func_tensors)
dtype = tf.float64 inputs = [2.0, [1, 2, 3], np.arange(1, 5, 1)] for i in inputs: x = piecewise.convert_to_tensor_or_func(i, dtype) # 校验返回值为 Tensor 且 flag 为 True output.append((tf.is_tensor(x[0]), x[1])) expected.append((True, True))该用例覆盖了 Python 标量、Python 列表、numpy 数组三类输入,断言返回值的第一个元素是tf.Tensor、flag为True。
2. 分段常数输入 → 原样返回分支(test_convert_to_tensor_or_func_PiecewiseConstantFunc)
times = np.arange(0, 10, 1) values = np.ones(11) pwc = piecewise.PiecewiseConstantFunc(times, values, dtype=dtype) output = piecewise.convert_to_tensor_or_func(pwc) expected = (pwc, False) self.assertAllEqual(output, expected)该用例构造了一个 10 个跳点、11 段取值均为 1 的PiecewiseConstantFunc,断言函数原样返回该实例且flag为False。
此外,geometric_brownian_motion_test.py 中的test_univariate_time_varying_drift_and_volatility等用例展示了PiecewiseConstantFunc与 GBM 模型联动的端到端效果:用np.sin、np.cos采样生成时变漂移与波动率序列,构造分段常数函数后传入GeometricBrownianMotion,再验证drift_fn/volatility_fn的输出与直接对分段函数求值一致。这从侧面验证了convert_to_tensor_or_func的flag标记能正确引导模型选择时变分支。
典型应用场景总结
综合源码与测试,该函数在 tf-quant-finance 中的典型应用场景包括:
- GBM(几何布朗运动):
mean与volatility均支持常数Tensor或PiecewiseConstantFunc,见 univariate_geometric_brownian_motion.py; - Heston 模型:
mean_reversion、theta、volvol、rho等参数同样接受_CallableOrTensor形式的输入,其中分段常数形态由tff.math.piecewise.PiecewiseConstantFunc表达,见 heston_model.py 中的示例(volvol = tff.math.piecewise.PiecewiseConstantFunc(jump_locations=[0.5], values=[1, 1.1], dtype=np.float64)); - Hull-White 模型族:
mean_reversion、volatility参数要求"带有is_piecewise_constant属性的PiecewiseConstantFunc",其采样框架进一步利用跳点构造时间网格,见 vector_hull_white.py 与 calibration.py; - HJM / 零息债券期权等:波动率函数同样可用分段常数函数刻画,见 gaussian_hjm.py 及对应测试。
实践建议
- 在自定义定价模型的
__init__中尽早调用:把convert_to_tensor_or_func的输出直接存为self._param与self._param_is_constant,后续所有逻辑(求值、积分、采样、校准)统一按flag分派,可显著降低分支复杂度; - 保持 dtype 贯通:如 GBM 实现那样,先用第一个参数确定
self._dtype,再传给后续参数,避免float32/float64混用导致的隐性类型转换; - 为每个参数指定
name:便于在计算图可视化与调试时区分不同参数的转换节点; - 注意构造
PiecewiseConstantFunc时的 shape 约束:values的分段数必须是num_jump_points + 1,batch shape 需与jump_locations一致,否则初始化会抛ValueError(可由 piecewise_test.py 中test_invalid_jump_batch_shape、test_invalid_value_event_shape两个用例印证)。
延伸阅读
- PiecewiseConstantFunc API 文档:分段常数函数的构造与
__call__/integrate方法; - piecewise 模块 API 文档:
PiecewiseConstantFunc、convert_to_tensor_or_func、find_interval_index三者总览; - piecewise.py 源码:本函数及
PiecewiseConstantFunc的完整实现; - piecewise_test.py:两个分支的针对性测试用例;
- univariate_geometric_brownian_motion.py:
convert_to_tensor_or_func在生产模型中的真实调用范例。
- 金融科技
- 科学计算
【免费下载链接】tf-quant-finance
High-performance TensorFlow library for quantitative finance.
相关推荐
tf-quant-finance 中分段常数函数 PiecewiseConstantFunc 的求值与积分实战指南
tf quant finance 中分段常数函数 PiecewiseConstantFunc 的求值与积分实战指南 本文围绕 tf quant finance
金融科技科学计算tf-quant-finance 中 LSM 回归基函数 make_polynomial_basis 的原理与实战
tf quant finance 中 LSM 回归基函数 make_polynomial_basis 的原理与实战 本篇以 tf_quant_finance.m
金融科技科学计算tf-quant-finance 的 HestonModel:分段常数参数随机波动率模型的构建、路径模拟与定价实践
tf quant finance 的 HestonModel:分段常数参数随机波动率模型的构建、路径模拟与定价实践 导读 本文围绕 tf quant finan
金融科技科学计算
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考