I am a complete beginner at Octave!
I am struggling to figure out the minimum value from the array mse_array. I keep getting an error saying: "subscript indices must be either positive integers less than 2^31 or logicals"
Could someone help me? Here's my code:
function randomLines(data1, data2)
mse_array = []
A = rand(2,10)*100
for i = columns(A)
max = A (1, i)
min = A (2, i)
m = (max-min)/0.16
p = [m min];
array_function_values = polyval(p,data2);
current_mse = mseFunction(data1,array_function_values);
mse_array(end + 1) = current_mse
endfor
min_value = min(mse_array)
endfunction
Q: How to find a minimum from an array in Octave?
octave has built-in self-describing documentation to use once in doubts
A: Always re-read both help min and doc min
octave-3.2.4.exe:1> help min
`min' is a function from the file C:\Octave\3.2.4_gcc-4.4.0\libexec\octave\3.2.4\oct\i686-pc-mingw32\max.oct
-- Loadable Function: min (X)
-- Loadable Function: min (X, Y)
-- Loadable Function: min (X, Y, DIM)
-- Loadable Function: [W, IW] = min (X)
For a vector argument, return the minimum value. For a matrix
argument, return the minimum value from each column, as a row
vector, or over the dimension DIM if defined. For two matrices
(or a matrix and scalar), return the pair-wise minimum. Thus,
min (min (X))
returns the smallest element of X, and
min (2:5, pi)
=> 2.0000 3.0000 3.1416 3.1416
compares each element of the range `2:5' with `pi', and returns a
row vector of the minimum values.
For complex arguments, the magnitude of the elements are used for
comparison.
If called with one input and two output arguments, `min' also
returns the first index of the minimum value(s). Thus,
[x, ix] = min ([1, 3, 0, 2, 0])
=> x = 0
ix = 3
See also: max, cummin, cummax
Re-defining (thus rendering un-usable) elements as reserved words just increases troubles. Try to use your own naming convention, that will not harm the rest of the system -- i.e. anArrayMinimumVALUE or aSmallestVALUE, rather than "killing" the Octave function min() by creating a variable named by accident as "also" min
There are several things wrong with your code. Here are a few to get you started.
The error is probably occurring at this line:
min_value = min(mse_array)
You're using mse_array as an index into min, but the values in mse_array are likely to valid array indices as the error states. (I'm guessing at this purely based on the name of the variable, mse_array, which appear to be from some form of mean squared error calculation.) It's important to check the line number and everything else in error messages.
Another issue in that your for loop only evaluates once. The columns function will return the scalar number of columns of A. Thus your your loop declaration is equivalent to:
for i = 10
In other words, the code will only look at the last column of A. You probably want to use:
for i = 1:columns(A)
Lastly, it's a bad idea to overwrite the built-in min and max functions in Octave with your own variable names. If you overwrite the built-in min function, you won't be able to use it anymore directly until you call clear min (alternatively, you can call builtin, but you should avoid that). Instead, just choose better variable names.
Related
I have a problem with the runtime of my code. The only module that is really slow is my for-loop over every matrix element in a (144, 208)-array.
I have to check every element if the condition is fulfilled and if so, i have to perform several actions like shifting another (144, 208)-array and add it to an existing one.
Is this not changeable or is my implementation way too beginner-like?
Here is my code:
# With this codeblock i am loading a specific image into python and
binarize it
g = Initialization()
b_init = g.initialize_grid(".\\geometries\\1.png")
# this function will modify the matrix m_sp, which i load in as csv.file
def expand_blockavg(x, h, w):
m, n = x.shape
return np.broadcast_to((x/float(h*w))[:, None, :, None], (m, h, n, w)).reshape(m*h, -1)
m_adapt = expand_blockavg(m_sp, 16, 16) / 256
# This is my actual calculation block
for index, x in np.ndenumerate(b_init):
if x == 1:
a = np.asarray(index)
y = np.subtract(a, index_default)
m_shift = shift(m_adapt, (y[0], y[1]), cval=0)
b = np.add(m_shift, b)
SO, the last block (calculation) is what takes so long. I know that the loop has to check 30k elements. But i thought that with numpy it will be faster.
Can some1 tell me if there's potential for optimization or do i have to live with the fact that it'll take so long.
thanks
Iteration in python is very slow compared to vectorized numpy operations.
An immediate optimization is to only iterate over the indices where the matrix is 1, rather than checking each index. Do this with:
indices = np.argwhere(b_init == 1)
for a in indices:
y = np.array(a) - index_default
m_shift = shift(m_adapt, y[:2], cval=0)
b += m_shift
Not knowing the details of shift it’s hard to say if you can vectorize that also. I replaced function calls with equivalent operations which should be faster; np.add etc. are mostly useful when the operation is being selected programmatically.
I have a vector A of size 7812x1 and would like to calculate the sum of fixed windows of length 21 (so 372 blocks). This should be reiterated, so that the output should return a vector of size 372x1.
I have t=7812, p=372, w=21;
for t=1:p
out = sum(A((t*w-w+1):(t*w)));
end
This code, however, does not work. My idea is that the part ((t*w-w+1):(t*w)) allows for something like a rolling window. The window is of length 21, so there is not really a need to express is with variables, yet I think it keeps some flexibility.
I've seen potentially related questions (such a partial sum of a vector), yet I'm not sure whether this would result the output desired.
Reshape into a matrix so that each block of A is a column, and compute the sum of each colum:
result = sum(reshape(A, w, []), 1);
Following your idea of using a rolling/moving window (requires Matlab 2016a or later):
t = 7812; w = 21; % your parameters
A = rand(t,1); % generate some test data
B = movsum(A,w); % the sum of a moving window with width w
out = B(ceil(w/2):w:end); % get every w'th element
I have written the following 'matlab' code that is supposed to return the maximum value in an array:
function m = maxi(a)
maximum = a(1,1);
[m,n]=size(a);
for i=1:m
for j=1:n
if a(i,j)>=maximum
maximum = a(i,j)
else
maximum = maximum;
end
end
end
m = maximum;
end
The case here is that the returned result seems to be the maximum number in each iteration. How can I return only one value, which is the maximum value?
Thanks.
To find the maximum value in an array, it is advisable to use the built-in function max. Note that max operates along the first dimension of the array by default; to find the overall max, you may therefore want to pass your array as a vector:
overallMax = max(array(:));
Really, it's not recommended to re-implement built-ins if performance is at all important. However, for educational purposes, it can be useful to reverse-engineer code.
Your function runs fine for me, though I would suggest that you iterate over linear indices (similar to how you transform the array to a vector above). This way it will work for an array of arbitrary dimensionality.
function mx = maxi(a)
mx = a(1);
for ii = 1:numel(a)
if a(ii) > mx
mx = a(ii);
end
end
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.
I have a set of arrays that describes a sequence of 3D positions. The structure is:
arr[N][0] = X;
arr[N][1] = Y;
arr[N][2] = Z;
where N goes from 0 to (total count of 3D-coords - 1).
How can I write a function that, taking a set of N arrays, returns a value from 0 to MAX where:
return value near 0 => the positions are very close together
return value near MAX => the positions have changed a lot.
Is there an algorithm/mathematical function for that?
One measure of scattering is the variance.
You can calculate the variance for each coordinate separately and then add them (and doing so should be mathematically correct).