Logarithm of a sparse tensor

tomsch420: <p>Hello,<br>
I am currently building a layered version of probabilistic circuits and for that I have to represent weighted edges using a tensor. In order to reduce memory consumption i would like to use a sparse tensor for that. However, i find it very difficult to work with those. For instance, the logarithm of a sparse tensor is not supported. Is there anyway that I can access/update elements of a sparse tensor in a nice way?</p>
<p>I already read into the torch_sparse package, but didn’t find the things I seek there.</p>
<p>Thanks in advance!</p>

KFrank: <p>Hi Tom!</p>
<aside class="quote no-group" data-username="tomsch420" data-post="1" data-topic="206958" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/tomsch420/48/71698_2.png" class="avatar"> tomsch420:</div>
<blockquote>
<p>the logarithm of a sparse tensor is not supported.</p>
</blockquote>
</aside>
<p>Indeed, <code>.log()</code> is not implemented for sparse tensors.</p>
<p>Note that <code>.log()</code> does not map <code>0.0</code> to <code>0.0</code> (it maps it to <code>-inf</code>), so it<br>
doesn’t preserve a tensor’s sparsity.  Not implementing it for sparse<br>
tensors would therefore seem to be a legitimate design choice.</p>
<p>It appears (by examination of a handful of such operations) that<br>
element-wise operations that do not map <code>0.0</code> to <code>0.0</code> are left<br>
unimplemented for sparse tensors.  For example, <code>.exp()</code> and<br>
<code>.cos()</code> are not implemented, while <code>.sin()</code> and <code>.sqrt()</code> are.</p>
<p>Best.</p>
<p>K. Frank</p>

tomsch420: <p>Hey Frank, thanks for the answer, I think you are right!<br>
Is there an efficient way on how to do it anyway? In my Case the, the existence of Elements in the sparse Tensor will Not Change ever. I already figured Out that one can modify the values by using the Output of .values() directly and constructing a new sparse Tensor. However, I belief this is fairly ineffiecent. Do you know another way?</p>
<p>Best,<br>
Tom</p>

KFrank: <p>Hi Tom!</p>
<aside class="quote no-group" data-username="tomsch420" data-post="3" data-topic="206958" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/tomsch420/48/71698_2.png" class="avatar"> tomsch420:</div>
<blockquote>
<p>In my Case the, the existence of Elements in the sparse Tensor will Not Change ever.</p>
</blockquote>
</aside>
<p>Well, if you say so.</p>
<p>But what, logically, do you want the semantics of <code>my_sparse.log()</code><br>
to be?  <code>log (0.0)</code> is not <code>0.0</code>, so how would it make sense for it to<br>
stay zero?</p>
<p>Or, if you want to say that <code>-inf</code> somehow doesn’t count, what would<br>
you want the semantics of <code>my_sparse.cos()</code> to be?</p>
<aside class="quote no-group">
<blockquote>
<p>I belief this is fairly ineffiecent.</p>
</blockquote>
</aside>
<p>You can modify <code>.values()</code> inplace:  Consider:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; torch.__version__
'2.3.1'
&gt;&gt;&gt; my_dense = torch.arange (-1.0, 1.1, 0.5)
&gt;&gt;&gt; my_dense.cos()
tensor([0.5403, 0.8776, 1.0000, 0.8776, 0.5403])
&gt;&gt;&gt; my_sparse = my_dense.to_sparse()
&gt;&gt;&gt; my_sparse
tensor(indices=tensor([[0, 1, 3, 4]]),
       values=tensor([-1.0000, -0.5000,  0.5000,  1.0000]),
       size=(5,), nnz=4, layout=torch.sparse_coo)
&gt;&gt;&gt; my_sparse.values().cos_()
tensor([0.5403, 0.8776, 0.8776, 0.5403])
&gt;&gt;&gt; my_sparse.to_dense()
tensor([0.5403, 0.8776, 0.0000, 0.8776, 0.5403])
</code></pre>
<p>Best.</p>
<p>K. Frank</p>

tomsch420: <p>Thanks, I wasn’t aware of the inplace version of the API. This solved many of my problems.</p>