How to write a varying matrix in matlab? - matlab

I have this equation system a set of 1 ≤ n ≤ 30
−(2 + α)x1 + x2 = b1,
xj−1 − (2 + α)xj + xj+1 = bj , for 2 ≤ j ≤ 29,
x29 − (2 + α)x30 = b30.
α = 1
We assume that the membrane is held at the end points (i.e x0 = 0 and x31 = 0). There is no weight on the membrane so all bj = 0 for j = 1 . . . 30 except for j = 6 where a load is applied: b6 = 2.
I want to calculate LU factorization of the system .
I do not know how to implement the left side of the system in matlab.
The right side I made it like this :
b=[0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]';
How to do the left side?
Thanks

It's unclear why you have included the entire linear system if you are only interested in the LU factorization of A? Regardless, here is some code which generates your A matrix as described above, and solves the linear system and shows the LU factorization.
% equation A*X = b
b = zeros(30,1);
b(6) = 2;
alpha = 1;
A = zeros(30, 30);
A(1, 1) = -(2 + alpha);
A(1, 2) = 1;
for i = 2:29
A(i, i-1) = 1;
A(i, i) = -(2 + alpha);
A(i, i+1) = 1;
end
A(30, 29) = 1;
A(30, 30) = -(2 + alpha);
You can then get the LU factorization using lu(A) or solve the linear system of equations using linsolve(A,b).

Related

Matlab CPLEX: add multiple SOCP constraints in cplexmiqcp

I have written my problem in MATLAB, using CPLEX as the solver. Due issues that are beyond my control (it is feasible), the CPLEX class API screws up when solving my problem. So, based on post found elsewhere on the internet, I am trying to solve using the toolbox API.
To solve my problem I need to use cplexmiqcp, which has the inputs:
cplexmiqcp(H,f,Aineq,bineq,Aeq,beq,l,Q,r,sostype,sosind,soswt,varLB,varUB,vartype,x0,options);
I have multiple SOCP constraints, and using the class API, I am able to define each of them using a structure, such as:
for n=1:numQCs
cplex.Model.qc(n).a=QC.a{n};
cplex.Model.qc(n).Q=QC.Q{n,1};
cplex.Model.qc(n).sense=QC.sense{n};
cplex.Model.qc(n).rhs=QC.rhs{n};
cplex.Model.qc(n).lhs=QC.lhs{n};
end
But how do I define multiple quadratic constraints for cplexmiqcp inputs? These are l,Q,r. When I try creating a structure as before, I get "Error: incorrect l,Q,r."
The documentation for the cplexmiqcp toolbox function is here. Quoting the documentation, for l, Q, and r, we have:
l: Double column vector or matrix for linear part of quadratic constraints
Q: Symmetric double matrix or row cell array of symmetric double matrices for quadratic constraints
r: Double or double row vector for rhs of quadratic inequality constraints
So, when we want to create one quadratic constraint, we can give a double column vector, a symmetric double matrix, and a double for l, Q, and r, respectively. When we want to create multiple quadratic constraints, we need to provide a matrix, a row cell array of symmetric double matrices, and a row vector for l, Q, and r, respectively.
Consider the following simple model:
Minimize
obj: x1 + x2 + x3 + x4 + x5 + x6
Subject To
c1: x1 + x2 + x5 = 8
c2: x3 + x5 + x6 = 10
q1: [ - x1 ^2 + x2 ^2 + x3 ^2 ] <= 0
q2: [ - x4 ^2 + x5 ^2 ] <= 0
Bounds
x2 Free
x3 Free
x5 Free
End
The MATLAB code would look like the following:
H = [];
f = [1 1 1 1 1 1]';
Aineq = []
bineq = []
Aeq = [1 1 0 0 1 0;
0 0 1 0 1 1];
beq = [8 10]';
l = [0 0;
0 0;
0 0;
0 0;
0 0;
0 0;];
Q = {[-1 0 0 0 0 0;
0 1 0 0 0 0;
0 0 1 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0], ...
[0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 -1 0 0;
0 0 0 0 1 0;
0 0 0 0 0 0]};
r = [0 0];
sostype = [];
sosind = [];
soswt = [];
lb = [ 0; -inf; -inf; 0; -inf; 0];
ub = []; % implies all inf
ctype = []; % implies all continuous
options = cplexoptimset;
options.Display = 'on';
options.ExportModel = 'test.lp';
[x, fval, exitflag, output] = cplexmiqcp (H, f, Aineq, bineq, Aeq, beq,...
l, Q, r, sostype, sosind, soswt, lb, ub, ctype, [], options);
fprintf ('\nSolution status = %s \n', output.cplexstatusstring);
fprintf ('Solution value = %f \n', fval);
disp ('Values =');
disp (x');

Make a one simple code from several similar code

Hello everybody I have a very simple problem, I have too many data y, p and r. So I want to calculate it in a single code.
This an example of my code if I breakdown into separate code
y1=45
y2=56
y3=67
p1=34
p2=45
p3=56
r1=23
r2=34
r3=45
Ryaw1=[cosd(y1) -sind(y1) 0;
sind(y1) cosd(y1) 0;
0 0 1]
Rpitch1=[cosd(p1) 0 sind(p1);
0 1 0;
-sind(p1) 0 cos(p1)]
Rroll1=[1 0 0;
0 cosd(r1) -sind(r1);
0 sind(r1) cosd(r1)]
R1=Ryaw1*Rpitch1*Rroll1
Coordinate1=R1*X0
Ryaw2=[cosd(y2) -sind(y2) 0;
sind(y2) cosd(y2) 0;
0 0 1]
Rpitch2=[cosd(p2) 0 sind(p2);
0 1 0;
-sind(p2) 0 cos(p2)]
Rroll2=[1 0 0;
0 cosd(r2) -sind(r2);
0 sind(r2) cosd(r2)]
R2=Ryaw2*Rpitch2*Rroll2
Coordinate2=R2*X0
Ryaw3=[cosd(y3) -sind(y3) 0;
sind(y3) cosd(y3) 0;
0 0 1]
Rpitch3=[cosd(p3) 0 sind(p3);
0 1 0;
-sind(p3) 0 cos(p3)]
Rroll3=[1 0 0;
0 cosd(r3) -sind(r3);
0 sind(r3) cosd(r3)]
R3=Ryaw3*Rpitch3*Rroll3
Coordinate3=R3*X0
Coordinate=[Cooedinate1 Coordinate2 Coordinate3]
The goals is to find "Coordinate" (in matrix - combined from Coordinate1, Coordinate2, Coordinate3, .... ,Coordinate..) from every y, p and r data with the same "X0" as a single primary data for calculation.
Sorry for my bad english,
Thanks :)
Use vectors and matrices instead of individual scalars. These are indexed in almost the same way as you had before, i.e. y1 becomes y(1).
Then you can easily loop over the code 3 times and save the repetition.
See my commented code below.
% Define some X0. This should be a column vector.
X0 = [1; 2; 3];
% Make y,p,r into 3 element vectors
y = [45 56 67];
p = [34 45 56];
r = [23 34 45];
% Make R, Ryaw, Rpitch and Rroll 3x3x3 matrices
R = zeros(3,3,3);
Ryaw = zeros(3,3,3);
Rpitch = zeros(3,3,3);
Rroll = zeros(3,3,3);
% Make Coordinate a 3x3 matrix
Coordinate = zeros(3,3);
% Loop k from 1 to 3
% For each 3x3x3 matrix, the kth 3x3 matrix is equivalent to your Ryawk, Rpitchk, Rrollk, Rk
for k = 1:3
Ryaw(:,:,k) = [cosd(y(k)) -sind(y(k)) 0
sind(y(k)) cosd(y(k)) 0
0 0 1];
Rpitch(:,:,k)= [cosd(p(k)) 0 sind(p(k))
0 1 0
-sind(p(k)) 0 cos(p(k))];
Rroll(:,:,k) = [1 0 0
0 cosd(r(k)) -sind(r(k))
0 sind(r(k)) cosd(r(k))];
R(:,:,k) = Ryaw(:,:,k)*Rpitch(:,:,k)*Rroll(:,:,k);
Coordinate(:,k) = R(:,:,k)*X0;
end
disp(Coordinate)

How to formulate this expression

I am new to MATLAB and I want to formulate the following lease square expression in Matlab. I have some codes that I am typing here. But the optimization problem solution seems not to be correct. Does anyone has an idea why?
First, I want to solve the heat equation
$$T_t(x,t) = - L_x . T(x,t) + F(x,t)$$
where L_x is Laplacian matrix of the graph.
then find y from the following least square.
$$ \min_y \sum_{j} \sum_{i} (\hat{T}_j(t_i) - T_j(t_i, y))^2$$
Thanks in advance!!
Here is my code:
%++++++++++++++++ main ++++++++++++++++++++
% incidence matrix for original graph
C_hat = [ 1 -1 0 0 0 0;...
0 1 -1 0 0 -1;...
0 0 0 0 -1 1;...
0 0 0 1 1 0;...
-1 0 1 -1 0 0];
% initial temperature for each vertex in original graph
T_hat_0 = [0 7 1 9 4];
[M_bar,n,m_bar,T_hat_heat,T_hat_temp] = simulate_temp(T_hat_0,C_hat);
C = [ 1 1 -1 -1 0 0 0 0 0 0;...
0 -1 0 0 1 -1 1 0 0 0;...
0 0 1 0 0 1 0 -1 -1 0;...
0 0 0 1 0 0 -1 0 1 -1;...
-1 0 0 0 -1 0 0 1 0 1];
%
% initial temperature for each vertex in original graph
T_0 = [0 7 1 9 4];
%
% initial temperature simulation
[l,n,m,T_heat,T_temp] = simulate_temp(T_0,C);
%
% bounds for variables
lb = zeros(m,1);
ub = ones(m,1);
%
% initial edge weights
w0 = ones(m,1);
% optimization problem
% w = fmincon(#fun, w0, [], [], [], [], lb, ub);
%++++++++++++++++++++ function++++++++++++++++++++++++++++
function [i,n,m,T_heat,T_temp] = simulate_temp(T,C)
%
% initial conditions
delta_t = 0.1;
M = 20; %% number of time steps
t = 1;
[n,m] = size(C);
I = eye(n);
L_w = C * C';
T_ini = T';
Temp = zeros(n,1);
% Computing Temperature
%
for i=1:M
K = 2*I + L_w * delta_t;
H = 2*I - L_w * delta_t;
%
if i == 1
T_heat = (K \ H) * T_ini;
%
t = t + delta_t;
else
T_heat = (K \ H) * Temp;
%
t = t + delta_t;
end
% replacing column of T_final with each node temperature in each
% iteration. It adds one column to the matrix in each step
T_temp(:,i) = T_heat;
%
Temp = T_heat;
end
end
%++++++++++++++++++ function+++++++++++++++++++++++++++++++++++++++++
function w_i = fun(w);
%
for r=1:n
for s=1:M_bar
w_i = (T_hat_temp(r,s) - T_temp(r,s)).^2;
end
end
To give a more clear answer, I need more information about what form you have the functions F_j and E_j in.
I've assumed that you feed each F_j a value, x_i, and get back a number. I've also assumed that you feed E_j a value x_i, and another value (or vector) y, and get back a value.
I've also assumed that by 'i' and 'j' you mean the indices of the columns and rows respectively, and that they're finite.
All I can suggest without knowing more info is to do this:
Pre-calculate the values of the functions F_j for each x_i, to give a matrix F - where element F(i,j) gives you the value F_j(x_i).
Do the same thing for E_j, giving a matrix E - where E(i,j) corresponds to E_j(x_i,y).
Perform (F-E).^2 to subtract each element of F and E, then square them element-wise.
Take sum( (F-E).^2**, 2)**. sum(M,2) will sum across index i of matrix M, returning a column vector.
Finally, take sum( sum( (F-E).^2, 2), 1) to sum across index j, the columns, this will finally give you a scalar.

matlab: praticle state simulation

Lets say I want to simulate a particle state, which can be normal (0) or excited (1) in given frame. The particle is in excited state f % of time. If the particle is in excited state, it lasts for ~L frames (with poisson distribution). I want to simulate that state for N time points. So the input is for example:
N = 1000;
f = 0.3;
L = 5;
and the result will be something like
state(1:N) = [0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 ... and so on]
with sum(state)/N close to 0.3
How to do that?
Thanks!
%% parameters
f = 0.3; % probability of state 1
L1 = 5; % average time in state 1
N = 1e4;
s0 = 1; % init. state
%% run simulation
L0 = L1 * (1 / f - 1); % average time state 0 lasts
p01 = 1 / L0; % probability to switch from 0 to 1
p10 = 1 / L1; % probability to switch from 1 to 0
p00 = 1 - p01;
p11 = 1 - p10;
sm = [p00, p01; p10, p11]; % build stochastic matrix (state machine)
bins = [0, 1]; % possible states
states = zeros(N, 1);
assert(all(sum(sm, 2) == 1), 'not a stochastic matrix');
smc = cumsum(sm, 2); % cummulative matrix
xi = find(bins == s0);
for k = 1 : N
yi = find(smc(xi, :) > rand, 1, 'first');
states(k) = bins(yi);
xi = yi;
end
%% check result
ds = [states(1); diff(states)];
idx_begin = find(ds == 1 & states == 1);
idx_end = find(ds == -1 & states == 0);
if idx_end(end) < idx_begin(end)
idx_end = [idx_end; N + 1];
end
df = idx_end - idx_begin;
fprintf('prob(state = 1) = %g; avg. time(state = 1) = %g\n', sum(states) / N, mean(df));
The average length of the excited state is 5. The average length of the normal state, should thus be around 12 to obtain.
The strategy can be something like this.
Start in state 0
Draw a random number a from a Poisson distribution with mean L*(1-f)/f
Fill the state array with a zeroes
Draw a random number b from a Poission distribution with mean L
Fill the state array witb b ones.
Repeat
Another option would be to think in terms of switching probabilities, where the 0->1 and 1->0 probabilities are unequal.

How can I generate the following matrix in MATLAB?

I want to generate a matrix that is "stairsteppy" from a vector.
Example input vector: [8 12 17]
Example output matrix:
[1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]
Is there an easier (or built-in) way to do this than the following?:
function M = stairstep(v)
M = zeros(length(v),max(v));
v2 = [0 v];
for i = 1:length(v)
M(i,(v2(i)+1):v2(i+1)) = 1;
end
You can do this via indexing.
A = eye(3);
B = A(:,[zeros(1,8)+1, zeros(1,4)+2, zeros(1,5)+3])
Here's a solution without explicit loops:
function M = stairstep(v)
L = length(v); % M will be
V = max(v); % an L x V matrix
M = zeros(L, V);
% create indices to set to one
idx = zeros(1, V);
idx(v + 1) = 1;
idx = cumsum(idx) + 1;
idx = sub2ind(size(M), idx(1:V), 1:V);
% update the output matrix
M(idx) = 1;
EDIT: fixed bug :p
There's no built-in function I know of to do this, but here's one vectorized solution:
v = [8 12 17];
N = numel(v);
M = zeros(N,max(v));
M([0 v(1:N-1)]*N+(1:N)) = 1;
M(v(1:N-1)*N+(1:N-1)) = -1;
M = cumsum(M,2);
EDIT: I like the idea that Jonas had to use BLKDIAG. I couldn't help playing with the idea a bit until I shortened it further (using MAT2CELL instead of ARRAYFUN):
C = mat2cell(ones(1,max(v)),1,diff([0 v]));
M = blkdiag(C{:});
A very short version of a vectorized solution
function out = stairstep(v)
% create lists of ones
oneCell = arrayfun(#(x)ones(1,x),diff([0,v]),'UniformOutput',false);
% create output
out = blkdiag(oneCell{:});
You can use ones to define the places where you have 1's:
http://www.mathworks.com/help/techdoc/ref/ones.html