Feature Request: Add a `torch.range_map` operator for easy value range mapping

songyuc: <p>Dear PyTorch Community,</p>
<p>I am writing to propose the addition of a new operator to PyTorch: <code>torch.range_map</code>. This operator would provide a convenient and efficient way to map the values of a tensor from an arbitrary range to a specified <code>[min_val, max_val]</code> range.</p>
<p><strong>Proposed Operator: <code>torch.range_map</code></strong></p>
<ul>
<li>
<p><strong>Functionality:</strong>  This operator would take an input tensor <code>x</code> and map its values to a target range defined by <code>min_val</code> and <code>max_val</code>.  The mapping can be performed using different methods, specified by the <code>mapping_type</code> parameter.</p>
</li>
<li>
<p><strong>Parameters:</strong></p>
<ul>
<li><code>x</code> (Tensor): The input tensor to be range-mapped.</li>
<li><code>min_val</code> (float): The minimum value of the target range.</li>
<li><code>max_val</code> (float): The maximum value of the target range.</li>
<li><code>mapping_type</code> (str, optional, default: <code>'tanh'</code> or <code>'linear'</code>):  Specifies the type of mapping to be used.  Possible values could include:
<ul>
<li><code>'linear'</code>: Linear scaling to the target range.</li>
<li><code>'sigmoid'</code>:  Mapping using the sigmoid function, then scaled to the target range.</li>
<li><code>'tanh'</code>: Mapping using the tanh function, then scaled to the target range.</li>
<li>(Potentially other mapping types as needed)</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Return Value:</strong>  A tensor with the same shape as <code>x</code>, where the values have been mapped to the <code>[min_val, max_val]</code> range.</p>
</li>
</ul>
<p><strong>Example Use Case and Code Comparison:</strong></p>
<p>Currently, to perform range mapping, users often need to manually implement the logic using basic PyTorch operators. For example, to map to the range [-1, 1] using <code>tanh</code>, one might write:</p>
<pre data-code-wrap="python"><code class="lang-python">import torch

def manual_tanh_range_map(x, min_val, max_val):
    return ((max_val - min_val) / 2) * torch.tanh(x) + ((max_val + min_val) / 2)

x = torch.randn(5)
min_value = -5.0
max_value = 10.0

manual_result = manual_tanh_range_map(x, min_value, max_value)
print("Manual result:", manual_result)
</code></pre>
<p>With the proposed <code>torch.range_map</code> operator, the code would become much cleaner and more readable:</p>
<pre data-code-wrap="python"><code class="lang-python">import torch

def proposed_range_map(x, min_val, max_val):
    return torch.range_map(x, min_val, max_val, mapping_type='tanh') # Assuming torch.range_map exists

x = torch.randn(5)
min_value = -5.0
max_value = 10.0

proposed_result = proposed_range_map(x, min_value, max_value) # Assuming torch.range_map exists
print("Proposed result:", proposed_result)
</code></pre>
<p><strong>Reasons for Adding <code>torch.range_map</code>:</strong></p>
<ul>
<li><strong>Improved Code Readability and Conciseness:</strong>  A dedicated <code>torch.range_map</code> operator would significantly improve the readability and conciseness of code that involves range mapping, making it easier to understand and maintain.</li>
<li><strong>Potential Performance Optimization:</strong> While manual implementations are already efficient, a dedicated operator could potentially be further optimized at the C++/CUDA level by the PyTorch team, leading to slight performance improvements.</li>
<li><strong>Lower Learning Curve for Beginners:</strong>  For users new to PyTorch, a dedicated operator would make range mapping more discoverable and easier to use, reducing the learning curve.</li>
<li><strong>Value in Various Domains:</strong> Range mapping is a common operation in various domains, including:
<ul>
<li><strong>Reinforcement Learning:</strong>  Normalizing action spaces or state features.</li>
<li><strong>Numerical Simulation:</strong>  Scaling physical quantities to appropriate ranges.</li>
<li><strong>Data Preprocessing:</strong>  Feature scaling and normalization.</li>
</ul>
</li>
</ul>
<p><strong>Acknowledging Existing Alternatives:</strong></p>
<p>I understand that range mapping can already be achieved using existing PyTorch operators. However, I believe that a dedicated <code>torch.range_map</code> operator would offer significant convenience and clarity, justifying its addition to the library.</p>
<p><strong>Open for Discussion and Feedback:</strong></p>
<p>I would love to hear the community’s thoughts on this proposal.</p>
<ul>
<li>Do you think a <code>torch.range_map</code> operator would be a useful addition to PyTorch?</li>
<li>In what scenarios would you find this operator helpful?</li>
<li>Do you have any suggestions for the API design, such as parameter names, default values, or supported <code>mapping_type</code> options?</li>
<li>Are there alternative approaches or existing PyTorch functionalities that could achieve similar results with better efficiency or flexibility?</li>
</ul>
<p>Thank you for your time and consideration. I look forward to your feedback and a fruitful discussion.</p>
<p>Sincerely,<br>
Yucheng Song</p>

KFrank: <p>Hi Yucheng!</p>
<aside class="quote no-group" data-username="songyuc" data-post="1" data-topic="217317">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/s/a698b9/48.png" class="avatar"> songyuc:</div>
<blockquote>
<ul>
<li><code>'linear'</code>: Linear scaling to the target range.</li>
</ul>
</blockquote>
</aside>
<p>Would this map the minimum value occurring in <code>x</code> to <code>min_val</code> and the maximum<br>
value of <code>x</code> to<code>max_val</code>?</p>
<aside class="quote no-group">
<blockquote>
<ul>
<li><code>'sigmoid'</code>: Mapping using the sigmoid function, then scaled to the target range.</li>
<li><code>'tanh'</code>: Mapping using the tanh function, then scaled to the target range.</li>
</ul>
</blockquote>
</aside>
<p>Would there be any substantive difference between these two?  After linear scaling of<br>
the output of <code>sigmoid()</code> or <code>tanh()</code> to the target range, <code>sigmoid (x)</code> is essentially<br>
the same as <code>tanh (x / 2)</code>.</p>
<aside class="quote no-group">
<blockquote>
<p>I understand that range mapping can already be achieved using existing PyTorch operators.</p>
</blockquote>
</aside>
<p>Would it be reasonable for a non-expert member of the pytorch community (perhaps<br>
even you) to write a “reference implementation” of <code>range_map()</code> in python (using, of<br>
course, pytorch tensor operations called from python)?</p>
<p>This would get you three out of your four “Reasons for Adding,” with “Potential<br>
Performance Optimization” being addressed (probably by pytorch experts) in a<br>
second phase after the reference implementation had stabilized and proved its worth.</p>
<p>This request seems reasonable to me (although I haven’t missed having a built-in<br>
<code>range_map()</code>).  Perhaps you could file a feature-request issue on the pytorch github<br>
and see how much interest it attracts.</p>
<p>Best.</p>
<p>K. Frank</p>