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.
Related
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.
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.
I am trying to generate random numbers between 1 and 5 using Matlab's randperm and calling randperm = 5.
Each time this gives me a different array let's say for example:
x = randperm(5)
x = [3 2 4 1 5]
I need the vector to be arranged such that 4 and 5 are always next to each other and 2 is always between 1 and 3... so for e.g. [3 2 1 4 5] or [4 5 1 2 3].
So essentially I have two "blocks" of unequal length - 1 2 3 and 4 5. The order of the blocks is not so important, just that 4 & 5 end up together and 2 in between 1 and 3.
I can basically only have 4 possible combinations:
[1 2 3 4 5]
[3 2 1 4 5]
[4 5 1 2 3]
[4 5 3 2 1]
Does anyone know how I can do this?
Thanks
I'm not sure if you want a solution that would somehow generalize to a larger problem, but based on how you've described your problem above it looks like you are only going to have 8 possible combinations that satisfy your constraints:
possible = [1 2 3 4 5; ...
1 2 3 5 4; ...
3 2 1 4 5; ...
3 2 1 5 4; ...
4 5 1 2 3; ...
5 4 1 2 3; ...
4 5 3 2 1; ...
5 4 3 2 1];
You can now randomly select one or more of these rows using randi, and can even create an anonymous function to do it for you:
randPattern = #(n) possible(randi(size(possible, 1), [1 n]), :)
This allows you to select, for example, 5 patterns at random (one per row):
>> patternMat = randPattern(5)
patternMat =
4 5 3 2 1
3 2 1 4 5
4 5 3 2 1
1 2 3 5 4
5 4 3 2 1
You can generate each block and shuffle each one then and set them as members of a cell array and shuffle the cell array and finally convert the cell array to a vector.
b45=[4 5]; % block 1
b13=[1 3]; % block 2
r45 = randperm(2); % indices for shuffling block 1
r13 = randperm(2); % indices for shuffling block 2
r15 = randperm(2); % indices for shuffling the cell
blocks = {b45(r45) [b13(r13(1)) 2 b13(r13(2))]}; % shuffle each block and set them a members of a cell array
result = [blocks{r15}] % shuffle the cell and convert to a vector
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)
This question already has answers here:
Generate a matrix containing all combinations of elements taken from n vectors
(4 answers)
Closed 8 years ago.
I'm trying to build all possible arrays of length n of a vector of n elements with at least 2 integers in each position. I should be getting 2^n combinations, 16 in this case. My code is generating only half of them, and not saving the output to an array
allinputs = {[1 2] [2 3] [3 4] [5 6]}
A = []
the command I run is
inputArray = inputBuilder(A,[],allinputs,1)
for the function
function inputArray = inputBuilder(A,currBuild, allInputs, currIdx)
if currIdx <= length(allInputs)
for i = 1:length(allInputs{currIdx})
mybuild = [currBuild allInputs{currIdx}(i)];
inputBuilder(A,mybuild,allInputs,currIdx + 1);
end
if currIdx == length(allInputs)
A = [A mybuild];
%debug output
mybuild
end
if currIdx == 1
inputArray = A;
end
end
end
I want all 16 arrays to get output in a vector. Or some easy way to access them all. How can I do this?
EDIT:
Recursion may be a requirement because allinputs will have subarrays of different lengths.
allinputs = {[1] [2 3] [3 4] [5 6 7]}
with this array it will be 1*2*2*3 or 12 possible arrays built
Not sure exactly if this is what you want, but one way of doing what I think you want to do is as follows:
allinputs = {[1 2] [2 3] [3 4] [5 6]};
comb_results = combn([1 2],4);
A = zeros(size(comb_results));
for rowi = 1:size(comb_results, 1)
indices = comb_results(rowi,:);
for idxi = 1:numel(indices)
A(rowi, idxi) = allinputs{idxi}(indices(idxi));
end
end
This gives:
A =
1 2 3 5
1 2 3 6
1 2 4 5
1 2 4 6
1 3 3 5
1 3 3 6
1 3 4 5
1 3 4 6
2 2 3 5
2 2 3 6
2 2 4 5
2 2 4 6
2 3 3 5
2 3 3 6
2 3 4 5
2 3 4 6
combn is here.