Visual Basic, Array, Mod - arrays

I have 2 variables - Z and X. Z is a sequence of numbers and X is just a number. F.e. Z = 4 6 2 6 2 3 (it can be any length) and X = 2. I need to do operation Mod for each number - Z mod X: 4 Mod 2, 6 Mod 2, 2 Mod 2,...
And after that all numbers with Mod=0 must be written to new array. How to do this thing ?

assume z is an array and output is a list, so :
for i as integer = 0 to z.length-1
if z(i) mod x = 0
output.add(z(i)
end if

Related

How to merge the second vector to the first, but from a predefined different position, not from continuation?

Suppose I initialized two vectors,
x=[1 2 3 4 5]';
y=[6 7 8 9 10]';
both representing a column matrix, or vector. Now,
z=[x;y];
The z vector will be combination of the two, in a similar column format. y vector will be in continuation to the x vector by this method.
But what should be the approach if I wanted y to be in continuation from a certain given position, leaving the remaining values in between as blank. For example, I want the continuation of y from 8th position to get an output of z as:-
1
2
3
4
5
NaN
NaN
6
7
8
9
10
Just count, how many blanks (NaN) do you need using the desired position and the number of elements of x, and assemble your output z:
% Input
x = [1 2 3 4 5]'
y = [6 7 8 9 10]'
% Position
pos = 8;
% Add some code for checking numel(x) >= pos here...
% Output
z = [x; NaN(pos-numel(x)-1, 1); y]
x =
1
2
3
4
5
y =
6
7
8
9
10
z =
1
2
3
4
5
NaN
NaN
6
7
8
9
10
Meh, after some editing, I realized, that a comment would've been sufficient...

Syntax understanding in task with matlab

can comeone help to understand in MAtlab this:
k=2
n = (0:-1:-4)+k
the result; 2 1 0 -1 -2
how it works?
You are dealing with a colon operator and a vectorized sum at the same time. Let's split the problem into smaller, stand-alone problems:
In Matlab, if you add or subtract between a scalar value to a matrix, the arithmetic operation is performed on all the elements of the matrix, in a vectorized way. Example:
A = [1 2; 3 4]; % 2-by-2 matrix
S1 = A + 2 % output: S1 = [3 4; 5 6]
B = [1 2 3 4] % 1-by-5 matrix, also called column vector
S2 = B - 5 % output: S2 = [3 4 5 6]
The column operator in Matlab can be used in many situation: indexing, for iterations and vector creation. In your case, its purpose is the third one and it's syntax is START(:STEP):END. The default STEP, if not specified, is 1. The START and END parameters are never exceeded. Example:
A = 1:5 % output: A = [1 2 3 4 5]
B = -2.5:2.5:6 % output: B = [-2.5 0 2.5 5]
C = 1:-1:-5 % output: C = [1 0 -1 -2 -3 -4 -5]
D = -4:-2:0 % output: D = []
In all the programming languages, an operator precedence criterion is defined so that a one-liner calculation that uses multiple operators is atomized into smaller calculations that respect the given priority, unless parentheses are used to redefine the default criterion... just like in common maths. Example
A = 2 * 5 + 3 % output: A = 13
B = 2 * (5 + 3) % output: B = 16
Let's put all this together to provide you an explaination:
n = (0:-1:-4) + k
% vector creation has parentheses, so it's executed first
% then, the addition is executed on the result of the first operation
Let's subdivide the calculation into intermediate steps:
n_1 = 0:-1:-4 % output: n_1 = [0 -1 -2 -3 -4]
n_2 = n_1 + k % output: n_2 = [2 1 0 -1 -2]
n = n_2
Want to see what happens without parentheses?
n = 0:-1:-4+k % output: n = [0 -1 -2]
Why? Because the addition has priority over the colon operator. It's like writing n = 0:-1:(-4+k) and adding k to the END parameter of the colon operator. Let's subdivide the calculation into intermediate steps:
n_1 = -4 + k % output: n_1 = -2
n_2 = 0:-1:n_1 % output: n_2 = [0 -1 -2]
n = n_2
Basic Matlab syntax, you're dealing with range operators. There are two patterns:
[start]:[end]
and
[start]:[step]:[end]
Patterns like this result in arrays / vectors / "1D matrices".
In your example, you will get a vector first, stepping through the numbers 0 to -4 (step == -1). Then, you are adding k == 2 to all numbers in this vector.
octave:1> k = 2
k = 2
octave:2> n = (0:-1:-4)+k
n =
2 1 0 -1 -2
octave:3> 0:-1:-4
ans =
0 -1 -2 -3 -4
The parenthesizes expression determines an array. The the first number there is the first element, the second is the step and the last one is the last element. So the parenthesizes returns 0 -1 -2 -3 -4. Next we add k=2 to each element that results in 2 1 0 -1 -2

2D coordinates from 1D array

So basically I'm converting the array index to 2d coordinates.
What I'm trying is the 2D reverse here: https://softwareengineering.stackexchange.com/a/212813/199992
But on the division part for the x (in my case the width is 3), it's returning a double/float, which make sense since (2 / 3) isn't a whole number.
Should I be rounding x?
My code (Lua) is:
for i=1, 9 do
local x = i % 3
local y = i / 3
end
Yeah, you should be rounding x (down), the same for y:
local x = math.floor(i % 3)
local x = math.floor(i / 3)
But you should either count from 0..8 instead (and add 1 to x and y to be 1-based), or subtract 1 from i like this (this is how I usually do it in lua):
for i=1, 9 do
local x = math.floor((i - 1) % 3) + 1 -- 1, 2 or 3
local y = math.floor((i - 1) / 3) + 1 -- 1, 2 or 3
end

Matlab: how to find an enclosing grid cell index for multiple points

I am trying to allocate (x, y) points to the cells of a non-uniform rectangular grid. Simply speaking, I have a grid defined as a sorted non-equidistant array
xGrid = [x1, x2, x3, x4];
and an array of numbers x lying between x1 and x4. For each x, I want to find its position in xGrid, i.e. such i that
xGrid(i) <= xi <= xGrid(i+1)
Is there a better (faster/simpler) way to do it than arrayfun(#(x) find(xGrid <= x, 1, 'last'), x)?
You are looking for the second output of histc:
[~,where] = histc(x, xGrid)
This returns the array where such that xGrid(where(i)) <= x(i) < xGrid(where(i)+1) holds.
Example:
xGrid = [2,4,6,8,10];
x = [3,5,6,9,11];
[~,where] = histc(x, xGrid)
Yields the following output:
where =
1 2 3 4 0
If you want xGrid(where(i)) < x(i) <= xGrid(where(i)+1), you need to do some trickery of negating the values:
[~,where] = histc(-x,-flip(xGrid));
where(where~=0) = numel(xGrid)-where(where~=0)
This yields:
where =
1 2 2 4 0
Because x(3)==6 is now counted for the second interval (4,6] instead of [6,8) as before.
Using bsxfun for the comparisons and exploiting find-like capabilities of max's second output:
xGrid = [2 4 6 8]; %// example data
x = [3 6 5.5 10 -10]; %// example data
comp = bsxfun(#gt, xGrid(:), x(:).'); %'// see if "x" > "xGrid"
[~, result] = max(comp, [], 1); %// index of first "xGrid" that exceeds each "x"
result = result-1; %// subtract 1 to find the last "xGrid" that is <= "x"
This approach gives 0 for values of x that lie outside xGrid. With the above example values,
result =
1 3 2 0 0
See if this works for you -
matches = bsxfun(#le,xGrid(1:end-1),x(:)) & bsxfun(#ge,xGrid(2:end),x(:))
[valid,pos] = max(cumsum(matches,2),[],2)
pos = pos.*(valid~=0)
Sample run -
xGrid =
5 2 1 6 8 9 2 1 6
x =
3 7 14
pos =
8
4
0
Explanation on the sample run -
First element of x, 3 occurs last between ...1 6 with the criteria of xGrid(i) <= xi <= xGrid(i+1) at the backend of xGrid and that 1 is at the eight position, so the first element of the output pos is 8. This continues for the second element 7, which is found between 6 and 8 and that 6 is at the fourth place in xGrid, so the second element of the output is 4. For the third element 14 which doesn't find any neighbours to satisfy the criteria xGrid(i) <= xi <= xGrid(i+1) and is therefore outputted as 0.
If x is a column this might help
xg1=meshgrid(xGrid,1:length(x));
xg2=ndgrid(x,1:length(xGrid));
[~,I]=min(floor(abs(xg1-xg2)),[],2);
or a single line implementation
[~,I]=min(floor(abs(meshgrid(xGrid,1:length(x))-ndgrid(x,1:length(xGrid)))),[],2);
Example: xGrid=[1 2 3 4 5], x=[2.5; 1.3; 1.7; 4.8; 3.3]
Result:
I =
2
1
1
4
3

MATLAB Vector of elements x(i) or y(i) with max(abs(x),abs(y))

Sorry for the title, couldn't think of a concise way to phrase the problem. I need to write a MATLAB one-liner that gives you a vector of elements z(i) where z(i) is the element x(i) or y(i) given by max(abs(x(i)),abs(y(i))). I.e, z is the vector whose elements are the ith elements of x or y which has the maximum absolute value.
I have
max(abs(x),abs(y))
But this obviously gives you a vector of the greatest absolute values. This is close to what I want, but I need to get the sign back of the original vector. I'm not sure how to do this on a single line.
Under the assumption that x and y are arrays (not necessarily vectors) of identical dimensions, you can use logical indexing:
(abs(x)>=abs(y)).*x + (abs(x)<abs(y)).*y
For information, abs(x)>=abs(y) is a logical array for which, for all valid indices, the kth component is
1 if x(k) is greater than or equal to y(k),
0 otherwise.
Example:
>> x = [4;7;-1;9;6];
>> y = [5;2;-3;9;3];
>> (abs(x)>=abs(y)).*x + (abs(x)<abs(y)).*y
ans =
5
7
-3
9
6
If you are interested in a generic code that you could use when working with a number of 2D matrices, let's say x, y and p, you can try this -
x = [-2 4 1;
4 -3 2]
y = [8 -3 -5;
-9 1 5]
p = [6 8 6;
7 -1 -2]
mats = cat(3,x,y,p);%// concatenate all identically sized 2D matrices into 3D
[m,n] = size(x);%// get size
[maxval,dim3ind] = max(abs(mats),[],3);%// Max abs values and indices across dim3
mats_sign = sign(mats); %// signum values
out = mats_sign((dim3ind-1)*m*n + bsxfun(#plus,[1:m]',[0:n-1]*m)).*maxval %// output
Output -
x =
-2 4 1
4 -3 2
y =
8 -3 -5
-9 1 5
p =
6 8 6
7 -1 -2
out =
8 8 6
-9 -3 5
So, if you would like to include one more 2D matrix say q into the mix, just edit the first line of code -
mats = cat(3,x,y,p,q);

Resources