Why does in Octave the following
X = ones(10, 10)
X ^ 2
yields a 10x10 matrix with all elements set to 10?
I was not expecting this but rather having all elements squared (and therefore a matrix of 10x10 1 elements)
If you want the ^ operator to be applied element-by-element, use .^
Otherwise you will be doing matrix multiplication.
Related
I am a student trying to learn how to use Octave and I need help with plotting this thing right here the function I want to plot
The code looks like this:
x2 = 0:0.1:50;
y2 = power((1+(2.*x2/(exp(0.5.*x2)+(x2.^2)))), 0.5);
plot(x2, y2, '-b');
It feels like it should have plotted without problems but the plot in the figure appears to be completely empty, and I cannot wrap my head around why this might happen. Would love to know what am I doing wrong
If you inspect the value of y2 (simply type y2 and press enter) then you find that y2 is a single number rather than a vector.
To find out out why y2 is a single number we type in the calculation power((1+(2.*x2/(exp(0.5.*x2)+(x2.^2)))), 0.5) and remove the outer functions/operators step by step. Once the result is a vector we know that the last thing removed ruined the result.
In your case / turns out to be the culprit.
From Octave, Arithmetic Ops (emphasis mine):
x / y
Right division. This is conceptually equivalent to the expression (inv (y') * x')' but it is computed without forming the inverse of y'.
If the system is not square, or if the coefficient matrix is singular, a minimum norm solution is computed.
x ./ y
Element-by-element right division.
Therefore, replace / by ./.
x2 = 0:0.1:50;
y2 = power(1 + 2 .* x2 ./ (exp(0.5 .* x2) + (x2 .^ 2)), 0.5);
plot(x2, y2, '-b');
In Octave, one can do an element-wise multiplication between a full matrix and compatible (broadcastable) vector (i.e. MxN .* 1xN or MxN .* Mx1). But this does not seem to be applicable for sparse matrix.
Consider the following example,
v = (1:5)';
s = spdiags(v,0,5,5); % simple sparse matrix
s .* v; % <--- error 'nonconformant arguments (op1 is 5x5, op2 is 5x1)'
full(s) .* v; % <--- works but defeats sparse matrix
In the above simple case, with a diagonal sparse matrix, converting to full matrix can be avoided by converting v to diagonal matrix i.e.
s * diag(v); % <--- returns desired result
diag(v) * s; % <--- also results desired result
but for other cases, i.e. non-diagonal sparse matrix, it gets unnecessarily complicated by operand-order.
Is there a trick to doing broadcastable operation with sparse matrix? ...else is this a bug or feature (i.e. necessary)?
I have run a 3D Fourier Transform using FFTW (fftw_plan_dft_r2c_3d) and I would like to sum up the (log of the) values of the transform at every frequency, including the repeated frequencies that aren't actually stored in the output array (I understand the size is Nx x Ny x (Nz/2 + 1)). How do I do this without double counting?
Great question. Sorry of my answer is a little long-winded, I want to make sure I don’t make any mistakes. Here goes—
The sum-of-log-magnitudes of a complex-to-complex 3D FFT will be equal to the sum-of-log-magnitudes of a real-to-complex 3D FFT if you double-count all ‘slices’ (of the last dimension) of the latter that are missing from the former.
If Nz is even, that means double-count all slices other than the first and last slices.
If Nz is odd, double-count all slices except the first.
(This is because an even-length real-to-complex DFT includes the -π radians angular frequency (corresponding to a phasor of -1), whereas an odd-length one stops short of it. I never remember this pattern, so I always draw the N=4 vs N=3 phasors around the unit circle to remind myself whether odd or even includes -π rad.)
Here’s an experimental verification of the idea using Numpy/Python, whose notation for real-to-complex FFT I believe matches FFTW’s: generate an Nx = 10 by Ny = 20 by Nz = 8 real array. Compute its complex-to-complex 3D FFT (yielding an Nx by Ny by Nz complex array) and its real-to-complex 3D FFT (yielding Nx by Ny by (Nz/2+1) complex array). Verify that the sum-of-log-magnitudes of the former is the same as the sum-of-log-magnitudes of the latter if you double-count all but the first & last slices, since Nz is even.
The code:
import numpy as np
import numpy.fft as fft
Nx = 10
Ny = 20
Nz = 8
x = np.random.randn(Nx, Ny, Nz)
Xf = fft.fftn(x)
Xfr = fft.rfftn(x)
energyProduct1 = np.log10(np.abs(Xf)).sum()
lastSlice = -1 if Nz % 2 is 0 else None
energyProduct2 = np.log10(np.abs(np.dstack((Xfr, Xfr[:, :, 1:lastSlice])))).sum()
print('Difference: %g' % (energyProduct1 - energyProduct2))
# Difference: -4.54747e-13
If you re-run this with odd Nz, you will see that the difference between the complex-to-complex and the real-to-complex remains within machine precision of 0.
That np.dstack((Xfr, Xfr[:, :, 1:lastSlice)) (docs for dstack, fft.rfftn) stacks the rfftn output with its 2nd to penultimate slices in the 3rd dimension—penultimate because Nz is even, and you don’t want to double-count the 0 or -π DFT bins.
Of course, another way to do this is to compute the sum-of-log-magnitudes over the real-to-complex array, double it, then subtract the sum-of-log-magnitudes over the first slice and (if Nz is even) the last slice.
tl;dr Sum the log-magnitudes over the real-to-complex output. Double it. Subtract from this result the sum-log-magnitudes of the very first slice (in the 3rd dimension). If Nz is odd, you’re done. If Nz is even, also subtract the sum-log-magnitudes of the very last slice.
I want to calculate the integration of a matrix over a path. This matrix is in fact dependent on two variables. the answer of this integral would be a vector. it is:
Fn=integral(-(q ) Wn dГ)
q is a constant. Wn is a 2D matrix, N*n, which N is the number of the points (x,y) and n is the number of source points which create element of function and refers to different columns of this matrix. for example W2(1,2) is the matrix function value at point (x1,y1) for the source n=2.
I cannot use "trapz" for calculation of this integral, because in trapz(X,Y) the X should be a vector but in my case the function Wn is dependent on two variable (x,y), So the X in trapz would be a matrix instead of a vector.
how can I calculate this integral?
also, how should I implement the path in the calculation of my integral. My current path for integral calculation is a vertical line at x=0, 0
so many thanks in advance.
I found the answer. I should devide the boundary to strait lines between each 2 node,then calculate the integral using gauss-lojander method.
What it the best way to plot a vertical line using Octave?
So, I have two methods for this. One, I found, and the other I made up.
Method 1: From here.
%% Set x value where verticle line should intersect the x-axis.
x = 0;
%% plot a line between two points using plot([x1,x2],[y1,y2])
plot([x,x],[-10,10]);
Method 2: A slightly different approach, exact same result
%% Setup a vector of x values
x = linspace(0,0,100);
%% Setup a vector of y values
y = linspace(0,10,100);
%% Plot the paired points in a line
plot(x,y);
I think Method 2 may write more information to memory before the plot process and it's a line longer, so in my eyes, Method 1 should be the better option. If you prefer Method 2, make sure your x and y vectors are the same dimension or you'll end up with a bunch of dots where you're line should be.
Unfortunately the Octave documentation for doing obvious things can be ridiculously lousy with no working examples. Drawing a simple line on top of a plot is one.
As already mentioned, it's is very silly to plot straight lines in octave. It's a waste of memory and processing. Instead use the line() function, to draw on top of your plot.
The line() function require 2 non-standard x-values and y-values vectors, instead of the standard point-slope arguments for point A and point B, normally represented by (x1,y1) and (x2,y2). Instead, you need to write this as: X=(x1,x2) and Y=(y1,y2). Thus confusing every living soul!
Here is an example of the correct way to do this in Octave language:
pkg load statistics % Need to load the statistics package
x = randn (1,1000); % Normal Distribution of random numbers
clf; histfit(x) % Make a histogram plot of x and fit the data
ylim ([-20,100]) % Change the plot limits (to lift graph up)
% Draw the (vertical) line between (0,-10) and (0,90)
line ("xdata",[0,0], "ydata",[-10,90], "linewidth", 3)
With the result:
notation (x1,x2),(y1,y2) is really confusing and against textbooks.
Anyway, this is my way:
figure;
hold on;
% vertical line x=0
plot([0,0],[0,10]);
%horizontal line y=0
plot([0,10],[0,0]);
% vertical line x=2
plot([2,2],[0,10]);
hold off;