renumbering values to be consecutive - loops

I am working with bioinformatics data. I have a sequence of repetitive numbers that are nonconsecutive in nature. I am trying to find a simple way to renumber them so that they are consecutive.
Ex:
old: 1 1 1 2 2 3 3 5 5 7 7 7 9 9
Desire change
new: 1 1 1 2 2 3 3 4 4 5 5 5 6 6
I'm using R.

One way you can solve this is by using a for loop and keeping track of the current number you are inserting and the value you are replacing.
vec <- c(1, 1, 1, 2, 2, 3, 3, 5, 5, 7, 7, 7, 9, 9)
curr <- vec[1]
rep <- vec[1]
for(i in 1:length(vec)) {
if(vec[i] > rep) {
rep <- vec[i]
curr <- curr + 1
}
if(vec[i] > curr) {
vec[i] <- curr
}
}
# Print the results
for(val in vec) {
print(val)
}
This solution assumes that the numbers are already sorted. If not, you can use the sort method.

Related

The inverse operation of tensor circular unfolding in Julia

I implemented Tensor Circular Unfolding (TCU) defined in this document (See Definition 2).
The TCU reshapes a tensor (or multidimensional array) X into a matrix (or two-dimensional array). By using TensorToolbox, I implemented that as follows:
using TensorToolbox
function TCU(X,d,k)
N = ndims(X)
#assert d < N
if d <= k
a = k-d+1
else
a = k-d+1+N
end
tenmat(permutedims(X,circshift(1:N,-a+1)),row=1:d)
end
for positive integers d<N and k≦N where N is the depth of input tensor X. The function tenmat comes from TensorToolbox.jl and it is for matricization of a tensor. Please see ReadMe file in TensorToolbox.jl.
Here I put an example with N=4.
X = rand(1:9,3,4,2,2)
#3×4×2×2 Array{Int64, 4}:
#[:, :, 1, 1] =
# 5 7 2 6
# 4 5 6 2
# 6 8 9 1
#
#[:, :, 2, 1] =
# 4 3 7 5
# 8 3 3 1
# 8 2 4 7
#
#[:, :, 1, 2] =
# 4 3 9 6
# 7 4 9 2
# 6 7 2 4
#
#[:, :, 2, 2] =
# 9 2 1 7
# 8 2 1 3
# 6 2 4 9
M = TCU(X, 2, 3)
#8×6 Matrix{Int64}:
# 5 4 4 7 6 6
# 7 3 5 4 8 7
# 2 9 6 9 9 2
# 6 6 2 2 1 4
# 4 9 8 8 8 6
# 3 2 3 2 2 2
# 7 1 3 1 4 4
# 5 7 1 3 7 9
What I need
I would like to write the reverse operation of the above function. That is, I need the function InvTCU that satisfies
X == InvTCU( TCU(X, d, k), d, k )
If we need, InvTCU can require the original tensor size size(X)
X == InvTCU( TCU(X, d, k), d, k, size(X) )
The reason why I need InvTCU
It is required in Equation (18) in the document to implement the algorithm named PTRC. In this situation, the size of the original tensor size(X) are available information.
EDIT
I added the description about tenmat.
I added the description that InvTCU can require the original tensor size.
Before giving the function, it might be noted that to get the matrixfied tensor, it is possible to use views instead of permuting the dimensions, which might be more efficient (depending on processing later). This can be done (I think) with the TrasmuteDims or TensorCast packages (https://docs.juliahub.com/TransmuteDims/NIYrh/0.1.15/).
Here is an attempt at a permutedims approach:
function invTCU(M,d,k, presize)
N = length(presize)
a = d<=k ? k-d+1 : k-d+1+N
X = reshape(M,Tuple(circshift(collect(presize),1-a)))
permutedims(X,circshift(1:N,a-1))
end
with this definition:
julia> X = reshape(1:48,3,4,2,2)
3×4×2×2 reshape(::UnitRange{Int64}, 3, 4, 2, 2) with eltype Int64:
[:, :, 1, 1] =
1 4 7 10
...
julia> X == invTCU(TCU(X, 2, 3), 2, 3, size(X))
true
seems to recover original tensor.

Efficient method to get node connectivity in FEM

I have information of element connectivity in problem of finite element method.
For example,
1, 5, 6, 8, 7, 1, 2, 4, 3
The first column is the index of element, and the last 8 columns are the node index which composed entries for element 1.
The goal what I want is node array like as below.
It is an array with all the node indices associated with each node.
node_arr[1] = [2 3 4 5 6 7 8]
node_arr[2] = [1 3 4 5 6 7 8]
node_arr[3] = [1 2 4 5 6 7 8]
node_arr[4] = [1 2 3 5 6 7 8]
node_arr[5] = [1 2 3 4 6 7 8]
node_arr[6] = [1 2 3 4 5 7 8]
node_arr[7] = [1 2 3 4 5 6 8]
node_arr[8] = [1 2 3 4 5 6 7]
So the current state of my code is as below .
1-count the number about how many elements contain that node index
for loop i (entire node){
for loop j (entire element){
if (element j has node i is true){
node_count[i] = node_count[i] + 1;
}
}
}
2-Allocate node_node_arr to contain target information by using the results of step 1
node_node_arr = malloc(by using node_count)
3-Again, it searches the entire element node index and append the node index related with current node index for composing node_node_array.
for loop i (entire node){
for loop j (entire element){
if (element j has node i is true){
node_node_arr[i] append node indices;
}
}
}
However this approach is so slow .
If both the number of elements and the number of nodes increase, the calculation time increases tremendously.
I need speed up.
Please help me.

Find an element in a specific row and column in a 2D array

I'm having trouble in looking for an element in a specific.
I have the array
A = [ 1 2 3 7 2 ; 2 8 5 7 2; 1 9 8 4 1; 8 7 2 10 9; 10 9 4 3 8]
I just want to get the index of A(3,4) for the element of 4. However my code spits out the two locations of the element 4, which is A(5,3) and A(3,4).
I used [row, col] = find(E==4)
Use
[row, col] = find(E==4, 1)
The second parameter is the number of elements you want to find. Find more details at https://www.mathworks.com/help/matlab/ref/find.html
Matlab searches a matrix in column-by-column order. If you want to find the first element by rows, you could transpose E before calling find. But you need to swap the resulting indices then:
[col, row] = find(E'==4, 1)
Here's a lengthier, iterative way to find the first index:
A = [ 1 2 3 7 2 ;...
2 8 5 7 2;...
1 9 8 4 1;...
8 7 2 10 9;...
10 9 4 3 8];
[a,b] = size(A);
for i = 1:a
for j = 1:b
if A(i,j) == 4
break
end
end
if A(i,j) == 4
break
end
end
index = [i,j]
It returned [3, 4] for me.

Find and Replace specific number at specific location in array in MATLAB

I have an array containing numbers.
A = [1 0 5 6 2 4 5 7 8 8 3 2 1 0 0 1 0 0];
I have calculated peaks and locations of these numbers in an array.
pks = [6 8 1 ]
locs = [4 9 16]
Now I want to update the array with the new peaks value that I have calculated and plot it.
Example.
I have received peaks [6, 8, 1] at locations [4, 9, 16].
I have altered the peaks values e.g. (pks-1).
I want to replace the peak values in the original array with the new values [5, 7, 0].
Like this.
% replace: ↓ ↓ ↓
A = [1 0 5 5 2 4 5 7 7 8 3 2 1 0 0 0 0 0];
Is there any trick to do this in MATLAB?
Thanks a lot.
Example Code
A = [1 0 5 6 2 4 5 7 8 8 3 2 1 0 0 1 0 0];
[pks,locs] = findpeaks(A);
for i=1:length(pks)
if (pks(i)==locs(i))
pks_1(i)=(pks(i)-1);
A_copy(A_copy==pks(i))=pks_1(i);
else
goto if
end
end
You can directly index them, replace your example code with the following:
A = [1 0 5 6 2 4 5 7 8 8 3 2 1 0 0 1 0 0];
% We aren't interested in the actual pks values, so use ~ instead
[~,locs] = findpeaks(A)
% Reduce all values at 'locs' by 1
A(locs) = A(locs) - 1;
Note, there were several errors in your code. For instance,
you are comparing pks(i) == locs(i), have a think about what that's actually comparing because it doesn't find when your loop is at a peak. For that you would need a double loop
for jj = 1:numel(pks)
for ii = 1:numel(A)
if (ii == locs(ii))
% Peak is at index ii
end
end
end
Better would be
for ii = locs
% Peak is at index ii
end
Even better would be the direct indexing I've shown at the top of this answer!
You are also indexing A_copy and pks_1 before they're defined, so that could cause issues.
Also I'm not sure what you think the goto statement is doing?!

Sort an array in such a way that the first element is the largest, the second element is the smallest, and so on. Do without extra space

The question is:
Given an unsorted array, sort it in such a way that the first element is the largest, the second element is the smallest, the third element is the second largest, etc.
Follow up: Can you do it without using extra space?
Example:
[2, 4, 3, 5, 1] -> [5, 1, 4, 2, 3]
I want to be able to sort the array without using extra space. What is the most efficient solution? I can only think of an O(n2) solution that loops through the array to find the next largest and next smallest elements. Is there a more efficient solution?
I've looked at the related questions Sorting an array with alternate smallest and largest values and Sorting an array with alternate smallest-largest values but the answers didn't help with my question.
precondition : using deque.
1.sorting the array.
loop)
2.pop_back(array) -> insert that element in i*2 position.
example) 1, 2, 3, 4, 5, 6, 7
a) 7 (insert to 0) -> 1 2 3 4 5 6 => 7 1 2 3 4 5 6
b) 6 (insert to 2) -> 7 1 2 3 4 5 => 7 1 6 2 3 4 5
c) 5 (insert to 4) -> 7 1 6 2 3 4 => 7 1 6 2 5 3 4 (finished)
Its complexity maybe O(nlog(n)) + O(n/2)

Resources