Entry level question about Matlab array operation - arrays

Hey guys. I have this question to ask. In C programming, if we want to store several values in an array, we implement that using loops like this:
j=0; //initialize
for (idx=1,idx less than a constant; idex++)
{
slope[j]=(y2-y1)/(x2-x1);
j++;
}
My question is in Matlab do we have any simpler way to get the same array 'slope' without manually increasing j? Something like:
for idx=1:constant
slope[]=(y2-y1)/(x2-x1);
Thank you!

Such operations can usually be done without looping.
For example, if the slope is the same for all entries, you can write
slope = ones(numRows,numCols) * (y2-y1)/(x2-x1);
where numRows and numCols are the size of the array slope.
If you have a list of y-values and x-values, and you want the slope at every point, you can call
slope = (y(2:end)-y(1:end-1))./(x(2:end)-x(1:end-1)
and get everything in one go. Note that y(2:end) are all elements from the second to the last, and y(1:end-1) are all elements from the first to the second to last. Thus, the first element of the slope is calculated from the difference between the second and the first element of y. Also, note the ./ instead of /. The dot makes it an element-wise operation, meaning that I divide the first element of the array in the numerator by the first element of the array in the denominator, etc.

Related

removing second layer for loop when defining array

Working in MATLAB R2017a. I'm trying to optimise a piece of code I'm working on. It uses arrays to store field values on a grid.
In order to create a specific function in a field array I originally used the straight forward method of two for loops iterating over all the array elements. But i know for loops are slow so since then I came back and tried my best to remove them. However I could only manage to remove one of the loops; leaving me with this:
for n = 1:1:K
%%% define initial pertubation
t=n*dt;
% create array for source Ez field.
xtemps = (1:Ng)*dX;
for k = 1:Ng
ztemp = k*dX;
Ez0(k,:) = THzamp * (1/(1+exp(-(t-stepuppos)))) * exp(-((xtemps-...
THzstartx).^2)./(bx^2)) .* (t-((ztemp-THzstartz)/vg))*exp(-((t-((ztemp-...
THzstartz)/vg))^2)/(bt^2));
end
The important bit here is the last 5 lines, but I figured the stuff before might be important for context. I've removed the for loop looping over the x coordinates. I want to vectorize the z/k for loop but I can't figure out how to distinguish between the dimensions with the array oporators.
Edit: THzamp, stepuppos, bx, bt, THzstartz, THzstartx are all just scalars, they control the function (Ez0) I'm trying to create. dX and t are also just scalars. Ez0 is a square array of size Ng.
What I want to achieve is to remove the for loop that loops over k, so that that the values of ztemp are defined in a vector (like xtemps already is), rather than individually in the loop. However, I don't know how I'd write the definition of Ez0 in that case.
First time posting here, if I'm doing it wrong let me know. If you need more info just ask.
It isn't clear if n is used in the other headers and as stated in the comments your sizes aren't properly defined so you'll have to ensure the sizes are correct.
However, you can give this vectorize code a try.
n = 1:K
%%% define initial pertubation
t=n*dt;
% create array for source Ez field.
xtemps = (1:Ng)*dX;
for k = 1:Ng
ztemp = k*dX;
Ez0(k,:) = THzamp .* (1./(1+exp(-(t-stepuppos)))) .* exp(-((xtemps-...
THzstartx).^2)./(bx^2)) .* (t-((ztemp-THzstartz)/vg)).*exp(-((t-((ztemp-...
THzstartz)/vg)).^2)/(bt.^2));
end
So now t has the size K you'll need to ensure stepupposand (ztemp-THzstartz)/vg) have the same size K. Also you can take a look at vectors vs array operators here.

Creating a cell array of different randomized matrices

I'm trying to create a cell array of size N,
where every cell is a randomized Matrix of size M,
I've tried using deal or simple assignments, but the end result is always N identical Matrices of size M
for example:
N=20;
M=10;
CellArray=cell(1,N);
CellArray(1:20)={rand(M)};
this yields identical matrices in each cell, iv'e tried writing the assignment like so:
CellArray{1:20}={rand(M)};
but this yields the following error:
The right hand side of this assignment has too few values to satisfy the left hand side.
the ends results should be a set of transition probability matrices to be used for a model i'm constructing,
there's a currently working version of the model, but it uses loops to create the matrices, and works rather slowly,
i'd be thankful for any help
If you don't want to use loops because you are interested in a low execution time, get rid of the cells.
RandomArray=rand(M,M,N)
You can access each slice, which is your intended MxM matrix, using RandomArray(:,:,index)
Use cellfun:
N = 20;
M = 10;
CellArray = cellfun(#(x) rand(M), cell(1,N), 'uni',0)
For every cell it newly calls rand(M) - unlike before, you were assigning the same rand(M) to every cell, which was just computed once.

Limit input data to achieve a better Big O complexity

You are given an unsorted array of n integers, and you would like to find if there are any duplicates in the array (i.e. any integer appearing more than once).
Describe an algorithm (implemented with two nested loops) to do this.
The question that I am stuck at is:
How can you limit the input data to achieve a better Big O complexity? Describe an algorithm for handling this limited data to find if there are any duplicates. What is the Big O complexity?
Your help will be greatly appreciated. This is not related to my coursework, assignment or coursework and such. It's from the previous year exam paper and I am doing some self-study but seem to be stuck on this question. The only possible solution that i could come up with is:
If we limit the data, and use nested loops to perform operations to find if there are duplicates. The complexity would be O(n) simply because the amount of time the operations take to perform is proportional to the data size.
If my answer makes no sense, then please ignore it and if you could, then please suggest possible solutions/ working out to this answer.
If someone could help me solve this answer, I would be grateful as I have attempted countless possible solution, all of which seems to be not the correct one.
Edited part, again.. Another possible solution (if effective!):
We could implement a loop to sort the array so that it sorts the array (from lowest integer to highest integer), therefore the duplicates will be right next to each other making them easier and faster to be identified.
The big O complexity would still be O(n^2).
Since this is linear type, it would simply use the first loop and iterate n-1 times as we are getting the index in the array (in the first iteration it could be, for instance, 1) and store this in a variable names 'current'.
The loop will update the current variable by +1 each time through the iteration, within that loop, we now write another loop to compare the current number to the next number and if it equals to the next number, we can print using a printf statement else we move back to the outer loop to update the current variable by + 1 (next value in the array) and update the next variable to hold the value of the number after the value in current.
You can do linearly (O(n)) for any input if you use hash tables (which have constant look-up time).
However, this is not what you are being asked about.
By limiting the possible values in the array, you can achieve linear performance.
E.g., if your integers have range 1..L, you can allocate a bit array of length L, initialize it to 0, and iterate over your input array, checking and flipping the appropriate bit for each input.
A variance of Bucket Sort will do. This will give you complexity of O(n) where 'n' is the number of input elements.
But one restriction - max value. You should know the max value your integer array can take. Lets say it as m.
The idea is to create a bool array of size m (all initialized to false). Then iterate over your array. As you find an element, set bucket[m] to true. If it is already true then you've encountered a duplicate.
A java code,
// alternatively, you can iterate over the array to find the maxVal which again is O(n).
public boolean findDup(int [] arr, int maxVal)
{
// java by default assigns false to all the values.
boolean bucket[] = new boolean[maxVal];
for (int elem : arr)
{
if (bucket[elem])
{
return true; // a duplicate found
}
bucket[elem] = true;
}
return false;
}
But the constraint here is the space. You need O(maxVal) space.
nested loops get you O(N*M) or O(N*log(M)) for O(N) you can not use nested loops !!!
I would do it by use of histogram instead:
DWORD in[N]={ ... }; // input data ... values are from < 0 , M )
DWORD his[M]={ ... }; // histogram of in[]
int i,j;
// compute histogram O(N)
for (i=0;i<M;i++) his[i]=0; // this can be done also by memset ...
for (i=0;i<N;i++) his[in[i]]++; // if the range of values is not from 0 then shift it ...
// remove duplicates O(N)
for (i=0,j=0;i<N;i++)
{
his[in[i]]--; // count down duplicates
in[j]=in[i]; // copy item
if (his[in[i]]<=0) j++; // if not duplicate then do not delete it
}
// now j holds the new in[] array size
[Notes]
if value range is too big with sparse areas then you need to convert his[]
to dynamic list with two values per item
one is the value from in[] and the second is its occurrence count
but then you need nested loop -> O(N*M)
or with binary search -> O(N*log(M))

use five point stencil to evaluate function with vector inputs and converge to maximum output value

I am familiar with iterative methods on paper, but MATLAB coding is relatively new to me and I cannot seem to find a way to code this.
In code language...
This is essentially what I have:
A = { [1;1] [2;1] [3;1] ... [33;1]
[1;2] [2;2] [3;2] ... [33;2]
... ... ... ... ....
[1;29] [2;29] [3;29] ... [33;29] }
... a 29x33 cell array of 2x1 column vectors, which I got from:
[X,Y] = meshgrid([1:33],[1:29])
A = squeeze(num2cell(permute(cat(3,X,Y),[3,1,2]),1))
[ Thanks to members of stackOverflow who helped me do this ]
I have a function that calls each of these column vectors and returns a single value. I want to institute a 2-D 5-point stencil method that evaluates a column vector and its 4 neighbors and finds the maximum value attained through the function out of those 5 column vectors.
i.e. if I was starting from the middle, the points evaluated would be :
1.
A{15,17}(1)
A{15,17}(2)
2.
A{14,17}(1)
A{14,17}(2)
3.
A{15,16}(1)
A{15,16}(2)
4.
A{16,17}(1)
A{16,17}(2)
5.
A{15,18}(1)
A{15,18}(2)
Out of these 5 points, the method would choose the one with the largest returned value from the function, move to that point, and rerun the method. This would continue on until a global maximum is reached. It's basically an iterative optimization method (albeit a primitive one). Note: I don't have access to the optimization toolbox.
Thanks a lot guys.
EDIT: sorry I didn't read the iterative part of your Q properly. Maybe someone else wants to use this as a template for a real answer, I'm too busy to do so now.
One solution using for loops (there might be a more elegant one):
overallmax=0;
for v=2:size(A,1)-1
for w=2:size(A,2)-1
% temp is the horizontal part of the "plus" stencil
temp=A((v-1):(v+1),w);
tmpmax=max(cat(1,temp{:}));
temp2=A(v,(w-1):(w+1));
% temp2 is the vertical part of the "plus" stencil
tmpmax2=max(cat(1,temp2{:}));
mxmx=max(tmpmax,tmpmax2);
if mxmx>overallmax
overallmax=mxmx;
end
end
end
But if you're just looking for max value, this is equivalent to:
maxoverall=max(cat(1,A{:}));

algorithm to sort elements of three arrays

Here's the stumper:
Start with three arrays A, B and C with a total of 2n+1 entries.
Write an algorithm to sort all of the entries from all of the arrays
using only the following two methods:
X = sort(X) replaces the array X with the sorted version.
(X , Y) = doubleUp(X , Y) does nothing if X has more elements
than Y, otherwise it removes the first length(X) entries from Y
and appends them to the end of X.
Here's what I've tried so far. If two of the arrays are empty, then just use sort on the nonempty array.
If one of the arrays is empty, then I think I can use doubleUp to get one array to have just one thing and the other array to have everything else, and if that singleton array has the smallest (or largest) element, then that works. So I can use sort after I use doubleUp each time to make sure this happens. I coded this up in Maple and it worked for all the cases I checked.
I have no idea how to do it with 3 arrays though. Anyone have any ideas?
Sounds like nonsense. The total number of entries is odd. The only way to increase the length of an array is to make it the smaller first argument of doubleUp, in which case it ends up with an even number of elements. So unless all the elements are in one array to begin with there's no way to make one array contain all the elements, sorted or otherwise.
So, the desired final result is not a single array containing all the elements in order. Or if it is, then the answer to the question is "it cannot be done".

Resources