@@ -4123,66 +4123,55 @@ def matmul(x1: "ArrayLike", x2: "ArrayLike", dtype: Optional["DTypeLike"] = None
4123
4123
4124
4124
4125
4125
def vecdot (
4126
- x1 : "ArrayLike" ,
4127
- x2 : "ArrayLike" ,
4128
- axis : int = - 1 ,
4126
+ x1 : "TensorLike" ,
4127
+ x2 : "TensorLike" ,
4129
4128
dtype : Optional ["DTypeLike" ] = None ,
4130
- ):
4131
- """Compute the dot product of two vectors along specified dimensions .
4129
+ ) -> "TensorVariable" :
4130
+ """Compute the vector dot product of two arrays .
4132
4131
4133
4132
Parameters
4134
4133
----------
4135
4134
x1, x2
4136
- Input arrays, scalars not allowed.
4137
- axis
4138
- The axis along which to compute the dot product. By default, the last
4139
- axes of the inputs are used.
4135
+ Input arrays with the same shape.
4140
4136
dtype
4141
- The desired data-type for the array . If not given, then the type will
4137
+ The desired data-type for the result . If not given, then the type will
4142
4138
be determined as the minimum type required to hold the objects in the
4143
4139
sequence.
4144
4140
4145
4141
Returns
4146
4142
-------
4147
- out : ndarray
4148
- The vector dot product of the inputs computed along the specified axes .
4143
+ TensorVariable
4144
+ The vector dot product of the inputs.
4149
4145
4150
4146
Notes
4151
4147
-----
4152
- This is similar to `dot` but with broadcasting. It computes the dot product
4153
- along the specified axes, treating these as vectors, and broadcasts across
4154
- the remaining axes.
4148
+ This is similar to `np.vecdot` and computes the dot product of
4149
+ vectors along the last axis of both inputs. Broadcasting is supported
4150
+ across all other dimensions.
4151
+
4152
+ Examples
4153
+ --------
4154
+ >>> import pytensor.tensor as pt
4155
+ >>> x = pt.matrix("x")
4156
+ >>> y = pt.matrix("y")
4157
+ >>> z = pt.vecdot(x, y)
4158
+ >>> # Equivalent to np.sum(x * y, axis=-1)
4155
4159
"""
4156
4160
x1 = as_tensor_variable (x1 )
4157
4161
x2 = as_tensor_variable (x2 )
4158
4162
4159
- # Handle negative axis
4160
- if axis < 0 :
4161
- x1_axis = axis % x1 .type .ndim
4162
- x2_axis = axis % x2 .type .ndim
4163
- else :
4164
- x1_axis = axis
4165
- x2_axis = axis
4166
-
4167
- # Move the axes to the end for dot product calculation
4168
- x1_perm = list (range (x1 .type .ndim ))
4169
- x1_perm .append (x1_perm .pop (x1_axis ))
4170
- x1_transposed = x1 .transpose (x1_perm )
4171
-
4172
- x2_perm = list (range (x2 .type .ndim ))
4173
- x2_perm .append (x2_perm .pop (x2_axis ))
4174
- x2_transposed = x2 .transpose (x2_perm )
4175
-
4176
- # Use the inner product operation
4177
- out = _inner_prod (x1_transposed , x2_transposed )
4163
+ # Use the inner product operation along the last axis
4164
+ out = _inner_prod (x1 , x2 )
4178
4165
4179
4166
if dtype is not None :
4180
4167
out = out .astype (dtype )
4181
4168
4182
4169
return out
4183
4170
4184
4171
4185
- def matvec (x1 : "ArrayLike" , x2 : "ArrayLike" , dtype : Optional ["DTypeLike" ] = None ):
4172
+ def matvec (
4173
+ x1 : "TensorLike" , x2 : "TensorLike" , dtype : Optional ["DTypeLike" ] = None
4174
+ ) -> "TensorVariable" :
4186
4175
"""Compute the matrix-vector product.
4187
4176
4188
4177
Parameters
@@ -4192,20 +4181,35 @@ def matvec(x1: "ArrayLike", x2: "ArrayLike", dtype: Optional["DTypeLike"] = None
4192
4181
x2
4193
4182
Input array for the vector with shape (..., K).
4194
4183
dtype
4195
- The desired data-type for the array . If not given, then the type will
4184
+ The desired data-type for the result . If not given, then the type will
4196
4185
be determined as the minimum type required to hold the objects in the
4197
4186
sequence.
4198
4187
4199
4188
Returns
4200
4189
-------
4201
- out : ndarray
4190
+ TensorVariable
4202
4191
The matrix-vector product with shape (..., M).
4203
4192
4204
4193
Notes
4205
4194
-----
4206
- This is similar to `matmul` where the second argument is a vector,
4207
- but with different broadcasting rules. Broadcasting happens over all but
4208
- the last dimension of x1 and all dimensions of x2 except the last.
4195
+ This is equivalent to `numpy.matmul` where the second argument is a vector,
4196
+ but with more intuitive broadcasting rules. Broadcasting happens over all but
4197
+ the last two dimensions of x1 and all dimensions of x2 except the last.
4198
+
4199
+ Examples
4200
+ --------
4201
+ >>> import pytensor.tensor as pt
4202
+ >>> import numpy as np
4203
+ >>> # Matrix-vector product
4204
+ >>> A = pt.matrix("A") # shape (M, K)
4205
+ >>> v = pt.vector("v") # shape (K,)
4206
+ >>> result = pt.matvec(A, v) # shape (M,)
4207
+ >>> # Equivalent to np.matmul(A, v)
4208
+ >>>
4209
+ >>> # Batched matrix-vector product
4210
+ >>> batched_A = pt.tensor3("A") # shape (B, M, K)
4211
+ >>> batched_v = pt.matrix("v") # shape (B, K)
4212
+ >>> result = pt.matvec(batched_A, batched_v) # shape (B, M)
4209
4213
"""
4210
4214
x1 = as_tensor_variable (x1 )
4211
4215
x2 = as_tensor_variable (x2 )
@@ -4218,7 +4222,9 @@ def matvec(x1: "ArrayLike", x2: "ArrayLike", dtype: Optional["DTypeLike"] = None
4218
4222
return out
4219
4223
4220
4224
4221
- def vecmat (x1 : "ArrayLike" , x2 : "ArrayLike" , dtype : Optional ["DTypeLike" ] = None ):
4225
+ def vecmat (
4226
+ x1 : "TensorLike" , x2 : "TensorLike" , dtype : Optional ["DTypeLike" ] = None
4227
+ ) -> "TensorVariable" :
4222
4228
"""Compute the vector-matrix product.
4223
4229
4224
4230
Parameters
@@ -4228,20 +4234,35 @@ def vecmat(x1: "ArrayLike", x2: "ArrayLike", dtype: Optional["DTypeLike"] = None
4228
4234
x2
4229
4235
Input array for the matrix with shape (..., K, N).
4230
4236
dtype
4231
- The desired data-type for the array . If not given, then the type will
4237
+ The desired data-type for the result . If not given, then the type will
4232
4238
be determined as the minimum type required to hold the objects in the
4233
4239
sequence.
4234
4240
4235
4241
Returns
4236
4242
-------
4237
- out : ndarray
4243
+ TensorVariable
4238
4244
The vector-matrix product with shape (..., N).
4239
4245
4240
4246
Notes
4241
4247
-----
4242
- This is similar to `matmul` where the first argument is a vector,
4243
- but with different broadcasting rules. Broadcasting happens over all but
4248
+ This is equivalent to `numpy. matmul` where the first argument is a vector,
4249
+ but with more intuitive broadcasting rules. Broadcasting happens over all but
4244
4250
the last dimension of x1 and all but the last two dimensions of x2.
4251
+
4252
+ Examples
4253
+ --------
4254
+ >>> import pytensor.tensor as pt
4255
+ >>> import numpy as np
4256
+ >>> # Vector-matrix product
4257
+ >>> v = pt.vector("v") # shape (K,)
4258
+ >>> A = pt.matrix("A") # shape (K, N)
4259
+ >>> result = pt.vecmat(v, A) # shape (N,)
4260
+ >>> # Equivalent to np.matmul(v, A)
4261
+ >>>
4262
+ >>> # Batched vector-matrix product
4263
+ >>> batched_v = pt.matrix("v") # shape (B, K)
4264
+ >>> batched_A = pt.tensor3("A") # shape (B, K, N)
4265
+ >>> result = pt.vecmat(batched_v, batched_A) # shape (B, N)
4245
4266
"""
4246
4267
x1 = as_tensor_variable (x1 )
4247
4268
x2 = as_tensor_variable (x2 )
0 commit comments