Trying to find index of minimum value in a matrix fails in Octave - octave

So I have this matrix:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34]
lets say I want to find the location of the value closest to 18.9. let A = 18.9
I would do
[r,c] = find(E1==min(min(abs(E1-A))))
This doesn't work. It returns r = "[](0x1)" and c = "[](0x1)"
however,
if I first do:
F = abs(E1-A) and then do
[r,c] = find(F==min(min(F)))
this gives r = 2 and c = 3 which is correct. 19 is the closest value and 19 lives in row 2 column 3.
Why doesnt this work then? F is simply abs(E1-A) so why can I not put abs(E1-A) in place of F in the find formula?

min(min(abs(E1-A)))
ans = 0.10000
This gives you the min over the absolute difference. Then you compare it to E1 which has absolute values. This is complete different from your second formular
[r,c] = find(F==min(min(F)))
where you comapre the minimum difference with the matrix containing the absolute of differences between E1 and A. If you replace in your second formula F with abs(E1-A) you would get
[r,c] = find(abs(E1-A)==min(min(abs(E1-A))))
Which would also work. Nevertheless I would suggest another approach:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34];
A = 18.9;
# get the index ( Column-major order) of the minimum
idx = nthargout (2, #min, abs (E1-A)(:));
# this returns 10
# convert it ro row, column
[r, c] = ind2sub (size (E1), idx)
r = 2
c = 3

Related

How to deduce left-hand side matrix from vector?

Suppose I have the following script, which constructs a symbolic array, A_known, and a symbolic vector x, and performs a matrix multiplication.
clc; clearvars
try
pkg load symbolic
catch
error('Symbolic package not available!');
end
syms V_l k s0 s_mean
N = 3;
% Generate left-hand-side square matrix
A_known = sym(zeros(N));
for hI = 1:N
A_known(hI, 1:hI) = exp(-(hI:-1:1)*k);
end
A_known = A_known./V_l;
% Generate x vector
x = sym('x', [N 1]);
x(1) = x(1) + s0*V_l;
% Matrix multiplication to give b vector
b = A_known*x
Suppose A_known was actually unknown. Is there a way to deduce it from b and x? If so, how?
Til now, I only had the case where x was unknown, which normally can be solved via x = b \ A.
Mathematically, it is possible to get a solution, but it actually has infinite solutions.
Example
A = magic(5);
x = (1:5)';
b = A*x;
A_sol = b*pinv(x);
which has
>> A
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
but solves A as A_sol like
>> A_sol
A_sol =
3.1818 6.3636 9.5455 12.7273 15.9091
3.4545 6.9091 10.3636 13.8182 17.2727
4.4545 8.9091 13.3636 17.8182 22.2727
3.4545 6.9091 10.3636 13.8182 17.2727
3.1818 6.3636 9.5455 12.7273 15.9091

round to the nearest even number with array of numbers

My function and rounding to nearest even number
function y = rndeven(x)
if x<=1
y=2;
else
y = 2*floor(x);
end
endfunction
When I run it I get:
cc=[0:3]'
both=[cc,rndeven(cc)]
0 0
1 2
2 4
3 6
What I'm trying to get as the Result:
0 2
1 2
2 2
3 4
You can use the modulo 2 to find whether a number is even. If it isn't this will return 1, so just add 1 to this number to find the nearest (larger) even number:
function y = rndeven(x)
x = floor(x);
x(x <= 1) = 2;
y = mod(x,2)+x;
end
This works for any array, order of elements does not matter.
You could also check if it is dividable by 2 if you don't want to use the mod function. The pseudo code would be something like this:
while(x % 2 != 0) x = x + 1
return x

Big numbers Napier's location arithmetic

I have to represent this equation 2049*(M+N*100)+(M*N)*2800 using John Napier's Location Arithmetic and then calculate it using the notation's characteristic.
So for example I know that 29*11 would be (2*1)(2*1)(9*1)(9*1) = 3 3 10 10 = 4 11 = 24+ 211 = 16 + 2048 = 2064.
With that knowledge I can change most part of equation, but how can I calculate it with a big number like 2800?
Let's say M = 7 and N = 10.

Any quick way to delete predefined multiple columns?

I will have a periodic spreadsheet that gets generated with a lot of information. (Some 153 columns.) But I only need to keep a fraction of those. So I planned on writing a script that will be run to delete a predefined set of columns.
Example:
Columns from initial spreadsheet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
A B C D E F G H I J K L M N
I only want columns 2-4, 8, 10, & 13-14 to be left, say.
Columns from final spreadsheet after script is run:
1 2 3 4 5 6 7
B C D H J M N
The only way I can think of is where I carry a counter and each time I delete a column I have to adjust by 1 to accurately delete the next desired column in the loop.
Is there not a deleteColumns(2,7,12,...) type code..?
Thank you.
Count backwards - that way the things you delete have no impact on the rest of your work.
...
var sheet = blahblahblah;
var lastCol = sheet.getLastColumn();
var keep = [2,3,4,8,10,13,14]; // array of column numbers to keep
for (var col=lastCol; col > 0; col--) {
if (keep.indexOf(col) == -1) {
// This isn't a keeper, delete it
sheet.deleteColumn(col);
}
}
...

octave: using find() on cell array {} subscript and assigning it to another cell array

This is an example in Section 6.3.1 Comma Separated Lists Generated from Cell Arrays of the Octave documentation (I browsed it through the doc command on the Octave prompt) which I don't quite understand.
in{1} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
in{2} = inf;
in{3} = "last";
in{4} = "first";
out = cell(4, 1);
[out{1:3}] = find(in{1 : 3}); % line which I do not understand
So at the end of this section, we have in looking like:
in =
{
[1,1] =
10 20 30 40 50 60 70 80 90
[1,2] = Inf
[1,3] = last
[1,4] = first
}
and out looking like:
out =
{
[1,1] =
1 1 1 1 1 1 1 1 1
[2,1] =
1 2 3 4 5 6 7 8 9
[3,1] =
10 20 30 40 50 60 70 80 90
[4,1] = [](0x0)
}
Here, find is called with 3 output parameters (forgive me if I'm wrong on calling them output parameters, I am pretty new to Octave) from [out{1:3}], which represents the first 3 empty cells of the cell array out.
When I run find(in{1 : 3}) with 3 output parameters, as in:
[i,j,k] = find(in{1 : 3})
I get:
i = 1 1 1 1 1 1 1 1 1
j = 1 2 3 4 5 6 7 8 9
k = 10 20 30 40 50 60 70 80 90
which kind of explains why out looks like it does, but when I execute in{1:3}, I get:
ans = 10 20 30 40 50 60 70 80 90
ans = Inf
ans = last
which are the 1st to 3rd elements of the in cell array.
My question is: Why does find(in{1 : 3}) drop off the 2nd and 3rd entries in the comma separated list for in{1 : 3}?
Thank you.
The documentation for find should help you answer your question:
When called with 3 output arguments, find returns the row and column indices of non-zero elements (that's your i and j) and a vector containing the non-zero values (that's your k). That explains the 3 output arguments, but not why it only considers in{1}. To answer that you need to look at what happens when you pass 3 input arguments to find as in find (x, n, direction):
If three inputs are given, direction should be one of "first" or
"last", requesting only the first or last n indices, respectively.
However, the indices are always returned in ascending order.
so in{1} is your x (your data if you want), in{2} is how many indices find should consider (all of them in your case since in{2} = Inf) and {in3}is whether find should find the first or last indices of the vector in{1} (last in your case).