Matrix access by x/y coordinates without linear indexing and looping in Matlab/Octave - matlab

I'm operating on very big, 2D, sparse matrices in Octave. I have hit the linear indexing limit of 2^31 and need to go bigger.
The problem is I have two same-sized vectors of X and Y coordinates and would like to modify respective points without a loop.
I have already tried looping over one dimension, and arrayfun - both work, but suffer from serious perfomance issues.
Is there any way to do this without recompiling Octave for 64bit linear indexing?
Example of what I would like to achive:
A = [1 2 3; 4 5 6; 7 8 9];
x = [1 3]; y = [3 2];
B = getxy/setxy(A, x ,y) % [7 6]

Related

Angles between n vectors - Matlab

Consider a set of points (just an example)
x = [0 1 2 5 4 8 5 6];
y = [5 8 4 2 5 6 4 5];
and another reference point:
xc=1;
yc=1;
In which I use to represent these points as vectors:
vec=[x-xc y-yc];
I wish to obtain a matrix with all the angles between all vectors which is obtained by the calculation (for single vectors)
angle = acosd(dot(v,u)/norm(u)*norm(v));
How can I obtain this calculation in a few lines without going vector by vector in a loop? In my calculation the number of points is very very large.
I think you mean vec = [x-xc; y-yc];. To calucate the dotproduct between all rows, you can use
vec.'*vec
The norm (Euclidean) of each vector can be determined as
no = sqrt(sum(vec.*vec,1))
The product of the different norms can be calculated the same as for vec:
no.'*no
The angles can thus be found as
no = sqrt(sum(vec.*vec,1));
angles = acosd(vec.'*vec./(no.'*no));

Ways around pinv([inf])=NaN in Octave/Matlab

I am using Octave 3.8.1, a Matlab-like program. I'd like to generalize 1/x to the case where x may be a scalar or a matrix. Replacing 1/x with inv(x) or pinv(x) works for most x, except:
octave:1> 1/inf
ans = 0
octave:2> pinv([inf])
ans = NaN
octave:3> inv([inf])
warning: inverse: matrix singular to machine precision, rcond = 0
ans = Inf
Should I convert NaN to 0 afterwards to get this to work? Or have I missed something? Thanks!
The Moore–Penrose pseudo inverse, which is the basis for Matab and octave's pinv, is implemented via completely different algorithm than the inv function. More specifically, singular value decomposition is used, which require's finite-valued matrices (they also can't be sparse). You didn't say if your matrices are square or not. The real use of pinv is for solving non-square systems (over- or underdetermined).
However, you shouldn't be using pinv or inv for your application, no matter the dimension of your matrices. Instead you should use mldivide (octave, Matlab), i.e., the backslash operator, \. This is much more efficient and numerically robust.
A1 = 3;
A2 = [1 2 1;2 4 6;1 1 3];
A1inv = A1\1
A2inv = A2\eye(size(A2))
The mldivide function handles rectangular matrices too, but you will get different answers for underdetermined systems compared to pinv because the two use different methods to choose the solution.
A3 = [1 2 1;2 4 6]; % Underdetermined
A4 = [1 2;2 4;1 1]; % Overdetermined
A3inv = A3\eye(min(size(A3))) % Compare to pinv(A3), different answer
A4inv = A4\eye(max(size(A4))) % Compare to pinv(A4), same answer
If you run the code above, you'll see that you get a slightly different result for A3inv as compared to what is returned by pinv(A3). However, both are valid solutions.

Matlab: Solve Exponential Equation with two unknown parameters

I have a Matrix called A. For example the following:
A = [1 2 3; 3 4 1; 2 4 4]
Now I have the following equation:
A(x,y) = (j^x)*(i^y)
j and i are normal values (dimension 1x1), not indices of a matrix. ^
Lets make an example:
A(1,1) = 1 (First value of the Matrix)
1 = (j^1)*(i^1)
And a second one:
A(1,2) = 3
3 = (j^1)*(i^2)
Is there a possibility to receive one solution for the two parameters using Matlab?
Here is some code that can find the best solution to your problem, if there is one. In this case, there is no reasonable solution, but defining A by M([4 2]) (for example) does work reasonably well.
A = [1 2 3; 3 4 1; 2 4 4] %// the A matrix
[C,R]=meshgrid(1:3) %// create matrices of row/column indices
M=#(xy) xy(2).^C.*xy(1).^R %// calculates matrix of elements j^x*i^y
d=#(xy) A-M(xy) %// calculates difference between A and the calculated i^x*y^j matrix
r=fsolve(#(xy) norm(d(xy)),[1 1]) %// use fsolve to attempt to find a solution
d(r) %// show resulting difference between target matrix and solution matrix
norm(d(r)) %// norm of that matrix
M(r) %// show the solution matrix

Finding solutions to a linear system in Matlab?

I have an equation like this
y = a*x+b;
I have sets of y and x
y = [1 2 3 4 5]
x = [6 7 8 9 10]
I want to find a and b, but not one solution; all solutions. I guess, I have to use polyfit, but I don't know how to do this and I don't understand why I have to use polyfit? Can you explain this to me?
From the polyfit documentation:
p = polyfit(x,y,n) finds the coefficients of a polynomial p(x) of
degree n that fits the data, p(x(i)) to y(i), in a least squares
sense. The result p is a row vector of length n+1 containing the
polynomial coefficients in descending powers:
So, you have data y at x-coordinates x, and you want to fit a first-degree polynomial to it. So use
p=polyfit(x,y,1);
and then p(1)=a and p(2)=b, or y=p(1)*x+p(2).
There are other ways to do this, but polyfit is very simple.

MATLAB: Matrix containing values of another matrix at specific indices

I need help solving an indexing problem. The assigned problem states: Two matrices (x and y) give the coordinates to form matrix B from matrix A. Produce the matrix B which contains the values of A at the given coordinates in x and y.
For instance:
x = [1 1 1; 2 2 1]
y = [1 2 1; 3 2 4]
%This would read as (1,1),(1,2),(1,1),(2,3),(2,2),(1,4)
% Given matrix:
A = [6 7 8 9; 10 11 12 13];
%This would give us this answer for B (using the coordinate scheme above):
B=[6 7 6; 12 11 9];
I'm guessing I need to use the find function in conjunction with a sub2ind function, but I'm not 100% sure how to translate that into working code. The only thing I can think of would be to do something like this:
B=((x(1),(y(1)), (x(2),y(2)).......
But that would only work for the defined matrix above, not a randomly generated matrix. I tried looking for a similar problem on the site, but I couldn't find one. Your help would be really appreciated!
You can't do it for randomly generated matrices, because you have to ensure that matrix A has lines and columns as required from the values of x and y.
In this case, you can write:
for i=1:length(x(:))
B(i)=A(x(i),y(i));
end
B=reshape(B,size(x));