Converting a loop from Matlab to C - c

I have a (3x5) matrix and I want to get its reduced row echelon form.
I want to implement it in C, so I first impelemnted it in Matlab like follows:
[L,U]=lu(a);
[m,n]=size(U);
disp('convert elements in major diagonal to 1')
for s=1:m
U(s,:)=U(s,:)/U(s,s);
end
for j=m:-1:2
for i=j-1:-1:1
U(i,:)=U(i,:)-U(j,:)*(U(i,j)/U(j,j));
end
end
The above code and rref function gave the same result.
When converting this code to C, I successfully implemented the LU decomposition and the conversion of elements in major diagonal to 1 but when imlemented these nested loops
for j=m:-1:2
for i=j-1:-1:1
U(i,:)=U(i,:)-U(j,:)*(U(i,j)/U(j,j));
end
end
as follows:
for(j=m-1;j>0;j--){
for(i=j-1;i=0;i--){
for(k=0;k<n;k++){
U[i*n+k]=U[i*n+k]-(U[j*n+k]*(U[i*n+j]/U[j*n+j]));
}
}
}
I got a wrong result. How to correct it please?

If you take a closer look at your inner loop. As soon as you reach k=j you write the element U[i*n+j] or U(i,j) and use this updated value in all following iterations. Your matlab code uses the old value because you implemented vectorized operations. If you calculate *(U[i*n+j]/U[j*n+j]) outside the inner loop it should be fine.

Related

Array of structures with parfor in Matlab

I am using Matlab to work on my project, and I want to use "parfor" as a part of my code that returns an array of structures in each its iteration, But when I run my code I got some errors. I just tried to bring an example of my problem in the simplest way. Will be appreciated any helps! Here is the example:
clear;
clc;
% An arbitrary number
constant_Number=3;
tic
parfor i=1:2
k=[constant_Number,i];
r(i)=test(k);
end
toc
and test function is as follows:
function [a]=test(k)
a.first=k(1) * k(2);
a.second=k(1)+k(2);
b.first=k(1)/k(2);
b.second=k(1);
a=[a;b];
end
One note is that when I just return one structure, it works fine but when I have more than one (adding b for instance), I got the following error: "Unable to perform assignment because the indices on the left side are not compatible with the size of the right side."
Thanks,
Ali
Find the solution, just need to define a cell array and then finally merge them! Follow can be an answer:
clear;
clc;
% An arbitrary number
constant_Number=3;
% Define an arbitrary array of structure
arb_arr=[];
% Define an arbitrary cell array
r={};
tic
parfor i=1:2
k=[constant_Number,i];
r{i}=test(k);
end
for i=1:2
arb_arr=[arb_arr;r{i}];
end
toc

Assigning values in an array into another array in MATLAB

I want to assign part of a matrix into another matrix using a for loop in MATLAB. I've tried different ways but none of them worked. I want to know what's wrong with this one:
fullGrid = complex(zeros(FFTLen, numSym, numTx),zeros(FFTLen, numSym, numTx));
for i=0:(numSym/2)-1
for j=0:(FFTLen/2)-1
A(i,j)=[fullGrid(i,j)];
end
end
You made a very basic mistake. The index position in a matrix/array in
Matlab starts from 1 and not 0. So replace all the for loops from 1 to
required length.
Corrected code is given below.
fullGrid = complex(zeros(FFTLen, numSym, numTx),zeros(FFTLen, numSym, numTx));
for i=1:(numSym/2)-1
for j=1:(FFTLen/2)-1
A(i,j)=[fullGrid(i,j)];
end
end

Inserting zeros into an array and looping using a for loop

I have several arrays that are calculated example a,b and c (there are more than three) are calculated: Please note this is just an example the numbers are much larger and are not so basic
a=[1,2,3,4,5] b=[10,20,30,40,50] c=[100,200,300,400,500] and I want a for loop that inserts zeros into it so I can have the new_abc array steps look like.
1st for loop step new_abc=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
2nd for loop step new_abc=[1,0,0,2,0,0,3,0,0,4,0,0,5,0,0]
3rd for loop step new_abc=[1,10,0,2,20,0,3,30,0,4,40,0,5,50,0]
4th for loop step new_abc=[1,10,100,2,20,200,3,30,300,4,40,400,5,50,500]
how can I do this with a for loop?
I started with the code below which gives me the zeros
a=[1,2,3,4,5]
new_abc=zeros(1,length(a)*(3));
But I'm not sure how to place the values of the array a b and c using a for loopinto the correct locations ofnew_abc
I know I could place all the arrays into one large array and do a reshape but the calculated arrays I use become to large and I run out of ram, so reading / calculating each array and inserting them into one common array new_abcusing a for loop works best.
I'm running octave 3.8.1 which is like matlab.
This should do it. You can put a,b,c into a cell array. (you can also put them in a matrix...)
new_abc = zeros(1, 3*numel(a));
in = {a, b, c};
for k = 1:3
new_abc(k:3:end) = in{k};
end

Set specific rows of matrices in cell array to zero without using a for-loop

I'd like to replace a specific number of elements of my cell to zero without using for. For example to replace elements of row 2 in example cell a below: How should I proceed possibly using cellfun?
a=cell(2,3);
cellfun(#(x)(zeros(a{x}(2,:))),a);
It gives the error "Bad cell reference operation".
what if I'd like to make row 2 empty again?
Thanks in advance for any help
The action you want to perform requires an assignment within a function. The only way to achieve this is using eval, which is considered bad practice.
A loop is therefore the best remaining option, if you want to keep everything in one script:
A = {randn(2,3),randn(2,3)};
for ii = 1:numel(A)
A{ii}(2,:) = 0;
end
If you don't bother using multiple files, you can put the assignment in a function:
function [ out ] = setZero( cellarray, rowidx )
out = cellarray;
out(rowidx,:) = 0;
end
and use it as follows:
A = cellfun(#(x) setZero(x,2),A ,'uni',0)
You need to find a transformation that turns a given matrix A to a matrix where the second row is all-zero. Here are three alternatives
A=cellfun(#(x) [x(1,:); zeros(size(x(2,:))); x(3:end,:)], A, 'uni', 0)
and
A=cellfun(#(x) diag(1:size(x,1)~=2)*x, A, 'uni', 0)
and
A=cellfun(#(x) bsxfun(#times, (1:size(x,1))' ~= 2, x), A, 'uni', 0)
The first one is the most robust one because it will handle the cases that your matrix has NaN elements. The second and third alternatives simply multiply the second row by zero. The second achieves this by multiplying it with a diagonal matrix where all diagonal elements are 1 except element (2,2) which is zero. The third alternative achieves this using bsxfun.
This is to demonstrate that you can achieve this without for loops however a simple for loop is much more readable.

R fill matrix or array with conditional lagged calculation in for loop

I've dug through the list archive, and either I don't know the right words to ask this question or this hasn't come up before--
I have a simulation function where I track a list of points over time, and want to introduce an extra lagged calculation based on an assignment. I've created a very simple bit of code to understand how R fills in a matrix:
t<-21 #time step
N<-10 #points to track
#creating a matrix where it's easy for me to see how the calculation is done
NEE<-rep(NA, (t+1)*N);dim(NEE)<-c(N,(t+1))
for(i in 1:t){
NEE[,1]<-1
NEE[,i+1]<-NEE[,i]+5
}
#the thing to calculate
gt<-rep(0, (t+1)*N);dim(gt)<-c(N,(t+1))
#assigned states
veg<-c(rep(0,5), rep(1,5))
veg.com<-rep(veg, t);dim(veg.com)<-c(N,t)
for (i in 1:t){
gt[,i+1]<-ifelse(veg.com[,i]==0, NEE[,i]/5, NEE[,i-3]/5)
}
#to have a view of what happens
veg1<-gt[1,]*5 #assignment for veg.com==0
veg2<-gt[10,]*5 #assignment for veg.com==1
what<-cbind(NEE[1,], veg1,veg2)
what
Of course it works, except how it fills in the first bit (shown here as the first 4 values in veg2 of what) before the lag is in effect when veg.com==1. I'm sure there're work arounds, but I first simply want to understand what R is doing in those initial few loops?
The first two times through that second for-loop you will be using negative indexing with the expression
NEE[ , i-3]
That will return a 10 column matrix with removal of the 2nd column. The next iteration will return another 10 column matrix with removal of the first column. Negative indices remove portions of a matrix or dataframe in R

Resources