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
//! Tensor shape manipulation operations
//!
//! This module provides functions for ensuring tensors have minimum dimensionality
//! and manipulating tensor shapes while preserving data. These operations are
//! essential for broadcasting compatibility and shape consistency in tensor operations.
use Result as TorshResult;
use Tensor;
/// Ensure tensor has at least 1 dimension
///
/// ## Mathematical Background
///
/// Converts scalar tensors (0-dimensional) to 1-dimensional tensors by adding
/// a dimension of size 1. This operation preserves all data while ensuring
/// the tensor can participate in operations requiring at least 1 dimension.
///
/// ## Shape Transformations
/// ```text
/// () → (1,) # Scalar to 1D
/// (n,) → (n,) # 1D unchanged
/// (m,n) → (m,n) # Higher dimensions unchanged
/// ```text
///
/// ## Broadcasting Compatibility
///
/// Many tensor operations require inputs to have compatible shapes for broadcasting.
/// The `atleast_1d` function ensures tensors can participate in element-wise operations:
///
/// ```text
/// scalar + vector # Requires scalar to be at least 1D
/// 0D + 1D → 1D + 1D → broadcasting possible
/// ```text
///
/// ## Parameters
/// * `tensor` - Input tensor of any dimensionality
///
/// ## Returns
/// * Tensor with at least 1 dimension, preserving all data
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::atleast_1d;
/// # use torsh_tensor::creation::{scalar, ones};
/// let scalar = scalar(5.0)?; // Shape: ()
/// let vector = atleast_1d(&scalar)?; // Shape: (1,)
///
/// let existing = ones(&[3])?; // Shape: (3,)
/// let unchanged = atleast_1d(&existing)?; // Shape: (3,) - no change
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **Broadcasting preparation**: Ensure compatibility with vector operations
/// - **API consistency**: Standardize inputs to expect at least 1D
/// - **Neural networks**: Batch dimension handling
/// - **Linear algebra**: Vector-matrix operation preparation
/// Ensure tensor has at least 2 dimensions
///
/// ## Mathematical Background
///
/// Converts tensors with fewer than 2 dimensions to 2-dimensional tensors
/// by adding dimensions of size 1. This is essential for matrix operations
/// which require 2D inputs.
///
/// ## Shape Transformations
/// ```text
/// () → (1,1) # Scalar to 2D
/// (n,) → (n,1) # Vector to column matrix
/// (m,n) → (m,n) # Matrix unchanged
/// (l,m,n) → (l,m,n) # Higher dimensions unchanged
/// ```text
///
/// ## Matrix Operation Compatibility
///
/// Many linear algebra operations require 2D inputs:
/// - **Matrix multiplication**: A @ B requires both A and B to be 2D
/// - **Linear systems**: Solving Ax = b requires A to be 2D
/// - **Decompositions**: SVD, QR, LU require 2D matrices
///
/// ## Column Vector Convention
///
/// 1D tensors are converted to column vectors (n,1) following the convention
/// that vectors are treated as column matrices in linear algebra:
///
/// ```text
/// vector: (n,) → column matrix: (n,1)
/// ```text
///
/// ## Parameters
/// * `tensor` - Input tensor of any dimensionality
///
/// ## Returns
/// * Tensor with at least 2 dimensions, preserving all data
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::atleast_2d;
/// # use torsh_tensor::creation::{scalar, ones};
/// let scalar = scalar(5.0)?; // Shape: ()
/// let matrix = atleast_2d(&scalar)?; // Shape: (1,1)
///
/// let vector = ones(&[3])?; // Shape: (3,)
/// let column = atleast_2d(&vector)?; // Shape: (3,1)
///
/// let existing = ones(&[2, 4])?; // Shape: (2,4)
/// let unchanged = atleast_2d(&existing)?; // Shape: (2,4) - no change
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **Linear algebra**: Prepare vectors for matrix operations
/// - **Neural networks**: Ensure weight matrices are 2D
/// - **Image processing**: Treat 1D signals as single-row images
/// - **Batch operations**: Prepare single samples for batch processing
/// Ensure tensor has at least 3 dimensions
///
/// ## Mathematical Background
///
/// Converts tensors with fewer than 3 dimensions to 3-dimensional tensors
/// by adding dimensions of size 1. This is essential for operations requiring
/// 3D inputs such as 3D convolutions, volume processing, or batch operations.
///
/// ## Shape Transformations
/// ```text
/// () → (1,1,1) # Scalar to 3D
/// (n,) → (n,1,1) # Vector to 3D
/// (m,n) → (m,n,1) # Matrix to 3D
/// (l,m,n) → (l,m,n) # 3D unchanged
/// (k,l,m,n) → (k,l,m,n) # Higher dimensions unchanged
/// ```text
///
/// ## Batch Processing Convention
///
/// The added dimensions follow the convention (batch, height, width) or
/// (batch, channels, spatial) for compatibility with deep learning frameworks:
///
/// ```text
/// 1D signal: (n,) → (n,1,1) # n samples, 1x1 spatial
/// 2D image: (h,w) → (h,w,1) # h×w image, 1 channel
/// ```text
///
/// ## 3D Operation Compatibility
///
/// Many operations require 3D inputs:
/// - **3D convolutions**: Conv3D requires (batch, channels, depth, height, width)
/// - **Volume processing**: Medical imaging, 3D computer vision
/// - **Sequence modeling**: (batch, sequence, features)
/// - **Batch operations**: Adding batch dimension for single samples
///
/// ## Parameters
/// * `tensor` - Input tensor of any dimensionality
///
/// ## Returns
/// * Tensor with at least 3 dimensions, preserving all data
///
/// ## Example
/// ```rust
/// # use torsh_functional::manipulation::atleast_3d;
/// # use torsh_tensor::creation::{scalar, ones};
/// let scalar = scalar(5.0)?; // Shape: ()
/// let volume = atleast_3d(&scalar)?; // Shape: (1,1,1)
///
/// let vector = ones(&[5])?; // Shape: (5,)
/// let volume_vec = atleast_3d(&vector)?; // Shape: (5,1,1)
///
/// let matrix = ones(&[3, 4])?; // Shape: (3,4)
/// let volume_mat = atleast_3d(&matrix)?; // Shape: (3,4,1)
///
/// let existing = ones(&[2, 3, 4])?; // Shape: (2,3,4)
/// let unchanged = atleast_3d(&existing)?; // Shape: (2,3,4) - no change
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```text
///
/// ## Applications
/// - **3D computer vision**: Prepare 2D images for 3D processing
/// - **Deep learning**: Add batch/channel dimensions
/// - **Scientific computing**: Volume and tensor field operations
/// - **Signal processing**: Multi-dimensional signal analysis
/// - **Medical imaging**: 3D volume reconstruction and analysis