indexing matrix multiplication for matlab coder into C - c

I would like to speed up my euler/Ornstein–Uhlenbeck code, to try to speed up the for loop, using the matlab coder to translate it to C. However, there seems to be a problem with the indexing, but I can not see what is the problem. Thanks a lot..
function [x,t] = Quick_Euler(N_t,N,A,G,dt)
x = zeros(N,N_t);
t = zeros(1,N_t);
for i = 2 : N_t
n = randn([N,1]);
x(1:N,i) = x(1:N,i-1) + dt^(.5)*G*n + (A*x(1:N,i))*dt;
t(1,i) = t(1,i-1) + dt;
end
end
Compiler:
>> coder -build Quick_Euler.prj
??? Size mismatch (size [:? x 1] ~= size [:? x :?]).
<br>Mismatched varying and fixed sizes indicate a probable run-time error.
If this diagnostic is incorrect, use indexing to explicitly make the varying size fixed.

Related

Error when using CVX package with large sparse matrix

The error description is as follows:
Error using full request 68813x68813 (35.3GB) array to exceed the preset maximum array size Creating an array larger than this limit can take a long time and result in no response from MATLAB for more information, see Array Size Limits or Default Items panel.
Error schurmat_sblk (line 35)
if issparse(schur); schur = full(schur); end;
The function file schurmat_sblk is a file in cvx\sdpt3\Solver,
How can I do to avoid this error?
My cvx codes are as follows:
The value you may need are: n=8; d=2^n;m=(d^2)*0.05;the size of Pauli is m*d^2, it's a sparse matrix. The size of y is m*1;
function [rhoE] = test_compressed_cc(n,~,m,Pauli,y)
d = 2^n;
cvx_begin sdp quiet
% how to define the variable ?
variable rhoE(d,d) hermitian;
rhoE == hermitian_semidefinite(d);
% ||x||_tr=tr(sqrt(x^\daggerx))=tr(sqrt(x^2))=Tr(x)
minimize(trace(rhoE));
subject to
(d/m)*(Pauli * vec(rhoE)) == y;
rhoE >= 0;
cvx_end
end
On the other hand, maybe CVX can't solve the 8 qubit case, does anyone know how SVT should be used to solve this convex program.
Paper link: https://arxiv.org/pdf/0909.3304.pdf
Welcome any comment : )

Using vectorization to reduce for loops, how to use conditional if?

I'm working in a Matlab project and I have a function that is working, but I want to optimize it, reducing the number of for loops that I have in my code.
I read about vectorization, I could use it but how would I include the if conditional statement if I have to test every single value at a time?
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
for n = 1:length(x)
for k=1:length(zi)
if n<k
y(n) = y(n) + b(k)*zi(length(zi)+(n-k)+1);
else
y(n) = y(n) + b(k)*x(n-k+1);
end
end
end
zf = x(length(x)-length(zi)+1:length(x));
I manage to do the vectorization, but I can't figure how to do the conditional, I get the warning:
Variable 'n' might be set by a nonscalar operator
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
n=1:1:length(x); % use of vectorization
for k=1:length(zi)
if n<k % problem with if
y = y + b(k)*zi(length(zi)+(n-k)+1);
else
y = y + b(k)*x(n-k+1);
end
end
zf = x(length(x)-length(zi)+1:length(x));
Currently n is a vector and k is a scalar, and n<k returns a logical vector. If you directly use if, it would be the same as if all(n), which will only return true when everything in that vector is true! That's unexpected behavior.
I don't know if there's a general way to vectorize codes with if. But in your case, I can do it this way.
% use indice to deal with if
for k=1:length(zi)
y(1:k-1)=y(1:k-1)+b(k)*zi(length(zi)+2-k:end);
y(k:end)=y(k:end)+b(k)*x(1:length(x)-k+1);
end
I also notice that actually if you cat zi and x, it's no need to use 2 individual statement.
% assume both zi & x to be column vector
ziandx=[zi;x];
for k=1:length(zi)
y=y+b(k)*ziandx(length(zi)+2-k:length(zi)+length(x)-k+1);
end
Finally, even this for-loop is no need if you use conv. (check the doc for more detail)
ziandx=[zi;x];
s=conv(b(1:length(zi)),ziandx);
y=s(length(zi)+1:length(zi)+length(x))
I recommend you to read all three methods and understand the idea, thus you can do it yourself next time.

MATLAB: Improving for-loop

I need to multiply parts of a column vector with a fixed row vector. I solved this problem using a for-loop. However, I am wondering if the performance can be improved as I have to perform this kind of computation around 50 million times. Here's my code so far:
multMat = 1:5;
mat = randi(5,10,1);
windowSize = 5;
vout = nan(10,1);
for r = windowSize : 10
vout(r) = multMat * mat( (r - windowSize + 1) : r);
end
I was thinking about uisng arrayfun. However, first I don't know how to adress the cell range (i.e. the previous five cells including the current cell), and second, I am not sure if arrayfun will be any faster than using the loop?
This sliding vector multiplication you're describing is an example of what is known as convolution. The following produces the same result as the loop in your example:
vout = [nan(windowSize-1,1);
conv(mat,flip(multMat),'valid')];
If your output doesn't really need the leading NaN values which aren't overwritten in your loop then the conv expression is sufficient without concatenating the NaN elements to it.
For sufficiently large vectors this is of course not guaranteed to be as fast as you'd like it to be, but MATLAB's built-in convolution implementation is likely to be pretty close to an optimal tool for the job.

Why is mxCreateNumericMatrix maximum size smaller than system maximum array size?

I am trying to create a matrix in a MEX function. The following works:
uint64_t N;
N = 2147483647; // N = 2*2^30 -1
plhs[0] = mxCreateNumericMatrix(N,1,mxUINT8_CLASS,mxREAL);
However, I am unable to create an array that is this size:
uint64_t N;
N = 2147483648; // N = 2*2^30
plhs[0] = mxCreateNumericMatrix(N,1,mxUINT8_CLASS,mxREAL);
The preceding code throws the error:
maximum variable size allowed by the function exceeded
Which is confusing since my system (64-bit Linux running 64-bit Matlab 2010b) tells me the maximum array size is, in fact, very large.
[~,M] = computer
M =
281474976710655 % 2^48 -1 for those of you keeping track
Furthermore, from the command line, I am able to create very large arrays, and have been quite happily for some time, with calls like the following:
a = zeros(16*2^30,1,'uint8');
disp(uint64(numel(a)))
17179869184
My question is, why am I not able to create arrays in my mex function that I am clearly able to create from the command line, or from other *.m functions?
Thank you.
P.S. - I have also asked this question in the Mathworks forum. I figured I'd cast as large a net as possible. If it is answered there first, I'll post it here.
The answer lies in the compiler options. By default, Matlab limits the size to 2^31-1. To increase the size, the following option must be included in your mex compile command.
mex -largeArrayDims myFunction.c

MATLAB min(array) gives index exceeds array dimensions [duplicate]

This question already has an answer here:
sum(Array) says index exceeds matrix dimensions [duplicate]
(1 answer)
Closed 3 years ago.
I am trying to find the minimum value of a function of two variables, and then find the value of the variables.
My method is to iterate the function through several values of the variables and then use the min function to find the lowest value.
minval = -10;
maxval = 10;
n = 1;
for x = minval:maxval
for y = minval:maxval
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
n=n+1;
end
end
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
fmin = min(f)
The problem is with the last line:
fmin = min(f)
I am getting the error
??? Index exceeds matrix dimensions.
Error in ==> Lab2 at 65
fmin = min(f)
Why is this? Any help is greatly appreciated.
Don't define a variable named min. Try this:
which min
What does it tell you?
Note that functions in MATLAB can be overloaded by creating variables with the same name. When you do so, you prevent the function from being accessed by MATLAB. This is RARELY a good idea, so don't do it. The solution is
clear min
So you will delete that variable you have created. Of course, if there was something important in that variable, stuff it somewhere else first.
It does indeed look like you have declared a variable called min and so Matlab now treats it like a variable and not a function so it thinks you are trying to index the variable min with the vector f.
But just a comment on your code, leaving off whatever f(442) is you could achieve the same thing in a much more matlabesque fashion without loops like this:
minval = -10;
maxval = 10;
X = minval:maxval;
Y = X;
[xx, yy] = meshgrid(X, Y);
F = abs(xx-1) + abs(yy-1) + abs(xx-3) + abs(yy-5) +abs(xx-8) + abs(yy-3);
Your f is now equivalent to F(:)' (without the final value...), prove it to yourself like this: sum(f(1:end-1) == F(:)')
F as a matrix probably makes more sense than f as a flat vector anyway and you can find the min of F like this: min(F(:))
This code runs perfectly when I plug it into my version of Matlab.
If the error is occuring on line 65, then there must be something else going on in your program. Try and turn this part of your program into a function, so that it won't be impacted by everything else that you're working on.

Resources