Linprog error-Matlab - matlab

I just tried to solve a simple linear programming problem using matlab, It is pretty easy:
Find x that minimizes f(x) = –5x1 – 4x2 –6x3, subject to
x1 – x2 + x3 ≤ 20
3x1 + 2x2 + 4x3 ≤ 42
3x1 + 2x2 ≤ 30
0 ≤ x1, 0 ≤ x2, 0 ≤ x3.
%mfile: First, enter the coefficient
clc;
clear all;
close all;
f = [-5; -4; -6];
A = [1 -1 1
3 2 4
3 2 0];
b = [20; 42; 30];
lb=zeros(3,1);
x = linprog(f,A,b,[],[],lb);
when I run this program it doesn't return x values, and returns this error:
Error in linprog1 (line 10)
x = linprog(f,A,b,[],[],lb);
what's the problem, my matlab have optimization toolbox, why it doesn't know linprog? what should I do now?
Thank you all
-Maryam

After some investigation (see comments to the original question for details) it transpired that as well as the MATLAB Optimization Toolbox's linprog, the questioner also had on her computer a copy of something like this linprog.m -- which I suspect is an ancestor of what's now in the Optimization Toolbox, but takes its arguments in a different order.
Either the "old" linprog.m or the one in the OT is capable of solving the questioner's linear program. So the options are:
Use the "old" one, adjusting the code appropriately.
Remove (or move elsewhere, or rename) the "old" one and use the one in the Optimization Toolbox.

Related

Matlab system of equations solver returns incorrect answers

It's not clear how the system of equations solver works. I looked at the documentation and attempted to replicate it to get a solution to a physics problem but got the incorrect answer.
The problem I am trying to solve is a statics physics problem. F1 and F3 are vectors that are pointed up and to the right in the first quadrant. 45 degrees represents the angle from the x axis to F1, and g represents the angle from the x axis to F3.
F2 is a vector pointed down and to the left in the third quadrant. 45 degrees also represents the angle from the x axis to F2.
The problem is to find the values of F3 and g to make the system stable.
after getting the incorrect answer I checked to see if the matlab answer was maybe just a different answer that also solves the system but after checking it didn't work.
theta = 45;
F1 = 8;
F2 = 16;
syms F3 g;
eq1 = F1*cosd(theta) + F3*cosd(g) == F2*cosd(theta);
eq1 = F1*sind(theta) + F3*sind(g) == F2*sind(theta);
sol = solve([eq1,eq2],[F3,g]);
double(sol.F3)
double(sol.g)
The output was F3 = 45 and g = -135
the answer should be F3 = 8 and g = 45 degrees.
I am certain that the equations that I used are correct because when I put them into desmos and graphed them I got the correct answer. So the problem must have been my syntax in the script.
Typo here:
syms F3 g;
eq1 = F1*cosd(theta) + F3*cosd(g) == F2*cosd(theta);
eq1 = F1*sind(theta) + F3*sind(g) == F2*sind(theta); % HERE
The second equation should be eq2, not eq1. eq2 is probably cached from previous computations and you used that instead.
Running this now I get:
>> double(sol.F3)
ans =
8
-8
>> double(sol.g)
ans =
45
-135
You can discard the negative solutions as they don't make sense physically, so you do indeed get 8 and 45 as per your expectations.
Word of advice
Use clearvars in your MATLAB script before you start any work. It prevents caching problems such as above.

Using tf() function in MATLAB

I'm trying to input this transfer function in matlab, but I can't figure out how because it has both positive and negative exponents.
If I do H = tf([1],[1 1 1 1],0.1,'variable','z^-1') I almost get it, but I can't figure out how to add the positive z to the bottom. I'm trying to use this H to plot the poles and zeros with pzmap(H).
To avoid negative exponents, we can multiply both the denominator and the numerator by z^3:
H = tf([1 0 0 0 0],[1 1 1 1 1],0.1,'variable','z')
Or divide its by z
H = tf([1],[1 1 1 1 1],0.1,'variable','z^-1')
You can create
z = tf('z', 0.1)
and then create any transfer function you want, e.g.
H = z / (1 + z + z^-1 + z^-2 + z^-3)
However, Matlab automatically adds additional pole-zero pairs at z=0, to make the transfer function H contain only z and no z^-1. Therefore, you will see multiple poles at z=0 instead of only one. Unfortunately I haven't found a solution to stop Matlab from doing that...
What you refer to as a transfer function is actually called DSP representation due to their implementation properties. In that every power of z is a unit delay. Hence, you have to use the filt. In this representation z terms should have nonpositive powers hence if you factor out one z from the denominator and cancel out you get
H = filt(1,[1,1,1,1,1])

Ways around pinv([inf])=NaN in Octave/Matlab

I am using Octave 3.8.1, a Matlab-like program. I'd like to generalize 1/x to the case where x may be a scalar or a matrix. Replacing 1/x with inv(x) or pinv(x) works for most x, except:
octave:1> 1/inf
ans = 0
octave:2> pinv([inf])
ans = NaN
octave:3> inv([inf])
warning: inverse: matrix singular to machine precision, rcond = 0
ans = Inf
Should I convert NaN to 0 afterwards to get this to work? Or have I missed something? Thanks!
The Moore–Penrose pseudo inverse, which is the basis for Matab and octave's pinv, is implemented via completely different algorithm than the inv function. More specifically, singular value decomposition is used, which require's finite-valued matrices (they also can't be sparse). You didn't say if your matrices are square or not. The real use of pinv is for solving non-square systems (over- or underdetermined).
However, you shouldn't be using pinv or inv for your application, no matter the dimension of your matrices. Instead you should use mldivide (octave, Matlab), i.e., the backslash operator, \. This is much more efficient and numerically robust.
A1 = 3;
A2 = [1 2 1;2 4 6;1 1 3];
A1inv = A1\1
A2inv = A2\eye(size(A2))
The mldivide function handles rectangular matrices too, but you will get different answers for underdetermined systems compared to pinv because the two use different methods to choose the solution.
A3 = [1 2 1;2 4 6]; % Underdetermined
A4 = [1 2;2 4;1 1]; % Overdetermined
A3inv = A3\eye(min(size(A3))) % Compare to pinv(A3), different answer
A4inv = A4\eye(max(size(A4))) % Compare to pinv(A4), same answer
If you run the code above, you'll see that you get a slightly different result for A3inv as compared to what is returned by pinv(A3). However, both are valid solutions.

piece-wise linear curve fitting with MATLAB

In my experiment, I need to approximate or fitting a measurement y = f_m(x) with n linear segments. Value of n can be selected to be 1, 2, 3, 4, 5... and probably less than 10. For clarity, it's good if the errors from different cases can be compared to find the one with smallest error.
I've found one example using MATLAB (link):
% Random data...
xdata = linspace(-2,3,101);
ydata = log(abs(10./(10+1i*10.^xdata))) + 0.5*randn(size(xdata));
plot(xdata,ydata)
F = #(B,xdata) min(B(1),B(2)+B(3)*xdata); %Form of the equation
IC = [max(ydata) max(ydata) 0]; %Initial guess
B = lsqcurvefit( F,IC,xdata,ydata,[min(ydata) -inf -inf],[max(xdata) inf 0]);
hold all;
plot(xdata,F(B,xdata));
a = (B(1) - B(2)) / B(3)
cte = B(1)
c = B(2)
d = B(3)
This is similar to what I'm looking for in the case of 2 segments. I tried to modify this function to suit my need with changing the function handle:
F = #(B,xdata) min(B(1),B(2)+B(3)*xdata); %Form of the equation
to
F = #(B,xdata) min(B(1)+B(2)*xdata,B(3)+B(4)*xdata);
but it seems my modification results in 2 segments on the same line.
I don't know much about MATLAB function handle. Especially here, there is "min" function in it. Moreover, how should I do to extend this example to several linear segments?
Thank you in advance!!
Edit01:
Thanks!! your answer has made my code run as desired. But, may I ask a little on the question here. As previously mentioned, I originally want to extend the approximation to several linear segments. So, I go like:
F = #(B,xdata) min(B(1)+B(2)*xdata, B(3)+B(4)*xdata, B(5)+B(6)*xdata); %Form of the equation
IC = [max(ydata) max(ydata) max(ydata) max(ydata) max(ydata) 0]; %Initial guess
B = lsqcurvefit( F,IC,xdata,ydata,[min(ydata) -inf -inf -inf -inf -inf],[max(xdata) inf inf inf inf 0]);
but MATLAB response with I.C. error:
Failure in initial user-supplied objective function evaluation
Can you help me shortly with the I.C here? and what's with the "min" function in function handle?
I get the following error when running your code :
??? Error using ==> lsqncommon at 101
LSQCURVEFIT cannot continue because user supplied objective function failed with the following error:
Attempted to access B(4); index out of bounds because numel(B)=3.
Hence, this means that there is nothing in B(4). I would try to modify IC, lb and ub to have 4 elements.
So try to put these two lines in your code :
IC = [max(ydata) max(ydata) max(ydata) 0]; %Initial guess
B = lsqcurvefit( F,IC,xdata,ydata,[min(ydata) -inf -inf -inf],[max(xdata) inf inf 0]);

Given f(x) a polynomial in DocPolynom format, how to find f(x-1) as a polynomial? (MatLab)

I'm using DocPolynom a lot at the moment (see here if unfamiliar: http://www.mathworks.co.uk/help/techdoc/matlab_oop/f3-28024.html)
I have a polynomial f = DocPolynom(v) where v is a vector of coefficients. I really would like to be able to convert f to the polynomial corresponding to f(x-a), where a is a pre-determined constant. Does anyone know if/how I can do this?
Thanks!
Although not a direct answer, since you know the coefficients of the polynomial, you can evaluate the polynomial by polyval at the inputs x-a and using the resultant output you can use polyfit to get the coefficients of the polynomial that passes through your data.
v=[1 2 3];
x=1:3;
a=2;
y=polyval(v,x-a);
polyfit(x,y,2) % 2 here is the order of your polynomial (i.e. length(v)-1)
ans =
1.0000 -2.0000 3.0000
To do this, you need at least N+1 data points, where N is the order of your polynomial.
I'm not sure what this object you are writing is supposed to do, but you might play with my sympoly toolbox, which allows symbolic computation on polynomials. It is on the file exchange.
If all you have are simple polynomials, you can always use conv to compute powers of (x - a), adding them together. Thus, if we have the polynomial
P(x) = 3*x^2 + 2*x + 1
and we wish to form the polynomial Q(x) = P(x-3), it takes only a few operations.
Q = 3*conv([1 -3],[1 -3]) + 2*conv([0 1],[1 -3]) + 1*conv([0 1],[0 1])
Q =
3 -16 22