How come these two matrices are not equivalent? - arrays

Assume we have a 3 dimensional array F and 2 dimensional matrix S.
First I find a matrix Y which is F multiplied by S. Then I try to find an estimate of F (lets call it F_est) from Y as sanity check in my code.
Can anyone see a flaw in logic, I dont seem to know why F_est is not exactly F.
F= randn(2,4,600);
S= randn(4,600);
for i =1:size(F,1);
for j=1:size(F,2)
for k= 1:size(F,3)
Y(i,k)= F(i,j,k) * S(j,k);
end
end
end
for i =1:size(F,1)
for j=1:size(F,2)
for k= 1:size(F,3)
F_est(i,j,k)= Y(i,k) / S(j,k);
end
end
end
then I try to see if F_est - F is zero and it is not. Any ideas. Much aprreciated.
**** EDIT after comments
Based on the answers I got I am wondering if the code below makes any sense?
for k=1:size(F,3)
Y(:,k) = squeeze(F(:,:,k)* S(:,k)
end
Am I able to recover F if I have Y and S?

When you create Y, you are replacing its values continuously. For any value of pair of i,k you are overwriting Y jtimes!
Those 2 codes are not equivalent, as F_est(i,j,k) computed only once, but you have Y(i,k) j times.
I don't know what you are trying to do, but a multiplication of a 3D matrix by a 2D matrix is not defined, and its not a 2D matrix

Related

How to take irfft of multidimensional array in julia?

I am new to julia, and I am trying to take the irfft of B, which is a 3d array of size (n/2, n, n) where B = rfft(A). However, the irfft in julia reqires an additional input d for the size of the transformed real array, and I'm unsure of what to put. I tried n and n/2, but both did not seem to work as expected when I printed the resulting matrix out.
EDIT: I should've lowered my dimensions to check if everything was working, turns out using d = n is ok. Thanks to everyone who answered!
Check out this discussion. Presumably any triple of numbers will do the trick, but may or may not give you what you want.
This should work:
using FFTW
function test(n = 16)
a = rand(n ÷ 2, n, n)
f = rfft(a)
#show irfft(f, n ÷ 2 + 1)
end
test()

Network Formation and Large Array's in Matlab Optimization

I am getting an error using repmat. My Matlab version is 2017a. "Requested 3711450x2726 (75.4GB) array exceeds maximum array size..." First, some context.
I have an adjacency matrix of social network data call it D. D is 2725x2725 with 1s denoting a link between agents i and j and 0s otherwise. I have been provided a function and sub-functions for a network formation model. There are K regressors (x variables). The model requires forming a dyad-specific regressor matrix W that is W = 0.5N(N-1) x K. In my data, this is 3711450 x K. For a start, I select only one x variable so K=1.
In the main function, there are two steps. The first step calculates the joint MLE from a logit. I have a problem in the second step computation of the variance covariance matrix with array size. Inside this step, there is a calculation that creates a 3711450 x n (2725) matrix using repmat.
INFO = ((repmat((exp_Xbeta ./ (1+exp_Xbeta).^2),1,K) .* X)'*X);
exp_Xbeta is 3711450 x K and X is a sparse 3711450 x 2725 matrix with Bytes = 178171416 of class double. The error occurs at INFO.
I've tried converting X to a tall matrix but thus far no joy. I've tried adding sparse to the INFO line but again no joy. Anyone have any ideas short of going to a cluster or getting more ram? Could I somehow convert X from a sparse matrix to a full matrix inside a datastore and then call the datastore using tall? I have not been able to figure out how to do that if it is possible.
Once INFO is constructed as an array it will be used later in one of the sub-functions. So, it needs to be callable. In case you're curious, INFO is the second derivative matrix.
I have found that producing the INFO matrix all at once was too much for my memory constraints. I split up the steps, but still, repmat and subsequent steps were a problem. Now, I've turned to building up the INFO matrix one step at a time, while never holding more than exp_Xbeta, X, and two vectors in memory. Replacing the construction of INFO with
for i = 1:d
s1_i = step1(:,1).*X(:,i);
s1_i = s1_i';
for j = 1:d;
INFO(i,j) = s1_i*X(:,j);
end
clear s1_i;
end
has dropped the memory requirement, though its slow, and things seem to be working. For anyone interested, below is a little example illustrating the point.
clear all
N = 20
n = 0.5*N*(N-1)
exp_Xbeta = rand(n,1);
X = rand(n,N);
step1 = (exp_Xbeta ./ (1+exp_Xbeta).^2);
[c,d] = size(X);
INFO = zeros(d,d);
for i = 1:d
s1_i = step1(:,1).*X(:,i)
s1_i = s1_i'
for j = 1:d
INFO(i,j) = s1_i*X(:,j)
end
clear s1_i
end
K = 1
INFO2 = ((repmat((exp_Xbeta ./ (1+exp_Xbeta).^2),1,K) .* X)'*X);
% Methods produce equivalent matrices
INFO
INFO2

Matlab: creating 3D arrays as a function of 2D arrays

I want to create 3d arrays that are functions of 2d arrays and apply matrix operations on each of the 2D arrays. Right now I am using for loop to create a series of 2d arrays, as in the code below:
for i=1:50
F = [1 0 0; 0 i/10 0; 0 0 1];
B=F*F';
end
Is there a way to do this without the for loop? I tried things such as:
F(2,2) = 0:0.1:5;
and:
f=1:0.1:5;
F=[1 0 0; 0 f 0; 0 0 1];
to create them without the loop, but both give errors of dimension inconsistency.
I also want to perform matrix operations on F in my code, such as
B=F*F';
and want to plot certain components of F as a function of something else. Is it possible to completely eliminate the for loop in such a case?
If I understand what you want correctly, you want 50 2D matrices stacked into a 3D matrix where the middle entry varies from 1/10 to 50/10 = 5 in steps of 1/10. You almost have it correct. What you would need to do is first create a 3D matrix stack, then assign a 3D vector to the middle entry.
Something like this would do:
N = 50;
F = repmat(eye(3,3), [1 1 N]);
F(2,2,:) = (1:N)/10; %// This is 1/10 to 5 in steps of 1/10... or 0.1:0.1:5
First pre-allocate a matrix F that is the identity matrix for all slices, then replace the middle row and middle column of each slice with i/10 for i = 1, 2, ..., 50.
Therefore, to get the ith slice, simply do:
out = F(:,:,i);
Minor Note
I noticed that what you want to do in the end is a matrix multiplication of the 3D matrices. That operation is not defined in MATLAB nor anywhere in a linear algebra context. If you want to multiply each 2D slice independently, you'd be better off using a for loop. Doing this vectorized with native operations isn't supported in this context.
To do it in a loop, you'd do something like this for each slice:
B = zeros(size(F));
for ii = 1 : size(B,3)
B(:,:,ii) = F(:,:,ii)*F(:,:,ii).';
end
... however, examining the properties of your matrix, the only thing that varies is the middle entry. If you perform a matrix multiplication, all of the entries per slice are going to be the same... except for the middle, where the entry is simply itself squared. It doesn't matter if you multiple one slice by the transpose of the other. The transpose of the identity is still the identity.
If your matrices are going to be like this, you can just perform an element-wise multiplication with itself:
B = F.*F;
This will not work if F is anything else but what you have above.
Creating the matrix would be easy:
N = 50;
S = cell(1,N);
S(:) = {eye(3,3)};
F = cat(3, S{:});
F(2,2,:) = (1:N)/10;
Another (faster) way would be:
N = 50;
F = zeros(3,3,N);
F(1,1,:) = 1;
F(2,2,:) = (1:N)/10;
F(3,3,:) = 1;
You then can get the 3rd matrix (for example) by:
F(:,:,3)

store data in array from loop in matlab

I want to store data coming from for-loops in an array. How can I do that?
sample output:
for x=1:100
for y=1:100
Diff(x,y) = B(x,y)-C(x,y);
if (Diff(x,y) ~= 0)
% I want to store these values of coordinates in array
% and find x-max,x-min,y-max,y-min
fprintf('(%d,%d)\n',x,y);
end
end
end
Can anybody please tell me how can i do that. Thanks
Marry
So you want lists of the x and y (or row and column) coordinates at which B and C are different. I assume B and C are matrices. First, you should vectorize your code to get rid of the loops, and second, use the find() function:
Diff = B - C; % vectorized, loops over indices automatically
[list_x, list_y] = find(Diff~=0);
% finds the row and column indices at which Diff~=0 is true
Or, even shorter,
[list_x, list_y] = find(B~=C);
Remember that the first index in matlab is the row of the matrix, and the second index is the column; if you tried to visualize your matrices B or C or Diff by using imagesc, say, what you're calling the X coordinate would actually be displayed in the vertical direction, and what you're calling the Y coordinate would be displayed in the horizontal direction. To be a little more clear, you could say instead
[list_rows, list_cols] = find(B~=C);
To then find the maximum and minimum, use
maxrow = max(list_rows);
minrow = min(list_rows);
and likewise for list_cols.
If B(x,y) and C(x,y) are functions that accept matrix input, then instead of the double-for loop you can do
[x,y] = meshgrid(1:100);
Diff = B(x,y)-C(x,y);
mins = min(Diff);
maxs = max(Diff);
min_x = mins(1); min_y = mins(2);
max_x = maxs(1); max_y = maxs(2);
If B and C are just matrices holding data, then you can do
Diff = B-C;
But really, I need more detail before I can answer this completely.
So: are B and C functions, matrices? You want to find min_x, max_x, but in the example you give that's just 1 and 100, respectively, so...what do you mean?

Plese write a solution for a prolog task

I have a matrix M x N, I need to switch places of the elements with indexed [1,N] and [M,N].
Update
I am really new to Prolog, here is my solution that returns false :(
main([FirstRow|Tail],X):-
last(FirstRow, A),
last(Tail, LastRow),
last(LastRow, B),
skipLastItem(FirstRow,FirstRowWithoutA),
skipLastItem(LastRow,LastRowWithoutB),
append(FirstRowWithoutA,[B],FirstRowNew),
append(LastRowWithoutB,[A],LastRowNew),
assign([FirstRowNew],X),
skipLastItem(Tail,Middle),
appendAllElements(Middle,X),
append(X,LastRowNew,X).
appendAllElements([X|Tail],List):-
append(List,X,NewList),
appendAllElements(Tail,NewList).
appendAllElements([],_).
assign(Item,Item).
skipLastItem([_],[ ]) :- !.
skipLastItem([H|T],[H|S]) :-
skipLastItem(T,S).
This sounds like homework, so I'm going to be a bit vague here...
Start with the simpler problem of replacing one value in a list. Write a recursive predicate
swap_list(X,N,A,B,Y)
which should be read as "for a list X, at position N, removing the value A and replacing it with B gives the list Y".
Now we can extend this to the case of matrices. Write a second recursive predicate
swap_matrix(X,M,N,A,B,Y)
which should be read as "for a matrix X, at position (M,N), removing element A and replacing it with B gives the matrix Y". The base case of this recursion, where M=0, will contain a call to swap_list.
Now, you can swap two positions (M1,N1) and (M2,N2) with the following:
swap(X,M1,N1,M2,N2,Y) :-
swap_matrix(X,M1,N1,A,B,Z),
swap_matrix(Z,M2,N2,B,A,Y).
Note that we insert B into the matrix Z before we even know what it is - B isn't assigned a value until the second swap_matrix call.

Resources