How to increment a v value to an i position in a vector every n iterations ?

5 views (last 30 days)
Hello,
In the context of meshing for a 1D finite elements method, I have a vector with 1 row and n columns (nodes). I divide it into E elements of L nodes, which means that every last node of an element is the first node of the following element.
I would like to create a second vector for which every L iteration I double the L value and shift my whole vector to the right. Example:
E = 3
L = 4
A = [1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4]
( l 1st E l 2nd E l 3rd E l etc... )
B = [1 2 3 4 1 1 2 3 4 1 1 2 3 4 1 1 2 3 4 1 1 2 3 4 1]
( l 1st E l l 2nd E l l 3rd E etc.... (the "l" are just delimiters))
To verify that B was correctly constructed I know that length(B) must be equal to E * (L + 1).
So far I had two leads. Let global_vector be A, and local_vector B (the vector I want to change):
%%1st lead:
Total_Element = 1; %Size of the global element
L = 9; %Number of nodes per element -1
E = 100; %Number of Elements
num_nodes = E * L + 1; %Number of nodes
nodes = linspace(0,L,num_nodes); %Position of the nodes on the global element
global_vector = nodes;
local_vector = [];
for i = L:1:length(global_vector)-L % I stop the loop before the last vector to avoid doubling it at the end
if mod(i,L) == 0
added_value = global_vector (1,i);
local_vector = [local_vector,added_value,added_value];
else
local_vector = [local_vector,global_vector(i)];
end
end
local_vector = [local_vector, global_vector(:,end-L:end)]; % Add the last element to local_vector
%%% 2nd Lead: my local_vector is already constructed, and every L iteration I increment the local_vector on the i + 1 column with the value global_vector(i) without deleting the value local_vector(i), and shifting the local_vector to the right:
Total_Element = 1; %Size of the global element
L = 9; %Number of nodes per element -1
E = 100; %Number of Elements
num_nodes = E * L + 1; %Number of nodes
nodes = linspace(0,L,num_nodes); %Position of the nodes on the global element
global_vector = nodes;
local_vector = global_vector;
j = 0;
for i = L:L:length(global_vector)-L %To double the Lth value of the vector
j = j + 1; %Count of the shift created for every loop
added_value = global_vector(1,i);
local_vector = [local_vector(1,1:i),added_value,global_vector(1,i+j)] %I try to fit the value by addind a row between i and i + 1
end
local_vector = [local_vector, global_vector(:,end-L:end)]; % Same reason as the first lead
But I am stuck since J exceeds quickly the array bounds. Maybe there is a function to do this or a way to make 2 loops run in parallel, but I can't find anything.
I did it for a simpler problem and it works:
Total_Element = 1; %Size of the global element
E = 150;
L = 2;
num_nodes = E * L + 1; %Number of nodes
nodes = linspace(0,L,num_nodes); %Position of the nodes on the global element
global_vector = nodes;
local_vector = global_vector(:,1);
for i = 2:1:length(global_vector)-2
if mod(i,2) == 0
local_vector = [local_vector,global_vector(i)];
else
added_value = global_vector (1,i);
local_vector = [local_vector,added_value,added_value];
end
end
local_vector = [local_vector, global_vector(:,end-1:end)];
Does anyone have a solution for this kind of problem ? Because I can't really find anything similar I don't know if the solution is just way more complicated or if it is something totally different.
Thank you !!
  2 Comments
darova
darova on 10 Jan 2020
What is the question in short? I don't want to read all this expanations
V.D-C
V.D-C on 10 Jan 2020
In short I want to implement a value from a vector to a second vector every L column, without deleting the value of the second vector on the corresponding column.
Take it in other words: select a value from a vector, take another vector, split it open, add the value, and stick it together again. And do that several times.

Sign in to comment.

Answers (1)

Guillaume
Guillaume on 10 Jan 2020
I don't really understand your example, particularly the E which doesn't appear to have any meaning (shouldn't the A in your example have E*L elements == 12 ?).
Transforming your example A into your example B by duplicating the first element of each run of length L at the end is trivially done:
L = 4;
A = 1:12; %actually numbers don't matter
assert(mod(numel(A), L) == 0, 'The numbers of elements in A must be a multiple of L');
Btemp = reshape(A, L, []); %reshape A into 2D matrix with L rows.
B = reshape([Btemp; Btemp(1, :)], 1, []) %duplicate 1st row (start of each L run) as last row, and reshape back into vector
No idea if that's what you're really after. If not please clarify with a better example.
  3 Comments
Guillaume
Guillaume on 10 Jan 2020
Sorry, I'm even more confused. I'm not even sure what the input is anymore (A? B?) and what the desired output is (A? B? Q?). In all the pieces of code you've posted E is just used to calculate num_nodes which is just to generate the input as far as I understand. It's not use anymore after that, hence why I think that for the purpose of transforming that input it's irrelevant.
As for transforming A into B, I believe my answer does that (my example use an implied E = 3).
V.D-C
V.D-C on 10 Jan 2020
Sorry for the inconvenience, it's a tricky subject to explain !
Yes I misunderstood you. E is used only at the beginning.
The input is A, and the desired output is B verifying length(B) = E * (L + 1), and Q.
And yes for you example your code work, thank you for that. I will try to implement it in my code with my parameters and see how it works. Thank you for having taking time to reply !!

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!