New to programing in matlab. I am currently trying to make a MATLAB program that will find the critical values of a multi-variable function and tell me whether each are a minimum, maximum, or saddle point. Unfortunately I always get the error : An array for multiple LHS assignment cannot contain LEX_TS_STRING
Any help will be very appreciated.
here's the code:
function [c,d] = critcalpoints(f)
syms x y
f(x,y)=x^3-3*x^2+5*x*y-7*y^2;
gradf = jacobian(f(x,y));
hessmatf = jacobian(gradf,[x,y]);
[xcr,ycr]=solve(gradf(1),gradf(2));
H1=subs(hessmatf,[x,y],[xcr(1),ycr(1)]);
H2=subs(hessmatf,[x,y],[xcr(2),ycr(2)]);
eig(H1);
eig(H2);
c = double(eig(H1));
d = double(eig(H2));
if (c(1) > 0 && d(1) > 0) || (c(2) > 0 && d(2) > 0)
print([xcr,ycr],' is a minimum')
elseif (c(1) < 0 && d(1) < 0) || (c(2) < 0 && d(2) < 0)
print( [xcr, ycr], ' is a maximum')
elseif (c(1) < 0 && d(1) > 0) || (c(1) > 0 && d(1) < 0)
print( [xcr, ycr], ' is a saddle point')
elseif (c(2) < 0 && d(2) > 0) || (c(2) > 0 && d(2) < 0)
print( [xcr, ycr], ' is a saddle point')
elseif (c(1)==0 || d(1)==0)
print( [xcr, ycr], ' is degenerate')
elseif (c(2)==0 || d(2)==0)
print( [xcr, ycr], ' is degenerate')
end
Cannot reproduce your error. The code can work but you need to change print to something else as print doesn't do what you think it does. The print function prints a figure that is open to file. Change it so that you display xcr and ycr first then display the right condition to satisfy after. Use disp instead:
syms x y
f(x,y)=x^3-3*x^2+5*x*y-7*y^2;
gradf = jacobian(f(x,y));
hessmatf = jacobian(gradf,[x,y]);
[xcr,ycr]=solve(gradf(1),gradf(2));
H1=subs(hessmatf,[x,y],[xcr(1),ycr(1)]);
H2=subs(hessmatf,[x,y],[xcr(2),ycr(2)]);
eig(H1);
eig(H2);
c = double(eig(H1));
d = double(eig(H2));
disp([xcr, ycr]); % Display the solutions first
if (c(1) > 0 && d(1) > 0) || (c(2) > 0 && d(2) > 0)
disp('is a minimum')
elseif (c(1) < 0 && d(1) < 0) || (c(2) < 0 && d(2) < 0)
disp('is a maximum')
elseif (c(1) < 0 && d(1) > 0) || (c(1) > 0 && d(1) < 0)
disp('is a saddle point')
elseif (c(2) < 0 && d(2) > 0) || (c(2) > 0 && d(2) < 0)
disp('is a saddle point')
elseif (c(1)==0 || d(1)==0)
disp('is degenerate')
elseif (c(2)==0 || d(2)==0)
disp('is degenerate')
end
I get:
[ 0, 0]
[ 59/42, 295/588]
is a maximum
I have a for loop code which I want to vectorize. Below is the initial for loop code, and the vectorized version of the code. The vectorized code isn't giving the same result as that of the parfor loop, hence I know something is wrong with the code. I would appreciate it if any member of the forum can help me review the vectorized code and see if they can point out my errors to me. Thank you in advance.
% Initialization and precomputations
% w is an n x 1 vector
% beta: any number larger than 0. Usually set to 1.
Here is the for-loop code I need to vectorize:
f = zeros(n,1);
x = w;
y = w;
rho = 1;
v = f – (rho*y);
rhow = rho*w;
n = length(w);
parfor i = 1 : n
if w(i) >= 0
if v(i) < -rhow(i) – beta – 1
x(i) = (-beta -1 -v(i))/rho;
elseif (-rhow(i) – beta – 1 <= v(i)) && (v(i) <= -rhow(i) + beta – 1)
x(i) = w(i);
elseif (-rhow(i) + beta – 1 < v(i)) && (v(i) < beta – 1)
x(i) = (beta – 1 -v(i))/rho;
elseif (beta – 1 <= v(i)) && (v(i) <= beta + 1)
x(i) = 0;
else
x(i) = (beta + 1 – v(i))/rho;
end
else
if v(i) < -beta -1
x(i) = (-beta -1 – v(i))/rho;
elseif (-beta – 1 <= v(i) )&& (v(i) <= -beta + 1)
x(i) = 0;
elseif (-beta + 1 < v(i)) && (v(i) < -rhow(i) – beta + 1)
x(i) = (-beta + 1 – v(i))/rho;
elseif (-rhow(i) – beta + 1 <= v(i)) && (v(i) <= -rhow(i) + beta + 1)
x(i) = w(i);
else
x(i) = (beta + 1 – v(i))/rho;
end
end
end
======================================================================
And here is my vectorized version of the code above:
cond1 = (w >= 0);
cond2 = (w >= 0) & (v < -rhow-beta-1);
x(cond2) = (-beta-1-v(cond2))/rho;
cond3 = (w>=0)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1);
x(cond3) = w(cond3);
cond4 = (w>=0) & (-rhow +beta - 1 < v) & (v < beta - 1);
x(cond4) = (beta - 1 - v(cond4))/rho;
cond5 = (w>=0) & (beta - 1 <= v) & (v <= beta + 1);
x(cond5) = 0;
cond6 = (~cond2);
x(cond6) = (beta + 1 - v(cond6))/rho;
cond7 = ((~cond1) & v < -beta -1);
x(cond7) = (-beta -1 - v(cond7))/rho;
cond8 = ((~cond1) & (-beta - 1 <= v) & (v <= -beta + 1));
x(cond8) = 0;
cond9 = ((~cond1) & (-beta + 1 < v) & (v < -rhow - beta + 1));
x(cond9) = (-beta + 1 - v(cond9))/rho;
cond10 = ((~cond1) & (-rhow - beta + 1 <= v) & (v <= -rhow + beta + 1));
x(cond10) = w(cond10);
cond11 = (~cond1);
x(cond11) = (beta + 1 - v(cond11))/rho;
I'm adding another answer with all the conditionals checked:
cond1 = (w >= 0);
cond2 = cond1 & (v < -rhow – beta – 1);
cond3 = cond1 & ((-rhow – beta – 1 <= v) && (v <= -rhow + beta – 1));
cond4 = cond1 & ((-rhow + beta – 1 < v) && (v < beta – 1));
cond5 = cond1 & ((beta – 1 <= v) && (v <= beta + 1));
cond6 = cond1 & (v > beta + 1)
cond7 = ~cond1 & (v < -beta -1);
cond8 = ~cond1 & ((-beta – 1 <= v ) && (v <= -beta + 1));
cond9 = ~cond1 & ((-beta + 1 < v) && (v < -rhow – beta + 1));
cond10 = ~cond1 & ((-rhow – beta + 1 <= v) && (v <= -rhow + beta + 1));
cond11 = ~cond1 & (v > -rhow + beta + 1);
x(cond2)=... to x(cond11)=... remain the same.
Hope this works.
Here is one mistake, cond6 is not equivalent to the original first else
cond2 = (w >= 0) & (v < -rhow-beta-1);
cond6 = (~cond2);
x(cond6) = (beta + 1 - v(cond6))/rho;
in the original this is:
if w(i) >= 0
if v(i) < -rhow(i) – beta – 1
...
else
x(i) = (beta + 1 – v(i))/rho; %this should be cond6
end
end
The else should be evaluated like this (If I'm not mistaken)
x(cond1) = (beta + 1 - v(cond6))/rho;
and before all the others up to cond5.
I did not check all the code, so if this doesn't solve your problem let me know.
This is really basic question. I have an array "relevant_IDs". I need to store 1 to 100 values in it when variable category is 1. Similarly, 101 to 200 when category is 2. So on till 901 to 1000 when category is 10.
I have written code for it but it is not inserting 100 values in it.
Code:
for i=1: 1000
if(category==1 && i>0 && i< 101)
relevant_IDs(i) = i;
end
if(category==2 && i>100 && i< 201)
relevant_IDs(i) = i;
end
if(category==3 && i>200 && i< 301)
relevant_IDs(i) = i;
end
if(category==4 && i>300 && i< 401)
relevant_IDs(i) = i;
end
if(category==5 && i>400 && i< 501)
relevant_IDs(i) = i;
end
if(category==6 && i>500 && i< 601)
relevant_IDs(i) = i;
end
if(category==7 && i>600 && i< 701)
relevant_IDs(i) = i;
end
if(category==8 && i>700 && i< 801)
relevant_IDs(i) = i;
end
if(category==9 && i>800 && i< 901)
relevant_IDs(i) = i;
end
if(category==10 && i>900 && i< 1001)
relevant_IDs(i) = i;
end
end
Something like this should work and be much quicker:
relevant_IDs = (category - 1) * 100 + (1:100);
You could also just generate the whole thing (numbers from 1 to 1000), then index into the matrix using category value as index to get the desired relevant_IDs:
relevant_IDs = reshape(1:1000, [100,10]).';
relevant_IDs(category,:) % this will return a 1x100 row vector
% (category is a number from 1 to 10)
Alrighty, it's that time of week again where I am officially throwing my hands up in the air with MATLAB and asking for help. My goal this week is to try and make a function that takes in two inputs, which are strings that say 'Rock, Paper, Scissors' (or whatever the choices are), it then outputs one of three strings 'Player 1 Wins!', 'Player 2 Wins!' or 'Keep Playing!'. To win, the player must beat the other two out of three times (a tie counts as a loss for both players)
function[winner] = RockPaperScissors(player1, player2)
[move1, others] = strtok(player1, ',');
[move2, rest] = strtok(others, ',');
[move3, ~] = strtok(rest, ',');
[go1, others] = strtok(player2, ',');
[go2, rest] = strtok(others, ',');
[go3, ~] = strtok(rest, ',');
Counter1 = 0;
Counter2 = 0;
for i = 1:3
if strcmp(move1, 'Rock') && strcmp(go1, 'Paper')
Counter2 = Counter2 + 1;
elseif strcmp(move1, 'Rock') && strcmp(go1, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move1, 'Rock') && strcmp(go1, 'Rock')
Counter1 = 0;
elseif strcmp(move1, 'Paper') && strcmp(go1, 'Paper')
Counter1 = 0;
elseif strcmp(move1, 'Paper') && strcmp(go1, 'Rock')
Counter1 = Counter1 + 1;
elseif strcmp(move1, 'Paper') && strcmp(go1, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move1, 'Scissors') && strcmp(go1, 'Scissors')
Counter1 = 0;
elseif strcmp(move1, 'Scissors') && strcmp(go1, 'Paper')
Counter1 = Counter1 + 1;
elseif strcmp(move1, 'Scissors') && strcmp(go1, 'Rock')
Counter2 = Counter2 + 1;
end
if strcmp(move2, 'Rock') && strcmp(go2, 'Paper')
Counter2 = Counter2 + 1;
elseif strcmp(move2, 'Rock') && strcmp(go2, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move2, 'Rock') && strcmp(go2, 'Rock')
Counter1 = 0;
elseif strcmp(move2, 'Paper') && strcmp(go2, 'Paper')
Counter1 = 0;
elseif strcmp(move2, 'Paper') && strcmp(go2, 'Rock')
Counter1 = Counter1 + 1;
elseif strcmp(move2, 'Paper') && strcmp(go2, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move2, 'Scissors') && strcmp(go2, 'Scissors')
Counter1 = 0;
elseif strcmp(move2, 'Scissors') && strcmp(go2, 'Paper')
Counter1 = Counter1 + 1;
elseif strcmp(move2, 'Scissors') && strcmp(go2, 'Rock')
Counter2 = Counter2 + 1;
end
if strcmp(move3, 'Rock') && strcmp(go3, 'Paper')
Counter2 = Counter2 + 1;
elseif strcmp(move3, 'Rock') && strcmp(go3, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move3, 'Rock') && strcmp(go3, 'Rock')
Counter1 = 0;
elseif strcmp(move3, 'Paper') && strcmp(go3, 'Paper')
Counter1 = 0;
elseif strcmp(move3, 'Paper') && strcmp(go3, 'Rock')
Counter1 = Counter1 + 1;
elseif strcmp(move3, 'Paper') && strcmp(go3, 'Scissors')
Counter2 = Counter2 + 1;
elseif strcmp(move3, 'Scissors') && strcmp(go3, 'Scissors')
Counter1 = 0;
elseif strcmp(move3, 'Scissors') && strcmp(go3, 'Paper')
Counter1 = Counter1 + 1;
elseif strcmp(move3, 'Scissors') && strcmp(go3, 'Rock')
Counter2 = Counter2 + 1;
end
if max(Counter1, Counter2) == Counter2
winner = 'Player 2 Wins!';
elseif max(Counter1, Counter2) == Counter1
winner = 'Player 1 Wins!';
elseif max(Counter1, Counter2) ~= (Counter1 || Counter2) % I tried making a Counter 3, did not work out
winner = 'Keep Playing!';
end
end
As you can see, I have most of this bad boy running. My issue now is that when I run the test case ' [winner1] = rockPaperScissors('Rock,Scissors,Scissors','Paper,Rock,Scissors')
It outputs my answer in a vertical 'ans' and not as winner. Additionally, it gives me 'Player 2 Win!' even though it should be a tie. I tried debugging it all, but can't figure out where my issue is. Bah!
Have you actually thought about using a table? It's perfect for your purpose!
Just an idea, how to do it alternatively. Please don't nail me on the fact, that I haven't considered all your restrictions and conditions, but it should be easy for you to adapt my function how you like it.
function RockPaperScissorsLizardSpock(player1, player2, rounds)
%// creating the table with all combinations
header = {'Rock';'Paper';'Scissors';'Lizard';'Spock'};
Rock = [0;-1;1;1;-1];
Paper = [1;0;-1;-1;1];
Scissors = [-1;1;0;1;-1];
Lizard = [-1;1;-1;0;1];
Spock = [1;-1;1;-1;0];
T = table(Rock,Paper,Scissors,Lizard,Spock,'RowNames',header);
%// play and display winners of every round
points = 0;
for ii = 1:rounds
pointsRound = T{player1(ii), player2(ii)}; %// no need for if-conditions
%// one line is enough
points = points + pointsRound;
if pointsRound > 0; disp(['Player 1 wins round ' num2str(ii) '!'])
elseif pointsRound < 0; disp(['Player 2 wins round ' num2str(ii) '!'])
else disp(['Draw in round ' num2str(ii) '!'])
end
end
%// display overall winner
if points > rounds/2; disp('Player 1 Wins!')
elseif points == 0; disp(['Draw!' num2str(ii) '!'])
else disp('Player 2 Wins!')
end
and now lets play:
player1 = {'Rock','Scissors','Scissors'}
player2 = {'Paper','Rock','Scissors'}
RockPaperScissorsLizardSpock(player1, player2, 3)
returns:
Player 1 wins round 1!
Player 1 wins round 2!
Tie in round 3!
Player 1 Wins!
you can also implement some advanced features, for example give names to the players:
function RockPaperScissorsLizardSpock(player1, player2, rounds)
plname = inputname(1);
p2name = inputname(2);
...
if pointsRound > 0; disp([plname ' wins round ' num2str(ii) '!'])
...
else disp([p2name ' Wins!'])
end
and
Sheldon = {'Spock','Spock','Spock'}
Penny = {'Paper','Rock','Scissors'}
RockPaperScissorsLizardSpock(sheldon, penny, 3)
yields
Sheldon wins round 1!
Penny wins round 2!
Penny wins round 3!
Penny Wins!
If you insist on your string input with commas:
Sheldon = 'Spock,Spock,Spock'
Penny = 'Paper,Rock,Scissors'
you need to add strsplit to the function:
player1= strsplit(player1,',')
player2= strsplit(player2,',')
You need to use the function strcmp instead of the == operator. The inputs are char arrays, which is why == is complaining about the dimensions.
Here's an example for your first if statement:
if strcmp(move1, 'Rock') && strcmp(go1, 'Paper')
winner1 = 'Player 2 Wins!';
Here I've made 2 changes, the first is to use strcmp, and the second to use scalar AND i.e. &&
See help strcmp and help && for more details.
I am trying to plot a best fit line on a probability density function with logarithmic axes. The Y-axis (PDF) is 10^-12 to 10^-28, while the X-axis is 10^10 to 10^20. I've tried polyfit, with no luck. Any ideas? Attached is my code.
Thanks,
Kevin
clc;
clear all;
load Aug2005_basin_variables.mat
% Initialize
j_len = length(W_SH);
prob_dens_all = zeros(j_len,30);
ii = 1 : j_len;
count(1:30) = 0;
bin(1:30) = 0;
for i = 1 : 30
bin(i) = 10^(11 + (0.3*i));
end
% Bin the Watts
for i = 1 : j_len
if((log10(W_SH(i)) >= 11) && (log10(W_SH(i)) < 11.3))
count(1) = count(1) + 1;
end
if((log10(W_SH(i)) >= 11.3) && (log10(W_SH(i)) < 11.6))
count(2) = count(2) + 1;
end
if((log10(W_SH(i)) >= 11.6) && (log10(W_SH(i)) < 11.9))
count(3) = count(3) + 1;
end
if((log10(W_SH(i)) >= 11.9) && (log10(W_SH(i)) < 12.2))
count(4) = count(4) + 1;
end
if((log10(W_SH(i)) >= 12.2) && (log10(W_SH(i)) < 12.5))
count(5) = count(5) + 1;
end
if((log10(W_SH(i)) >= 12.5) && (log10(W_SH(i)) < 12.8))
count(6) = count(6) + 1;
end
if((log10(W_SH(i)) >= 12.8) && (log10(W_SH(i)) < 13.1))
count(7) = count(7) + 1;
end
if((log10(W_SH(i)) >= 13.1) && (log10(W_SH(i)) < 13.4))
count(8) = count(8) + 1;
end
if((log10(W_SH(i)) >= 13.4) && (log10(W_SH(i)) < 13.7))
count(9) = count(9) + 1;
end
if((log10(W_SH(i)) >= 13.7) && (log10(W_SH(i)) < 14.0))
count(10) = count(10) + 1;
end
if((log10(W_SH(i)) >= 14.0) && (log10(W_SH(i)) < 14.3))
count(11) = count(11) + 1;
end
if((log10(W_SH(i)) >= 14.3) && (log10(W_SH(i)) < 14.6))
count(12) = count(12) + 1;
end
if((log10(W_SH(i)) >= 14.6) && (log10(W_SH(i)) < 14.9))
count(13) = count(13) + 1;
end
if((log10(W_SH(i)) >= 14.9) && (log10(W_SH(i)) < 15.2))
count(14) = count(14) + 1;
end
if((log10(W_SH(i)) >= 15.2) && (log10(W_SH(i)) < 15.5))
count(15) = count(15) + 1;
end
if((log10(W_SH(i)) >= 15.5) && (log10(W_SH(i)) < 15.8))
count(16) = count(16) + 1;
end
if((log10(W_SH(i)) >= 15.8) && (log10(W_SH(i)) < 16.1))
count(17) = count(17) + 1;
end
if((log10(W_SH(i)) >= 16.1) && (log10(W_SH(i)) < 16.4))
count(18) = count(18) + 1;
end
if((log10(W_SH(i)) >= 16.4) && (log10(W_SH(i)) < 16.7))
count(19) = count(19) + 1;
end
if((log10(W_SH(i)) >= 16.7) && (log10(W_SH(i)) < 17.0))
count(20) = count(20) + 1;
end
if((log10(W_SH(i)) >= 17.3) && (log10(W_SH(i)) < 17.6))
count(21) = count(21) + 1;
end
if((log10(W_SH(i)) >= 17.6) && (log10(W_SH(i)) < 17.9))
count(22) = count(22) + 1;
end
if((log10(W_SH(i)) >= 17.9) && (log10(W_SH(i)) < 18.2))
count(23) = count(23) + 1;
end
if((log10(W_SH(i)) >= 18.2) && (log10(W_SH(i)) < 18.5))
count(24) = count(24) + 1;
end
if((log10(W_SH(i)) >= 18.5) && (log10(W_SH(i)) < 18.8))
count(25) = count(25) + 1;
end
if((log10(W_SH(i)) >= 18.8) && (log10(W_SH(i)) < 19.1))
count(26) = count(26) + 1;
end
if((log10(W_SH(i)) >= 19.1) && (log10(W_SH(i)) < 19.4))
count(27) = count(27) + 1;
end
if((log10(W_SH(i)) >= 19.4) && (log10(W_SH(i)) < 19.7))
count(28) = count(28) + 1;
end
if((log10(W_SH(i)) >= 19.7) && (log10(W_SH(i)) < 20.0))
count(29) = count(29) + 1;
end
if((log10(W_SH(i)) >= 20.0) && (log10(W_SH(i)) < 20.3))
count(30) = count(30) + 1;
end
end
for i=1:30
prob(i) = count(i)/sum(count);
prob_dens(i) = prob(i)/bin(i);
end
% Check
sum(prob_dens.*bin);
prob_dens_all(i,:) = prob_dens(:);
%end
prob_dens_mean = zeros(1,30);
for i = 1 : 30
prob_dens_mean(1,i) = mean(prob_dens_all(:,i));
%prob_dens_std(1,i) = std(prob_dens_all(:,i));
end
% Plot
best_fit = polyfit(bin,log10(prob_dens_mean),11)
h = figure;
loglog(bin,prob_dens_mean,'ro','MarkerSize',10)
hold on;
plot(best_fit,'b')
t = title('Event Power Distribution, SHem, August 2005');
set(t, 'FontWeight', 'bold', 'FontSize', 12)
set(gca, 'FontWeight', 'bold', 'FontSize', 12)
xlabel('Event Power (W)');
ylabel('Probability Density');
print -dpng SHem_Wattage_PDF_AUG2005.png
I don't have your data, but here is an example using some random normally-distributed random data
x=randn(1000,1)+5; % create some data, keep numbers positive by adding 5
[n,xb]=hist(x); % Create the histogram
n = n/sum(n); % convert counts to a pdf
p=polyfit(log(xb), log(n), 3); % Do a 3rd order fit
loglog(xb,n, '*-', xb, exp(polyval(p, log(xb))), 'r')
grid on
legend('PDF', 'Fit', 0)