What type of operation should you use on single expressions containing vectors and numbers in Matlab? - matlab

I am trying to produce a contour plot of the following equation in Matlab.
theta=[(k+0.5)^2+t^2]^(-1/2)-[(k-0.5)^2+t^2]^(-1/2).
This is how I initially expressed it.
k=linspace(-1,1,20);
t=linspace(-0.5,0.5,20);
[K,T]=meshgrid(k,t);
Z=((K+0.5)^2+T.^2)^-0.5 -((K-0.5)^2+T.^2)^-0.5;
contour(K,T,Z, 'ShowText', 'on')
I'm getting the error message 'Input arguments for contour must be real.' so assuming I have expressed the equation wrong in the 4th line. I'm confused as to what type of operation I should use for expressions such as (K+0.5)^2+T.^2, where there are both vectors and numbers. How should I express it in Matlab syntax?
Apologies if the question is really basic. Absolute beginner.

The immediate error is because Z contains complex values (has non-zero imaginary components).
The real issue though is that you have used the matrix power (^) rather than an element-wise power (.^) in some places in your definition of Z.
Your expression to compute Z should actually be:
Z = ((K + 0.5).^2 + T.^2).^-0.5 - ((K - 0.5).^2 + T.^2).^-0.5;

Related

For loop equation into Octave / Matlab code

I'm using octave 3.8.1 which works like matlab.
I have an array of thousands of values I've only included three groupings as an example below:
(amp1=0.2; freq1=3; phase1=1; is an example of one grouping)
t=0;
amp1=0.2; freq1=3; phase1=1; %1st grouping
amp2=1.4; freq2=2; phase2=1.7; %2nd grouping
amp3=0.8; freq3=5; phase3=1.5; %3rd grouping
The Octave / Matlab code below solves for Y so I can plug it back into the equation to check values along with calculating values not located in the array.
clear all
t=0;
Y=0;
a1=[.2,3,1;1.4,2,1.7;.8,5,1.5]
for kk=1:1:length(a1)
Y=Y+a1(kk,1)*cos ((a1(kk,2))*t+a1(kk,3))
kk
end
Y
PS: I'm not trying to solve for Y since it's already solved for I'm trying to solve for Phase
The formulas located below are used to calculate Phase but I'm not sure how to put it into a for loop that will work in an array of n groupings:
How would I write the equation / for loop for finding the phase if I want to find freq=2.5 and amp=.23 and the phase is unknown I've looked online and it may require writing non linear equations which I'm not sure how to convert what I'm trying to do into such an equation.
phase1_test=acos(Y/amp1-amp3*cos(2*freq3*pi*t+phase3)/amp1-amp2*cos(2*freq2*pi*t+phase2)/amp1)-2*freq1*pi*t
phase2_test=acos(Y/amp2-amp3*cos(2*freq3*pi*t+phase3)/amp2-amp1*cos(2*freq1*pi*t+phase1)/amp2)-2*freq2*pi*t
phase3_test=acos(Y/amp3-amp2*cos(2*freq2*pi*t+phase2)/amp3-amp1*cos(2*freq1*pi*t+phase1)/amp3)-2*freq2*pi*t
Image of formula below:
I would like to do a check / calculate phases if given a freq and amp values.
I know I have to do a for loop but how do I convert the phase equation into a for loop so it will work on n groupings in an array and calculate different values not found in the array?
Basically I would be given an array of n groupings and freq=2.5 and amp=.23 and use the formula to calculate phase. Note: freq will not always be in the array hence why I'm trying to calculate the phase using a formula.
Ok, I think I finally understand your question:
you are trying to find a set of phase1, phase2,..., phaseN, such that equations like the ones you describe are satisfied
You know how to find y, and you supply values for freq and amp.
In Matlab, such a problem would be solved using, for example fsolve, but let's look at your problem step by step.
For simplicity, let me re-write your equations for phase1, phase2, and phase3. For example, your first equation, the one for phase1, would read
amp1*cos(phase1 + 2 freq1 pi t) + amp2*cos(2 freq2 pi t + phase2) + amp3*cos(2 freq3 pi t + phase3) - y = 0
Note that ampX (X is a placeholder for 1, 2, 3) are given, pi is a constant, t is given via Y (I think), freqX are given.
Hence, you are, in fact, dealing with a non-linear vector equation of the form
F(phase) = 0
where F is a multi-dimensional (vector) function taking a multi-dimensional (vector) input variable phase (comprised of phase1, phase2,..., phaseN). And you are looking for the set of phaseX, where all of the components of your vector function F are zero. N.B. F is a shorthand for your functions. Therefore, the first component of F, called f1, for example, is
f1 = amp1*cos(phase1+...) + amp2*cos(phase2+...) + amp3*cos(phase3+...) - y = 0.
Hence, f1 is a one-dimensional function of phase1, phase2, and phase3.
The technical term for what you are trying to do is find a zero of a non-linear vector function, or find a solution of a non-linear vector function. In Matlab, there are different approaches.
For a one-dimensional function, you can use fzero, which is explained at http://www.mathworks.com/help/matlab/ref/fzero.html?refresh=true
For a multi-dimensional (vector) function as yours, I would look into using fsolve, which is part of Matlab's optimization toolbox (which means I don't know how to do this in Octave). The function fsolve is explained at http://www.mathworks.com/help/optim/ug/fsolve.html
If you know an approximate solution for your phases, you may also look into iterative, local methods.
In particular, I would recommend you look into the Newton's Method, which allows you to find a solution to your system of equations F. Wikipedia has a good explanation of Newton's Method at https://en.wikipedia.org/wiki/Newton%27s_method . Newton iterations are very simple to implement and you should find a lot of resources online. You will have to compute the derivative of your function F with respect to each of your variables phaseX, which is very simple to compute since you're only dealing with cos() functions. For starters, have a look at the one-dimensional Newton iteration method in Matlab at http://www.math.colostate.edu/~gerhard/classes/331/lab/newton.html .
Finally, if you want to dig deeper, I found a textbook on this topic from the society for industrial and applied math: https://www.siam.org/books/textbooks/fr16_book.pdf .
As you can see, this is a very large field; Newton's method should be able to help you out, though.
Good luck!

MATLAB complicated integration

I have an integration function which does not have indefinite integral expression.
Specifically, the function is f(y)=h(y)+integral(#(x) exp(-x-1/x),0,y) where h(y) is a simple function.
Matlab numerically computes f(y) well, but I want to compute the following function.
g(w)=w*integral(1-f(y).^(1/w),0,inf) where w is a real number in [0,1].
The problem for computing g(w) is handling f(y).^(1/w) numerically.
How can I calculate g(w) with MATLAB? Is it impossible?
Expressions containing e^(-1/x) are generally difficult to compute near x = 0. Actually, I am surprised that Matlab computes f(y) well in the first place. I'd suggest trying to compute g(w)=w*integral(1-f(y).^(1/w),epsilon,inf) for epsilon greater than zero, then gradually decreasing epsilon toward 0 to check if you can get numerical convergence at all. Convergence is certainly not guaranteed!
You can calculate g(w) using the functions you have, but you need to add the (ArrayValued,true) name-value pair.
The option allows you to specify a vector-valued w and allows the nested integral call to receive a vector of y values, which is how integral naturally works.
f = #(y) h(y)+integral(#(x) exp(-x-1/x),0,y,'ArrayValued',true);
g = #(w) w .* integral(1-f(y).^(1./w),0,Inf,'ArrayValued',true);
At least, that works on my R2014b installation.
Note: While h(y) may be simple, if it's integral over the positive real line does not converge, g(w) will more than likely not converge (I don't think I need to qualify that, but I'll hedge my bets).

Plotting an equation with two input variables using meshgrid() in MATLAB - matrix incompatibility

I am trying to plot a 3D graph of an equation that has two input variables: time, t and spring constant, K in order to investigate the effect of K on the output. I have looked in to how to plot a function with two input variables using meshgrid() and converting the two inputs into compatible matrices.
For multiplying one of those inputs, say 't'. The multiplication sign needs to be preceded by '.' e.g y = t.*C (where C is some constant). For two inputs it is the same; e.g y = t.*C + K.^2.
However I cannot find how to do that for division, if the variable is in the numerator I assume you can simply write the expression as say: t*1/C. However how do you write it when the variable is in the denominator as in 'C/t'. I have tried placing '.' after 't' in the denominator however I get an error:
Error using /
Matrix dimensions must agree.
Also do I need to put the '.' after the variable in an addition?
Apologies if all this seems vague. I can put in the actual equation however it extremely long and it works when only t is a variable and K is a constant so the equation itself is sound.
The operations that have to be preceded with a . to apply element-wise are:
Multiplication: .*
Division: ./
Power: .^
Thus, if A, B, and C are arrays, you write
y = (A.*B./C).^2

scipy generalized eigenproblem with positive semidefinite

Hi, guys!!!
I want to compute generalized eigendecomposition of the form:
Lf = lambda Af
by using scipy.sparse.linalg.eigs function, but get this error:
/usr/local/lib/python2.7/dist-packages/scipy/linalg/decomp_lu.py:61: RuntimeWarning: Diagonal number 65 is exactly zero. Singular matrix.
RuntimeWarning)
** On entry to DLASCL parameter number 4 had an illegal value
I am passing three arguments, a diagonal matrix, a positive semi-definite (PSD) matrix and numeric value K (first K eigenvalues). Matlab's eigs function performs well using the same input parameters, but in SciPy as I have understood, in order to compute with PSD I need to specify sigma parameter as well.
So, my question is: is there a way to avoid setting sigma parameter, as it is in MatLab, or if not, how to pick up sigma value?
Looking forward to getting advices or hints...
Thank you in advance!
The error appears to mean that in your generalized eigenproblem
L x = lambda A x
the matrix A is not positive definite (check the eigs docstring -- in your case the matrix is probably singular). This is a requirement for ARPACK mode 2. However, you can try specifying sigma=0 to switch to ARPACK mode 3 (but note that the meaning of the which parameter is inverted in this case!).
Now, I'm not sure what Matlab does, but a possibility is that it's calculating the pseudoinverse rather than the inverse of A. To emulate this, do
from scipy.sparse.linalg import LinearOperator
from scipy.linalg import lstsq
Ainv = LinearOperator(matvec=lambda x: lstsq(A, x)[0], shape=A.shape)
w, v = eigs(L, M=A, Minv=Ainv)
Check the results --- I don't know what will happen in this case.
Alternatively, you may try to specify a nonzero sigma. What you should select depends on the matrices involved. It affects the eigenvalues that are picked --- for instance with which='LM' are those for which lambda' = 1/(lambda - sigma) is large. Otherwise, it can probably be chosen arbitrarily, of course it's probably better for the Krylov progress if the transformed eigenvalues lambda' which you are interested in become well separated from the other eigenvalues.

Matrix dimension error while calling mldivide in MATLAB

I am getting this error while running my code:
Error using ==> mldivide Matrix dimensions must agree.
Here is my code :
%make the plots of phase and group velocity vs discreteness of the grid
c=1;
a=input('Please enter the ratio cdt/dx : ')
figure(1)
R=2:40;
plot(R,phase_vel(R,a)/c)
xlabel('R=l/dx')
ylabel('u_phase/c')
%figure(2)
%plot(group_vel(R,a),R,0,40)
%xlabel('R=l/dx')
%ylabel('u_group/c')
and here are my functions :
function phase_velocity = phase_vel(R,a)
%numerical phase velocity of the discrete wave
c=1;
phase_velocity=(2*pi*c)/(R*knum(R,a));
end
function group_velocity =group_vel(R,a )
%numerical group velocity of the discrete wave
c=1;
group_velocity=(a*sin(knum(R,a)))/(sin(2*pi*a/R))
end
function knumber = knum(R,a)
%This is the k wave number
knumber=acos((1/a)^2*(cos(2*pi*a/R)-1)+1);
end
How can I resolve this error?
EDIT: I used . operator in every equation and i changed the limits of R=4:40
If your goal is to apply your formulas to each individual value in the vector R then you should be performing all of your computations using the element-wise arithmetic operators .*, ./, and .^ instead of the matrix operators *, /, and ^.
Your error is probably occurring in the first call to your function knum, specifically when you try to compute 2*pi*a/R. Since 2*pi*a is a single scalar value, you get an error when trying to perform matrix right division / using the row vector R. The really weird thing is the error message:
??? Error using ==> mldivide
Matrix dimensions must agree.
which implies you are using the matrix left division operator \, which you clearly aren't. I tested this in MATLAB R2010b and I get the same incorrect function name appearing in my message. I think this may just be a typo in the error message, and I've dropped a note to the MATLAB folks to take a look at it and clear it up.
I don't have the Symbolic Math Toolbox, but your problem seems to be that you are using plot, a function which can deal with arrays of numbers, and feeding it the result of a symbolic calculation. Have a look at the Matlab Help, where the Topic Creating Plots of Symbolic Functions suggests using ezplot(). Alternatively you need to evaluate your symbolic expression for certain input values to create an array of numbers that plot can deal with - but you can't use double() for that since it wouldn't know what numbers to plug into your variables.