How to request multiple inputs, n number of times - matlab

For the code below, I want to take the input values b and k, n times:
syms Q i w h2 h1 k
% n is number of layers for computation
n = input (' ')
for j = 1:n
k1 = input (' '); b1 = input (' ');
% up to...
k(n) = input (' '); b(n) = input (' ');
% so that i want to use the various inputs of b and k to calculate Q.
Qi=( -b(i) * k(i) )*((h2-h1)/w)
Q=symsum(Qi, i, 1, 3)

Within your loop, you can prompt for the input and store it into an array of k and b values
% Pre-allocate k and b arrays
k = zeros(1, n);
b = zeros(1, n);
for ind = 1:n
% Prompt for the next k value
k(ind) = input('');
% Prompt for the next b value
b(ind) = input('');
end
Alternately, you could prompt the user for an array directly
k = input('Please enter an array for k in the form [k1, k2, k3]');
b = input('Please enter an array for b in the form [b1, b2, b3]');
Using these arrays you could compute Q for each value of k and b
Q = (-b .* k)*((h2-h1)/w);

Related

how to randomly multiply symbolic array with matrix

Assuming a matrix W of dimensions n-by-n which is known, and its elements are positive numbers between 0 and 1.
Assuming also a symbolic vector
k = [a b c d];
I need to randomly multiply each all the non-zero component of W with one at a time of the components of k(randomly), such as e.g.:
What I tried:
k = sym('a', [1 4]);
msize = numel(k);
k(randperm(msize, 1))
for i = 1:length(W)
for j = 1:length(W)
W(i,j) = W(i,j)*(k);
end
end
and the error was the following:
The following error occurred converting from sym to double:
Error using maplemex
Error, (in MTM:-double) cannot handle unevaluated name `a1` in evalhf
First we define the inputs:
% PARAMETERS
% k: symbolic vector of length m
m = 4;
k = sym('a', [1, m]);
% W: n-by-n matrix of doubles
n = 5;
W = rand(n);
Here is the calculation:
% CALCULATION
% random assignment of elements of k to the shape of W
I = randi(m, n);
K = k(I);
% result: element-wise multiplication of K and W
result = K .* W;

Get row of functions from a matrix of functions

Before overwhelming you with examples where I try to encapsulate every aspect of my issue I'll try to just state the problem as simply as possible:
If f11 , ... , fnm is n*m real valued funtions that I wish to evaluate m at a time in n steps, through some higher order function b i.e.
v = []
f1 = #(x) [f11(x) f12(x) ... f1m(x)]
v = [v b(f1)]
f2 = #(x) [f21(x) f22(x) ... f2m(x)]
v = [v b(f2)]
How would I solve this through iteration? i.e. something like this:
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v b(f(i,:)) ]
end
Here's an example of what I have (it grew in order to not miss out any details of my actual real-world problem but I have tried to make it as small as possible):
% 4 functions that take a 1x2 real valued vector as argument
% and return a real value
f11 = #(x) x(1) + x(2);
f12 = #(x) x(1) - x(2);
f21 = #(x) x(2) - x(1);
f22 = #(x) x(1) * x(2);
% we'll run function b for 2 steps, then 4 steps
steps = [2 4];
% start value
x = [1 2];
% vector to hold results
v = []
% get the result of passing the 1:st 2 functions to b with steps(1)
f1 = #(x) [f11(x) f12(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd 2 functions to b with steps(2)
f2 = #(x) [f21(x) f22(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
Where b is a function defined as follows:
function [ X ] = b( x, f, n )
% #param:
% x = an 1x2 real valued vector
% f = a real valued function returning
% a 1x2 real valued vector
% n = an integer defining the rows of return matrix
%
% #return:
% X = an nx2 real valued matrix defined as below
X = zeros(n,2);
for i=1:n
% apply the functions on x
a = f(x+1);
b = f(x+2);
% update x
x = a+b
% add x to return matrix
X(i,:) = x;
end
end
The above code could be generalized as:
% n*m functions that take a 1xm real valued vector as argument
% and return a real value
f11 = #(x) ... ;
f12 = #(x) ... ;
.
.
.
fnm = #(x) ... ;
% we'll run function b for a1 steps, then a2 steps, ... , then an steps
steps = [a1 a2 ... an];
% start value
x = [1 2 ... m];
% vector to hold results
v = []
% get the result of passing the 1:st m functions to b with steps(1)
f1 = #(x) [f11(x) ... f1m(x)];
v = [v ;b(x, f1, steps(1))]
% update x
x = v(end,:)
% add the result of passing the 2:nd m functions to b with steps(2)
f2 = #(x) [f21(x) ... f2m(x)];
v = [v ;b(x, f2, steps(2))];
% update x
x = v(end,:)
.
.
.
% add the result of passing the n:ed m functions to b with steps(n)
fn = #(x) [fn1(x) ... fnm(x)];
v = [v ;b(x, fn, steps(n))];
% update x
x = v(end,:)
Where b is any function that returns an steps(i) x m matrix.
I wonder if both the small concrete example and the general example should be solvable through a general iteration, something like this:
% let f hold all the functions as a matrix
f = #(x) [f11(x) ... f1m(x) ; ... ; fn1(x) ... fnm(x)];
% now iterate over the rows of f
for i=1:n
v = [v ; b(x, f(i,:), steps(i)) ]
end
So the trick is in defining your functions as a cell matrix and then using some vectorization to solve the problem. This is the code that I came up with:
%First define your functions in a cell matrix
fn_mat = {#(x) x(1) + x(2), #(x) x(1) - x(2); ...
#(x) x(2) - x(1), #(x) x(1) * x(2)};
%Store the sixe of this matrix in two variables
[n, m] = size(fn_mat);
%Number of steps
steps = [2, 4];
% start value
x = [1 2];
% vector to hold results
v = [];
%This will run the required code for n iterations
for ii = 1:n
%This is the tricky part. What I have done is used arrayfun to run over
%all the functions in the row defined by ii and pass x as an argument
%each time. The rest is same as before
fn = #(x) arrayfun(#(a, b) fn_mat{ii, a}(b{:}), 1:m, repmat({x}, 1, m));
v = [v; b(x, fn, steps(ii))];
x = v(ii, :);
end
For the current values, the output is:
v =
12 -2
26 28
-28 -13
30 610
1160 38525
74730 89497060
The for loop is general enough to accommodate any size of fn_mat.

Output argument not assigned during call (MATLAB)

I'm having a bit of difficulty with this function in MATLAB and I can't figure out what the issue is. The error is,
Output argument "x" (and maybe others) not assigned during call to "SDLS".
Error in NO_wk4_Q3c (line 7)
x = SDLS( A, x0, b, 1e-3 );
So as far as I know, it's something to do with the output for 'x', yet I have assigned 'x' in the function file. Is it something to do with the 'while' loop?
Below is the function file:
function [ x, k ] = SDLS( A, x0, b, tol )
% Steepest descent with exact line search.
% A is the input matrix, x0 is the initial guess, b is a vector, tol is the
% tolerence level for convergence.
if nargin < 4
tol=eps;
end
g = A*x0+b; % Derivative of Q(x)=(1/2)x'Ax+b'x+c;
p = zeros(1,1);
k = 0;
x=zeros(1,1);
while norm(g,2)>=1e-3
g = A*x0 + b;
p = -g; % direction vector
alpha = -(transpose(g)*p)/(transpose(p)*A*p); % step length
x = x0 + alpha*p; % updates approximation
x0 = x;
k = k+1;
end
end
The script file that calls the function is as follows:
clear all;
A = [4 2; 2 3]; % Matrix
x0 = [ -1; -1]; % Initial guess
b = [ 3; 1];
[ x, k] = SDLS( A, x0, b, 1e-3 );
Any advice would be great :-)

Input space separated matrix in matlab of dim (m X n)

I am just a beginner using MatLab. I wanted to add 2 matrices in which user inputs dimension of matrix and then inputs values.
Values are inserted element by element.
I want user to input values row-wise, i.e., for a 2x3 matrix, user should input 2 lines, each line with 3 space separated integer values.
m = input('Enter no. of rows ');
n = input('Enter no. of columns ');
A = zeros(m, n);
B = zeros(m, n);
C = zeros(m, n);
disp('Enter elements in matrix A ');
for i=1 : m
for j=1 : n
A(i,j) = input('\');
end
end
disp('Enter elements in matrix B ');
for i = 1 : m
for j = 1 : n
B(i, j) = input('\');
C(i, j) = A(i, j) + B(i, j);
end
end
clc;
disp('Matrix A is');
A
disp('Matrix B is');
B
disp('Matrix A + B is');
C
How shall i do that?
You could do it using:
for j=1 : n
A(:,j) = input('\');
end
Then the user has to enter a row like [1,2,3,4]
My recommendation is to ask for the full matrix at once. This way the user can enter a variable name which contains the intended function.

Discrete probability distribution calculation in Matlab

I have given P(x1...n) discrete independent probability values which represent for example the possibility of happening X.
I want a universal code for the question: With which probability does happening X occur at the same time 0-n times?
For example:
Given: 3 probabilities P(A),P(B),P(C) that each car(A,B,C) parks. Question would be: With which probability would no car, one car, two cars, and three cars park?
The answer for example for two cars parking at the same time would be:
P(A,B,~C) = P(A)*P(B)*(1-P(C))
P(A,~B,C) = P(A)*(1-P(B))*P(C)
P(~A,B,C) = (1-P(A))*P(B)*P(C)
P(2 of 3) = P(A,B,~C) + P(A,~B,C) + P(~A,B,C)
I have written the code for all possibilities, but the more values I get, of course the slower it gets due to more possible combinations.
% probability: Vector with probabilities P1, P2, ... PN
% result: Vector with results as stated above.
% All possibilities:
result(1) = prod(probability);
shift_vector = zeros(anzahl_werte,1);
for i = 1:anzahl_werte
% Shift Vector allocallization
shift_vector(i) = 1;
% Compute all unique permutations of the shift_vector
mult_vectors = uperm(shift_vector);
% Init Result Vector
prob_vector = zeros(length(mult_vectors(:,1)), 1);
% Calc Single Probabilities
for k = 1:length(mult_vectors(:,1))
prob_vector(k) = prod(abs(mult_vectors(k,:)'-probability));
end
% Sum of this Vector for one probability.
result(i+1) = sum(prob_vector);
end
end
%%%%% Calculate Permutations
function p = uperm(a)
[u, ~, J] = unique(a);
p = u(up(J, length(a)));
end % uperm
function p = up(J, n)
ktab = histc(J,1:max(J));
l = n;
p = zeros(1, n);
s = 1;
for i=1:length(ktab)
k = ktab(i);
c = nchoosek(1:l, k);
m = size(c,1);
[t, ~] = find(~p.');
t = reshape(t, [], s);
c = t(c,:)';
s = s*m;
r = repmat((1:s)',[1 k]);
q = accumarray([r(:) c(:)], i, [s n]);
p = repmat(p, [m 1]) + q;
l = l - k;
end
end
%%%%% Calculate Permutations End
Does anybody know a way to speed up this function? Or maybe Matlab has an implemented function for that?
I found the name of the calculation:
Poisson binomial distribution
How about this?
probability = [.3 .2 .4 .7];
n = numel(probability);
combs = dec2bin(0:2^n-1).'-'0'; %'// each column is a combination of n values,
%// where each value is either 0 or 1. A 1 value will represent an event
%// that happens; a 0 value will represent an event that doesn't happen.
result = NaN(1,n+1); %// preallocate
for k = 0:n; %// number of events that happen
ind = sum(combs,1)==k; %// combinations with exactly k 1's
result(k+1) = sum(prod(...
bsxfun(#times, probability(:), combs(:,ind)) + ... %// events that happen
bsxfun(#times, 1-probability(:), ~combs(:,ind)) )); %// don't happen
end