Shift array in stateflow - arrays

I want to shift an array within stateflow by one element.
In matlab, I would use circshift or this code:
>> x = [1:5]
x =
1 2 3 4 5
>> x(2:end) = x(1:end-1)
x =
1 1 2 3 4
>> x(1) = 0 % New Value
x =
0 1 2 3 4
How can I implement this in stateflow action language.
Embedded matlab-function is not possible because of realtime-target.
I tried this:
{x[2:end] = x[1:end-1];
x[1] = 0;}
but thats a syntax error.
For loop should be possible as well, but thats strange to me in matlab :-)
Thanks in advance

Both answers in comments helped a lot: Matlab Function works also with my target and circshift works fine.

Related

How to create a loop for subtraction in MATLAB for arrays?

I'm new to MATLAB and want to learn more about looping. First, I have an array called "A":
A = 4
6
7
11
12
17
22
25
Next, I want to create an array that will subtract each row. So, it would essentially do "6-4", "7-6", "11-7", "12-11", "17-12", "22-17", "25-22". I want this to be displayed as:
2
1
3
1
5
5
3
However, what I have doesn't output anything.
I tried using a "while" loop but I don't receive any output, no error message either. What I have so far is shown below:
PS - I have used Python before so maybe I am mixing up Python syntax with MATLAB or maybe my logic is wrong ?
B = length(A); %will output the length of A, which is 8
while i <= B
X = A(i, 1); %set X equal to "row i" and column 1
Y = A(i+1, 1); %this i don't know what to do.. I want this to be the row
%directly below i so if i is row 1, then I want this to be
%row 2
bsxfun(#minus, X, Y)
end
I feel like this should be simple but I am not sure what I am doing wrong. I appreciate all feedback! If my question needs more clarification, please let me know! :)
MATLAB has a built-in function, diff, that does what you want:
>> A = [4; 6; 7; 11; 12; 17; 22; 25];
>> diff(A)
ans =
2
1
4
1
5
5
3
You could also get the same result using array slicing:
>> A(2:end) - A(1:end-1)

matlab making repetitions of data from one array into another array [duplicate]

This question already has answers here:
Element-wise array replication in Matlab
(7 answers)
Closed 6 years ago.
I would appreaciate a lot if you help. I am beginner in programming. I am using Matlab. So, I have an array which is 431x1 type - double; there i have numbers 1 to 6; for ex: 1 4 5 3 2 6 6 3 3 5 4 1 ...; what I want to do is I need to make a new array where I would have each element repeat for 11 times; for ex: a(1:11)=1; a(12:22)=4; a(23:33)=5; or to illustrate differently : a=[1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4...];
I tried doing it in a loop but had some problems, which way could you suggest, do you know any function I could take advantage of?
First of all, it would help if you could format your code is separate blocks to make your question easier to read...
Let's say you had an array of length Nx1 as:
x = [1 2 3 4 5 ...]';
You could construct a loop and concatenate as:
for i = 1 : length(x)
for i = 1: length(x)
y(1 + (i - 1) * 11 : 1 + i * 11) = x(i); % Copy to a moving block
end
y(end) = []; % Delete the superfluous one at the end
You could also look at functions like repmat in the MATLAB help for replicating arrays.
Try this (NRepis how many times you want it repeated):
x = [1, 2, 3, 4, 5];
NRep = 5;
y = reshape(repmat(x,[NRep,1]),[1,length(x)*NRep])
Since it's a little cumbersome to write that out, I also particularly enjoy to use this "hack":
x = [1, 2, 3, 4, 5];
NRep = 5;
y = kron(x, ones(1,NRep));
Hope that helps!
P.S.: This is designed for row vectors only. Though if you need column vectors it's easy to modify.
edit: Of course, if you're post-R2015a you can just use y=repelem(x,NRep). I tend to forget about those because I work on older Matlabs (and sometimes it's not such a bad idea to be a bit backward compatible). Thanks to #rahnema1 for reminding me.

Removing any two array values whose difference is a member of that array

I am trying to remove array values whose difference is a member of that array in MATLAB. For example, if I have an array defined as
x = [1 2 4 3 7];
I would like to remove 2, because it can be achieved from 4 - 2. I would also like to remove 4 because it can be achieved from 7 - 3. I would then like to store these values (2 and 4, respectively) into a matrix. The latter is easy. I just have a hard time doing this checker for summation.
I know you can use
ismember(*any 2 differences*),x(:))
to check if the differences are in the array. However, I don't know how to code my function to try out all the combinations of element subtraction.
Seemed like a good setup to use bsxfun -
abs_diffs = abs(bsxfun(#minus,x(:),x(:).')) %//'
unq_abs_diffs = unique(abs_diffs)
out = x(~any(bsxfun(#eq,unq_abs_diffs(:),x(:).'),1)) %//'
%// OR x(~ismember(x,unq_abs_diffs))
Sample run -
>> x
x =
1 2 4 3 7
>> abs_diffs = abs(bsxfun(#minus,x(:),x(:).'))
abs_diffs =
0 1 3 2 6
1 0 2 1 5
3 2 0 1 3
2 1 1 0 4
6 5 3 4 0
>> unq_abs_diffs = unique(abs_diffs)
unq_abs_diffs =
0
1
2
3
4
5
6
>> out = x(~any(bsxfun(#eq,unq_abs_diffs(:),x(:).'),1))
out =
7
So, in [1 2 4 3 7], only 7 seemed like the one that could not be removed.
You could do it like this:
n = length(a);
differences = meshgrid(a,a) - meshgrid(a,a)'; % get differences between elements
differences(1:n+1:n*n) = []; % remove diagonal
a(ismember(a,differences)) = []; % remove elements in differences
I'm assuming that you only want differences between unique elements. If you want to allow the difference between an element of a and itself, then remove the 3rd line.

Using bsxfun with an anonymous function

after trying to understand the bsxfun function I have tried to implement it in a script to avoid looping. I am trying to check if each individual element in an array is contained in one matrix, returning a matrix the same size as the initial array containing 1 and 0's respectively. The anonymous function I have created is:
myfunction = #(x,y) (sum(any(x == y)));
x is the matrix which will contain the 'accepted values' per say. y is the input array. So far I have tried using the bsxfun function in this way:
dummyvar = bsxfun(myfunction,dxcp,X)
I understand that myfunction is equal to the handle of the anonymous function and that bsxfun can be used to accomplish this I just do not understand the reason for the following error:
Non-singleton dimensions of the two input arrays must match each other.
I am using the following test data:
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18];
and hope for the output to be:
dummyvar = [1,0,0,0]
Cheers, NZBRU.
EDIT: Reached 15 rep so I have updated the answer
Thanks again guys, I thought I would update this as I now understand how the solution provided from Divakar works. This might deter confusion from others who have read my initial question and are confused to how bsxfun() works, I think writing it out helps me understand it better too.
Note: The following may be incorrect, I have just tried to understand how the function operates by looking at this one case.
The input into the bsxfun function was dxcp and X transposed. The function handle used was #eq so each element was compared.
%%// Given data
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18];
The following code:
bsxfun(#eq,dxcp,X')
compared every value of dxcp, the first input variable, to every row of X'. The following matrix is the output of this:
dummyvar =
0 1 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
The first element was found by comparing 1 and 2 dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
The next along the first row was found by comparing 2 and 2 dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
This was repeated until all of the values of dxcp where compared to the first row of X'. Following this logic, the first element in the second row was calculating using the comparison between: dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
The final solution provided was any(bsxfun(#eq,dxcp,X'),2) which is equivalent to: any(dummyvar,2). http://nf.nci.org.au/facilities/software/Matlab/techdoc/ref/any.html seems to explain the any function in detail well. Basically, say:
A = [1,2;0,0;0,1]
If the following code is run:
result = any(A,2)
Then the function any will check if each row contains one or several non-zero elements and return 1 if so. The result of this example would be:
result = [1;0;1];
Because the second input parameter is equal to 2. If the above line was changed to result = any(A,1) then it would check for each column.
Using this logic,
result = any(A,2)
was used to obtain the final result.
1
0
0
0
which if needed could be transposed to equal
[1,0,0,0]
Performance- After running the following code:
tic
dummyvar = ~any(bsxfun(#eq,dxcp,X'),2)'
toc
It was found that the duration was:
Elapsed time is 0.000085 seconds.
The alternative below:
tic
arrayfun(#(el) any(el == dxcp),X)
toc
using the arrayfun() function (which applies a function to each element of an array) resulted in a runtime of:
Elapsed time is 0.000260 seconds.
^The above run times are averages over 5 runs of each meaning that in this case bsxfun() is faster (on average).
You don't want every combination of elements thrown into your any(x == y) test, you want each element from dxcp tested to see if it exists in X. So here is the short version, which also needs no transposes. Vectorization should also be a bit faster than bsxfun.
arrayfun(#(el) any(el == X), dxcp)
The result is
ans =
0 1 0 0 0 0

loop to remove repeated elements of a vector and add corresponding elements of another vector

I am using MATLAB to write a code that multiplies polynomials. Most parts of my code work however there is one part where I have two row vectors a and b. I want to remove repeated elements of a and then add the corresponding elements of b. This is what I have written
c=length(a);
d=length(b);
remove=[];
for i=1:c
for j=i+1:c
if (a(i)==a(j))
remove=[remove,i];
b(j)=b(i)+b(j);
end
end
end
a(remove)=[];
b(remove)=[];
The problem with this is if there is an element in a that appears more than twice, it doesn't work properly.
For example if a=[5,6,8,9,6,7,9,10,8,9,11,12] and b=[1,7,1,-1,3,21,3,-3,-4,-28,-4,4]
then once this code is run a becomes [5,6,7,10,8,9,11,12] which is correct but b becomes [1,10,21,-3,-3,-27,-4,4] which is correct except the -27 should be a -26.
I know why this happens because the 9 in a(1,4) gets compared with the 9 in a(1,7) so b(1,7) becomes b(1,7)+b(1,4) and then a(1,4) gets compared with the 9 in a(1,10). and then later the a(1,7) compares with a(1,10) and so the new b(1,7) adds to the b(1,10) however the b(1,4) adds to the b(1,10) too. I somehow need to stop this once one repeated element has been found because here b(1,4) has been added twice when it should only be added once.
I am not supposed to use any built in functions, is there a way of resolving this easily?
I would prefer using built in functions, but assuming you have to stick to your own approach, you can try this:
a=[5,6,8,9,6,7,9,10,8,9,11,12];
b=[1,7,1,-1,3,21,3,-3,-4,-28,-4,4];
n = numel(a);
remove = zeros(1,n);
temp = a;
for ii = 1:n
for jj = ii+1:n
if temp(ii) == temp(jj)
temp(ii) = NaN;
remove(ii) = ii;
b(jj) = b(jj) + b(ii);
end
end
end
a(remove(remove>0)) = []
b(remove(remove>0)) = []
a =
5 6 7 10 8 9 11 12
b =
1 10 21 -3 -3 -26 -4 4
It's not much different from your approach, except for changing the iith value of a if it is found later. To avoid overwriting the values in a with NaN, I'm using a temporary variable for this.
Also, as you can see, I'm avoiding remove = [remove i], because this will create a growing vector, which is very slow.
It can be solved in a vectorized manner with the following indexing nightmare (perhaps someone will come up with a simpler approach):
a = [5,6,8,9,6,7,9,10,8,9,11,12];
b = [1,7,1,-1,3,21,3,-3,-4,-28,-4,4];
[sa, ind1] = sort(a);
[~, ii, jj] = unique(sa);
[ind2, ind3] = sort(ind1(ii));
a = a(ind2);
b = accumarray(jj(:),b(ind1)).';
b = b(ind3);
Anyway, to multiply polynomials you could use conv:
>> p1 = [1 3 0 2]; %// x^3 + 3x^2 + 1
>> p2 = [2 -1 4]; %// 2x^2 - x + 4
>> conv(p1,p2)
ans =
2 5 1 16 -2 8 %// 2x^5 + 5x^4 + x^3 + 16x^2 - 2x + 8

Resources