Row--wise application of an inline function - matlab

I defined an inline function f that takes as argument a (1,3) vector
a = [3;0.5;1];
b = 3 ;
f = #(x) x*a+b ;
Suppose I have a matrix X of size (N,3). If I want to apply f to each row of X, I can simply write :
f(X)
I verified that f(X) is a (N,1) vector such that f(X)(i) = f(X(i,:)).
Now, if I a add a quadratic term :
f = #(x) x*A*x' + x*a + b ;
the command f(X) raises an error :
Error using +
Matrix dimensions must agree.
Error in #(x) x*A*x' + x*a + b
I guess Matlab is considering the whole matrix X as the input to f. So it does not create a vector with each row, i, being equal to f(X(i,:)). How can I do it ?
I found out that there exist a built-in function rowfun that could help me, but it seems to be available only in versions r2016 (I have version r2015a)

That is correct, and expected.
MATLAB tries to stay close to mathematical notation, and what you are doing (X*A*X' for A 3×3 and X N×3) is valid math, but not quite what you intend to do -- you'll end up with a N×N matrix, which you cannot add to the N×1 matrix x*a.
The workaround is simple, but ugly:
f_vect = #(x) sum( (x*A).*x, 2 ) + x*a + b;
Now, unless your N is enormous, and you have to do this billions of times every minute of every day, the performance of this is more than acceptable.
Iff however this really and truly is your program's bottleneck, than I'd suggest taking a look at MMX on the File Exchange. Together with permute(), this will allow you to use those fast BLAS/MKL operations to do this calculation, speeding it up a notch.
Note that bsxfun isn't going to work here, because that does not support mtimes() (matrix multiplication).
You can also upgrade to MATLAB R2016b, which will have built-in implicit dimension expansion, presumably also for mtimes() -- but better check, not sure about that one.

Related

Adding a sparse vector to a dense vector in Matlab

Suppose I have a high dimensional vector v which is dense and another high dimensional vector x which is sparse and I want to do an operation which looks like
v = v + x
Ideally since one needs to update only a few entries in v this operation should be fast but it is still taking a good amount of time even when I have declared x to be sparse. I have tried with v being in full as well as v being in sparse form and both are fairly slow.
I have also tried to extract the indices from the sparse vector x by calling a find and then updating the original vector in a for loop. This is faster than the above operations, but is there a way to achieve the same with much less code.
Thanks
Quoting from the Matlab documentation (emphasis mine):
Binary operators yield sparse results if both operands are sparse, and full results if both are full. For mixed operands, the result is full unless the operation preserves sparsity. If S is sparse and F is full, then S+F, S*F, and F\S are full, while S.*F and S&F are sparse. In some cases, the result might be sparse even though the matrix has few zero elements.
Therefore, if you wish to keep x sparse, I think using logical indexing to update v with the nonzero values of x is best. Here is a sample function that shows either logical indexing or explicitly full-ing x is best (at least on my R2015a install):
function [] = blur()
n = 5E6;
v = rand(n,1);
x = sprand(n,1,0.001);
xf = full(x);
vs = sparse(v);
disp(['Full-Sparse: ',num2str(timeit(#() v + x) ,'%9.5f')]);
disp(['Full-Full: ',num2str(timeit(#() v + xf) ,'%9.5f')]);
disp(['Sparse-Sparse: ',num2str(timeit(#() vs + x) ,'%9.5f')]);
disp(['Logical Index: ',num2str(timeit(#() update(v,x)),'%9.5f')]);
end
function [] = update(v,x)
mask = x ~= 0;
v(mask) = v(mask) + x(mask);
end

Use fminsearch to find local minimizer and the minima at that value

I am having trouble using fminsearch: getting the error that there were not enough input arguments for my function.
f = #(x1,x2,x3) x1.^2 + 3.*x2.^2 + 4.*x3.^2 - 2.*x1.*x2 + 5.*x1 + 3.*x2 + 2.*x3;
[x, val] = fminsearch(f,0)
Is there something wrong with my function? I keep getting errors anytime I want to use it as an input function with any other command.
I am having trouble using fminsearch [...]
Stop right there and think some more about the function you're trying to minimize.
Numerical optimization (which is what fminsearch does) is unnecessary, here. Your function is a quadratic function of vector x; in other words, its value at x can be expressed as
x^T A x + b^T x
where matrix A and vector b are defined as follows (using MATLAB notation):
A = [ 1 -1 0;
-1 3 0;
0 0 4]
and
b = [5 3 2].'
Because A is positive definite, your function has one and only one minimum, which can be computed in MATLAB with
x_sol = -0.5 * A \ b;
Now, if you're curious about the cause of the error you ran into, have a look at fuesika's answer; but do without fminsearch whenever you can.
It is exactly what Matlab is telling you: your function expects three arguments. You are passing only one.
Instead of
[x, val] = fminsearch(f,0)
you should call it like
[x, val] = fminsearch(f,[0,0,0])
since you define the function f to accept a three dimensional vector as input only.
You can read more about the specification of fminsearch in the online documentation at http://mathworks.com/help/matlab/ref/fminsearch.html:
x = fminsearch(fun,x0) starts at the point x0 and returns a value x
that is a local minimizer of the function described in fun. x0 can be
a scalar, vector, or matrix. fun is a function_handle.

matlab wrong modulo result when the divident is raised to a power

Just wondering... I tried doing by hand (with the multiply and square method) the operation (111^11)mod143 and I got the result 67. I also checked that this is correct, in many online tools. Yet, in matlab plugging:
mod(111^11,143)
gives 127! Is there any particular reason for this? I didn't find anything in the documentation...
The value of 111^11 (about 3.1518e+022) exceeds the maximum integer that is guaranteed to be represented exactly as a double, which is 2^53 (about 9.0072e+015). So the result is spoilt by insufficient numerical precision.
To achieve the correct result, use symbolic computation:
>> syms x y z
>> r = mod(x^y, z);
>> subs(r, [x y z], [111 11 143])
ans =
67
Alternatively, for this specific operation (modulo of a large number that is expressed as a product of small numbers), you can do the computation very easily using the following fact (where ∗ denotes product):
mod(a∗b, z) = mod(mod(a,z)∗mod(b,z), z)
That is, you can apply the modulo operation to factors of your large number and the final result is unchanged. If you choose factors sufficiently small so that they can be represented exactly as double, you can do the computation numerically without any loss of precision.
For example: using the decomposition 111^11 = 111^4*111^4*111^3, since all factors are small enough, gives the correct result:
>> mod((mod(111^4, 143))^2 * mod(111^3, 143), 143)
ans =
67
Similarly, using 111^2 and 111 as factors,
>> mod((mod(111^2, 143))^5 * mod(111, 143), 143)
ans =
67
from the matlab website they recommend using powermod(b, e, m) (b^e mod m)
"If b and m are numbers, the modular power b^e mod m can also be computed by the direct call b^e mod m. However, powermod(b, e, m) avoids the overhead of computing the intermediate result be and computes the modular power much more efficiently." ...
Another way is to use symfun
syms x y z
f = symfun(mod(x^y,z), [x y z])
f(111,11,143)

Find entrance of matrix for each adjacent pair of numbers in vector and multiply

I have a (transition) function defined by a matrix say P=[0.75,0.25;0.25,0.75] and I have a vector say X=[1,2,1] then i would like to find P(1,2)*P(2,1). How is the easiest way to generalise this? I tried creating a function handle for P(i,j) and then X_temp=[X(1:end-1);X(2:end)], using the function of each column and finally using the product function, but it seems a lot more comprehensive than it has to be.
The X i want to use is 1000 dimensional and P is 3x3 and I would have to repeat it a lot of times so speed I think will matter.
You can use sub2ind to get your relevant P values:
Ps = P(sub2ind(size(P), X(1:end-1), X(2:end)))
Now just multiply them all together:
prod(Ps)
EDIT:
For function handles you had the right idea, just make sure that you function itself handles vectors. For example lets say your function f(i,j) = i + j, I'm going to assume it's actually f(x) = x(1) + x(2) but I want it to handle many xs at once sof(x) = x(:,1) + x(:,2):
f = #(x)(x(:,1) + x(:,2))
f([X(1:end-1)', X(2:end)'])
OR
f = #(ii, jj)(ii + jj)
f(X(1:end-1)', X(2:end)') %//You don't actually need the transposes here anymore
just note that you need to use element wise operators such as .*, ./ and .^ etc instead of *, /,^...

Simple MATLAB Variable Question

Please help me write a MATLAB program that constructs a column matrix b, such that
b1 = 3x1 - 3/4y0
b2 = 3x2
...
bn-2 = 3xn-2
bn-1 = 3xn-1 - 3/4yn
where x and y are variables. Notice that y only appears in the first and last entries of b.
My problem is that I don't know how variables work in MATLAB. I tried
b = 3*x
and it says
??? Undefined function or variable 'x'
So, how do we create variables instead of constants?
Thanks!
EDIT:
From your comments above, what you need is MATLAB's symbolic toolbox, which allows you to perform computations in terms of variables (without assigning an explicit value to them). Here's a small example:
syms x %#declare x to be a symbolic variable
y=1+x;
z=expand(y^2)
z=
x^2 + 2*x + 1
You will need to use expand sometimes to get the full form of the polynomial, because the default behaviour is to keep it in its simplest form, which is (1+x)^2. Here's another example to find the roots of a general quadratic
syms a b c x
y=a*x^2+b*x+c;
solve(y)
ans =
-(b + (b^2 - 4*a*c)^(1/2))/(2*a)
-(b - (b^2 - 4*a*c)^(1/2))/(2*a)
I think you meant bn and xn in the last line... Anyway, here's how you do it:
b=3*x;
b([1,end])=b([1,end])-3/4*y([1,end])
You can also do it in a single line as
b=3*x-3/4*[y(1); zeros(n-2,1); y(end)];
where n is the length of your vector.
You never stated your problem...
Anyways just set the first entry of b individually first. Then use a loop to set the next values of b from 2 up to n-2. Then set the last entry of b individually.
On a side note, if x is a vector, you can simply vectorize the loop part.