1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
//! Tensor construction operations
//!
//! This module provides functions for constructing new tensors from existing ones
//! through operations like block diagonal matrices, Cartesian products, and
//! coordinate grids. These operations are fundamental for creating structured
//! tensors and coordinate systems in scientific computing and machine learning.
use ;
use ;
use atleast_2d;
/// Create a block diagonal matrix from input tensors
///
/// ## Mathematical Background
///
/// A block diagonal matrix is a matrix where the non-zero elements are confined
/// to square blocks along the main diagonal:
///
/// ```text
/// A = [ A₁ 0 0 ]
/// [ 0 A₂ 0 ]
/// [ 0 0 A₃ ]
/// ```text
///
/// Each block Aᵢ can be a scalar, vector, or matrix. The resulting matrix has:
/// - **Size**: (∑ mᵢ) × (∑ nᵢ) where Aᵢ is mᵢ × nᵢ
/// - **Structure**: Only diagonal blocks contain non-zero elements
/// - **Determinant**: det(A) = ∏ det(Aᵢ) (product of block determinants)
///
/// ## Matrix Properties
///
/// Block diagonal matrices preserve many algebraic properties:
/// - **Multiplication**: (A ⊕ B)(C ⊕ D) = AC ⊕ BD (when compatible)
/// - **Inverse**: (A₁ ⊕ A₂)⁻¹ = A₁⁻¹ ⊕ A₂⁻¹ (when blocks are invertible)
/// - **Eigenvalues**: λ(A₁ ⊕ A₂) = λ(A₁) ∪ λ(A₂) (union of eigenvalues)
/// - **Trace**: tr(A₁ ⊕ A₂) = tr(A₁) + tr(A₂)
///
/// ## Implementation Details
///
/// The function automatically promotes inputs to 2D:
/// - Scalars (0D) → 1×1 matrices
/// - Vectors (1D) → column vectors (n×1)
/// - Matrices (2D) → unchanged
///
/// ## Parameters
/// * `tensors` - Slice of tensors to arrange in block diagonal form
///
/// ## Returns
/// * Block diagonal matrix with input tensors along the main diagonal
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::block_diag;
/// # use torsh_tensor::creation::{scalar, ones, eye};
/// let scalar = scalar(3.0)?; // Will become 1×1 block
/// let vector = ones(&[2])?; // Will become 2×1 block
/// let matrix = eye(3)?; // Will become 3×3 block
///
/// let result = block_diag(&[scalar, vector, matrix])?;
/// // Result shape: (6, 5) with structure:
/// // [ 3 0 0 0 0 ]
/// // [ 0 1 0 0 0 ]
/// // [ 0 1 0 0 0 ]
/// // [ 0 0 1 0 0 ]
/// // [ 0 0 0 1 0 ]
/// // [ 0 0 0 0 1 ]
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **Linear systems**: Decoupled system representation
/// - **Control theory**: Multi-input multi-output systems
/// - **Graph theory**: Adjacency matrices of disconnected components
/// - **Neural networks**: Architecture design with independent blocks
/// - **Optimization**: Separable problem formulations
/// Compute the Cartesian product of input tensors
///
/// ## Mathematical Background
///
/// The Cartesian product A × B × ... creates all possible combinations where
/// each element comes from a different set:
///
/// ```text
/// A × B = {(a,b) : a ∈ A, b ∈ B}
/// ```text
///
/// For tensors, this creates a matrix where each row represents one combination.
///
/// ## Combinatorial Properties
///
/// For sets of sizes |A₁|, |A₂|, ..., |Aₙ|:
/// - **Output size**: |A₁| × |A₂| × ... × |Aₙ| combinations
/// - **Output shape**: (∏ᵢ |Aᵢ|) × n where n is number of input tensors
/// - **Ordering**: Lexicographic ordering of combinations
///
/// ## Generation Algorithm
///
/// Uses counter-based generation:
/// 1. Initialize counters [0, 0, ..., 0]
/// 2. For each row, use current counter values as indices
/// 3. Increment counters in lexicographic order
/// 4. Repeat until all combinations generated
///
/// ## Parameters
/// * `tensors` - Slice of tensors to compute Cartesian product
///
/// ## Returns
/// * Matrix where each row is one combination from the Cartesian product
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::cartesian_prod;
/// # use torsh_tensor::creation::tensor;
/// let a = tensor(&[1.0, 2.0])?; // Set A = {1, 2}
/// let b = tensor(&[10.0, 20.0])?; // Set B = {10, 20}
///
/// let product = cartesian_prod(&[a, b])?;
/// // Result shape: (4, 2) with combinations:
/// // [ 1, 10 ] # (1, 10)
/// // [ 1, 20 ] # (1, 20)
/// // [ 2, 10 ] # (2, 10)
/// // [ 2, 20 ] # (2, 20)
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **Parameter grids**: Generate all parameter combinations for experiments
/// - **Coordinate systems**: Create discrete coordinate grids
/// - **Combinatorial optimization**: Enumerate solution space
/// - **Statistical sampling**: Factorial design experiments
/// - **Machine learning**: Hyperparameter grid search
/// Create coordinate matrices from coordinate vectors
///
/// ## Mathematical Background
///
/// Meshgrid creates coordinate matrices for evaluating functions on grids.
/// Given coordinate vectors x, y, ..., it produces arrays X, Y, ... where
/// each array contains coordinates for one dimension at every grid point.
///
/// For 2D case with x ∈ ℝᵐ and y ∈ ℝⁿ:
/// ```text
/// X[i,j] = x[j] (x-coordinates at each point)
/// Y[i,j] = y[i] (y-coordinates at each point)
/// ```text
///
/// ## Indexing Conventions
///
/// ### Matrix Indexing ('ij')
/// - **X[i,j] = x[j]**: X varies along columns (dimension 1)
/// - **Y[i,j] = y[i]**: Y varies along rows (dimension 0)
/// - **Convention**: Matches array indexing (row, column)
///
/// ### Cartesian Indexing ('xy')
/// - **X[i,j] = x[i]**: X varies along rows (dimension 0)
/// - **Y[i,j] = y[j]**: Y varies along columns (dimension 1)
/// - **Convention**: Matches mathematical (x, y) convention
///
/// ## Grid Structure
///
/// For vectors x = [x₁, x₂, ...] and y = [y₁, y₂, ...]:
///
/// Matrix indexing ('ij'):
/// ```text
/// X = [ x₁ x₂ x₃ ] Y = [ y₁ y₁ y₁ ]
/// [ x₁ x₂ x₃ ] [ y₂ y₂ y₂ ]
/// [ x₁ x₂ x₃ ] [ y₃ y₃ y₃ ]
/// ```text
///
/// Cartesian indexing ('xy'):
/// ```text
/// X = [ x₁ x₁ x₁ ] Y = [ y₁ y₂ y₃ ]
/// [ x₂ x₂ x₂ ] [ y₁ y₂ y₃ ]
/// [ x₃ x₃ x₃ ] [ y₁ y₂ y₃ ]
/// ```text
///
/// ## Parameters
/// * `tensors` - Coordinate vectors (1D tensors)
/// * `indexing` - Either "ij" (matrix) or "xy" (Cartesian) indexing
///
/// ## Returns
/// * Vector of coordinate grids, one for each input dimension
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::meshgrid;
/// # use torsh_tensor::creation::tensor;
/// let x = tensor(&[1.0, 2.0, 3.0])?;
/// let y = tensor(&[10.0, 20.0])?;
///
/// let grids = meshgrid(&[x, y], "ij")?;
/// let (x_grid, y_grid) = (&grids[0], &grids[1]);
/// // x_grid: [[1, 2, 3], y_grid: [[10, 10, 10],
/// // [1, 2, 3]] [20, 20, 20]]
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **Function evaluation**: Evaluate f(x,y) on regular grids
/// - **Numerical methods**: Finite difference discretization
/// - **Visualization**: Create coordinate systems for plotting
/// - **Image processing**: Pixel coordinate generation
/// - **Scientific computing**: Physical simulation grids
/// - **Interpolation**: Define evaluation points for splines