Creating a linearly spaced array of a particular size - arrays

I am new to MATLAB and currently working on my homework assignment. I am trying to declare the x variable as the following:
Create a linearly spaced array x of size (1 × 200) comprising values ranging from –pi to pi.
I've tried this code:
x=[-pi:200:pi];
but I'm not sure if it's the correct way to do this or not.

You can use linspace as follow:
x = linspace(-pi, pi, 200);
check this out for an example:
https://www.mathworks.com/help/matlab/ref/linspace.html

The other answer shows how to use linspace, this is the correct method.
But you can also use the colon operator and some simple arithmetic to do this:
x = -pi : 2*pi/199 : pi -- This means: go from -π to π in steps of such a size that we get exactly 200 values.
x = (0:199) * (2*pi/199) - pi -- This means: create an array with 200 integer values, then scale them to the right range.
Note that you shouldn't use square brackets [] here. They are for concatenating arrays. The colon operator creates a single array, there is nothing to concatenate it with.

Related

Creating a logarithmic spaced array in IDL

I was looking for a way to generate a logarithmic spaced array in IDL.
From the L3 Harris Geospatial website I came across "arrgen" and was trying to use it for this purpose. However,
arrgen(1,215,/log)
returns the error: Variable is undefined: ARRGEN.
What would be the correct way to do it?
Thanks in advance for your help
Start by defining your lower and upper bounds in which ever log-base you prefer. I will use base $e$ for brevity sake.
lowe = ALOG(low[0])
uppe = ALOG(upp[0])
where low and upp are scalar, numerical values you, the user, define (e.g., 1 and 215 in your example). Then construct an evenly spaced array of n elements, such as:
dinde = DINDGEN(n[0])*(uppe[0] - lowe[0])/(n[0] - 1L) + lowe[0]
where n is a scalar integer. Now convert back to linear space to get:
dind = EXP(dinde)
This will be a logarithmically spaced array. If you want to use base-10 log, then substitute ALOG for ALOG10. If you need another base, then you can use the logarithmic change of base rule given by:
logb x = logc x / logc b

Declaring two arrays in gnuplot and plotting them one with respect to another

Gnuplot version 5.2 supports arrays. As given here, one can declare 1D arrays and plot them
array A[100]
do for [i=1:100] { A[i] = sin(2*pi*i/100.) + 0.1*rand(0) }
plot A
This plots the matrix A with the index i.
Is there a way to have two 1D arrays (Eg: x and y) and plot them y vs x.
OR
Declare a 2D array A and plot the 2nd column of A with respect to the first column of A?
Answer #2
If the two arrays A and B are guaranteed to have the same size, a simpler plot command is possible. We start by noting that all of the following plot commands are equivalent.
plot A
plot A using 1:2
plot A using (column(1)):(column(2))
plot A using ($1):($2)
plot A using ($1):(A[$1])
This is because for purposes of plotting an array A is treated as providing two columns of information, the index i (column 1) and the value A[i] (column 2). Following standard gnuplot syntax, each field in the "using" specifier of a plot command may contain either a bare column number or an expression in parentheses. Inside an expression the value of a column can be referred either by prefixing a $ sign or by using the function column(i).
With this in mind, it follows that the command below plots the values of array B against the values of array A.
plot A using (A[$1]):(B[$1])
The trick is to have gnuplot generate a set of samples to plot. Instead of a filename you can provide the string '+' to generate a set of samples along one dimension or '++' to generate a set of samples along two dimensions. Gnuplot calls these "special file names". In your case you want to generate 100 samples (integers from 1 to 100) and use each sample as an index into your arrays.
array A[100]
array B[100]
do for [i=1:100] {
A[i] = something
B[i] = something else
}
plot sample [i=1:100] '+' using (A[i]):(B[i]) with linespoints
The keyword "sample" guarantees that the term in square brackets will not be mis-interpreted as setting the horizontal range ("set xrange") of the plot.
Documentation entries
help +
help special-filenames
help sampling
Answer #3
You ask whether there is an alternative to make A a 2-dimensional array. Not exactly, but remember that in gnuplot floating point numbers are actually complex values. So you could use the real and imaginary components of each A[i] to place it in the x/y plane:
array A[36]
set angle degree
i = {0,1} # i = sqrt(-1) as a complex value
do for [n=1:36] {
A[n] = cos(real(10.*n)) + i * sin(real(10.*n))
}
plot A using (real(A[$1])):(imag(A[$1])) with lp
Is there any special reason why you want to have data in arrays first?
As you are filling your arrays with values of functions, you can also plot two functions (or as you say two columns of a 2D-array) directly against each other without first defining arrays in a do for loop.
Just define some functions and plot them against each other.
Use set samples to define the number of points and use plot sample [] for setting the range. I guess this would be easier than setting the array size, doing the loop and "messing" around with the index i and the range and/or offsets.
### plot one function vs. another function
reset session
f(x) = sin(x) + 0.1*rand(0)
g(x) = cos(x) + 0.1*rand(0)
set samples 100
plot sample [0:2*pi] '+' u (f($1)):(g($1)) w lp pt 7 lc rgb "red"
### end of code

How to select part of complex vector in Matlab

This is probably a trivial question, but I want to select a portion of a complex array in order to plot it in Matlab. My MWE is
n = 100;
t = linspace(-1,1,n);
x = rand(n,1)+1j*rand(n,1);
plot(t(45):t(55),real(x(45):x(55)),'.--')
plot(t(45):t(55),imag(x(45):x(55)),'.--')
I get an error
Error using plot
Vectors must be the same length.
because the real(x(45):x(55)) bit returns an empty matrix: Empty matrix: 1-by-0. What is the easiest way to fix this problem without creating new vectors for the real and imaginary x?
It was just a simple mistake. You were doing t(45):t(55), but t is generated by rand, so t(45) would be, say, 0.1, and t(55), 0.2, so 0.1:0.2 is only 0.1. See the problem?
Then when you did it for x, the range was different and thus the error.
What you want is t(45:55), to specify the vector positions from 45 to 55.
This is what you want:
n = 100;
t = linspace(-1,1,n);
x = rand(n,1)+1j*rand(n,1);
plot(t(45:55),real(x(45:55)),'.--')
plot(t(45:55),imag(x(45:55)),'.--')

Using hist in Matlab to compute occurrences

I am using hist to compute the number of occurrences of values in a matrix in Matlab.
I think I am using it wrong because it gives me completely weird results. Could you help me to understand what is going on?
When I run this piece of code I get countsB as desired
rng default;
B=randi([0,3],10,1);
idxB=unique(B);
countsB=(hist(B,idxB))';
i.e.
B=[3;3;0;3;2;0;1;2;3;3];
idxB=[0;1;2;3];
countsB=[2;1;2;5];
When I run this other piece of code I get wrong results for countsA
A=ones(524288,1)*3418;
idxA=unique(A);
countsA=(hist(A,idxA))';
i.e.
idxA=3148;
countsA=[zeros(1709,1); 524288; zeros(1708,1)];
What am I doing wrong?
To add to the other answers: you can replace hist by the explicit sum:
idxA = unique(A);
countsA = sum(bsxfun(#eq, A(:), idxA(:).'), 1);
idxA is a scalar, which means the number of bins in this context.
setting idxA as a vector instead e.g. [0,3418] will get you a hist with bins centered at 0 and 3418, similarly to what you got with idxB, which was also a vector
I think it has to do with:
N = HIST(Y,M), where M is a scalar, uses M bins.
and I think you are assuming it would do:
N = HIST(Y,X), where X is a vector, returns the distribution of Y
among bins with centers specified by X.
In other words, in the first case matlab is assuming that you are asking for 3418 bins

Draw imaginary numbers in matlab

i am trying to learn matlab.
I am trying to make a program that draw these imaginary numbers: ("," = decimal number)
and determine what of the 500 numbers that is closest the real axis.
And i need a little guidance.
What do i have to do to solve this task?
I was thinking about making a loop where all the "values" get stored in a array:
[code]
n= 1
while n < 500
value=1+0.1^n;
disp(value)
n=n+1[/code]
(seems like value is printing wrong values? and how to store in a array?)
And then somehow determine what number that is nearest the real axis and then display the value.
would be really grateful if someone could help me.
thanks in advance.
MATLAB creates imaginary numbers by appending an i or j term with the number. For example, if you wanted to create an imaginary number such that the real component was 1 and the imaginary component was 1, you would simply do:
>> A = 1 + i
A =
1.0000 + 1.0000i
You can see that there is a distinct real component as well as an imaginary component and is stored in A. Similarly, if you want to make the imaginary component have anything other than 1, you would need to add a constant in front of the i (or j). Something like:
>> A = 3 + 6i
A =
3.0000 + 6.0000i
Therefore, for your task, you simply need to create a vector of n between 1 to 500, input this into the above equation, then plot the resulting imaginary numbers. In this case, you would plot the real component on the x axis and the imaginary component on the y axis. Something like:
>> n = 1 : 500;
>> A = (1 + 0.1i).^n;
>> plot(real(A), imag(A));
real and imag are functions in MATLAB that access the real and imaginary components of complex numbers stored in arrays, matrices or single values. As noted by knedlsepp, you can simply plot the array itself as plot can handle complex-valued arrays:
>> plot(A);
Nice picture btw! Be mindful of the . operator appended with the ^ operator. The . means an element-wise operation. This means that we wish to apply the power operation for each value of n from 1 to 500 with 1 + 0.1i as the base. The result would be a 500 element array with the resulting calculations. If we did ^ by itself, we would be expecting to perform a matrix power operation, when this is not the case.
The values that you want to analyze for each value of n being applied to the equation in your post are stored in A. We then plot the real and imaginary components on the graph. Now if you want to find which numbers are closest to the real axis, you simply need to find the smallest absolute imaginary component of the numbers stored in A, then search for all of those numbers that share this number.
>> min_dist = min(abs(imag(A)));
>> vals = A(abs(imag(A)) == min_dist)
vals =
1.3681 - 0.0056i
This means that the value of 1.3681 - 0.0056i is the closest to the real axis.

Resources