I'm trying to understand and learn the C language, and since I used to work in Matlab, I'm interested in knowing how this code would be converted into C.
for j=1:n
v=A(:,j);
for i=1:j-1
R(i,j)=Q(:,i)'*A(:,j);
v=v-R(i,j)*Q(:,i);
end
R(j,j)=norm(v);
Q(:,j)=v/R(j,j);
end
Do you know about the Matlab Coder? Matlab can automatically generate c/c++ code for you. It has its limitations, but if are trying to learn c from Matlab, using the coder should be the best way for you to populate many examples.
Arrays are declared and accessed like so:
const int N = 10; // needs to be a constant
double v[N]; // 1-d
double A[N][N]; // 2-d
v[0] = A[1][2]; // indexing starts at 0, not 1
C doesn't do automatic vectorization like matlab, so you have to do it in for-loops manually. Instead of R(i,j)=Q(:,i)'*A(:,j),
for (int k = 0; k < N; ++k) {
R[i][j] += Q[k][i] * A[k][j];
}
That last piece also demonstrates what a for-loop looks like - the first "argument" of the "for" is the initialization of the indexing variable k, the second sets the condition under which the for loop continues, and the third increments k. The code to be executed in the loop is enclosed in braces {}.
The main logical difference is that you have to do everything element-by-element in C.
Related
It says the index in position 1 of the diff function must be a positive integer or a logical value which is it so why am I getting this error? I'm trying to implement the basic Euler method in MATLAB
y=zeros(1,6);
h=0;
x(1)= 0;
y(1)= 0;
i=1;
diff(y,x)= x+y
while h<=1
y(i+1)=y(i) + h*f(x(i))
h=h+0.2;
i=i+1;
end
Edit: Changed it to the code below but it still raises the same error in the line y(i+1)=...
y=zeros(1,6);
x=zeros(1,6);
h=0;
i=1;
g=x+y;
while h<=1
y(i+1)=y(i) + h*g(x(i),y(i));
h=h+0.2;
i=i+1;
end
Approach: I would recommend defining an anonymous function
diffh =#(x,y) x + y; % define this prior to use
to use later inside the loop.
Then changing one line
y(ii+1)=y(ii) + h*diffh(x(ii),y(ii));
should work. I've added the "h" to the end as a convention to remind me this is an anonymous function (see note at end).
% MATLAB R2019a
y = zeros(1,6);
x = zeros(1,6);
h=0;
ii=1;
diffh =#(x,y) x + y;
while h <= 1
y(ii+1)=y(ii) + h*diffh(x(ii),y(ii));
x(ii+1) = x(ii)+h;
h=h+0.2;
ii=ii+1;
end
Side note: I've also changed the index i to ii by convention (though MATLAB doesn't require this). Unless you overwrite their values, both i and j default as the sqrt(-1). You can absolutely use them as indices without issue (provided you don't later need complex or imaginary numbers). To ensure this never becomes an issue, many people just use ii and jj as a convention to preserve the default values.
Note that diff is a MATLAB function itself.
Using i as an index is mostly not a good idea in Matlab, because i is also imaginary number. Perhaps another name could solve the problem.
I am actually translating a matlab script into python an i have a problem using arrays in python (I am still a beginner) numpy.
My question is this:
In matlab I am computing the fourier transform of several signals and I am storing dynamically it in a 3 by 3 array say U. A simple example of what i want to do is as follows;
l = 3 ;
c = 0 ;
for i = 1:3
for j = 1:10
c=c+1 ;
a = j + 1;
U(i,c,:)=a ;
end
end
I want to translate this to python and I am unable to create the array U that stores dynamically the value of 'a' in U.
Note : Here am computing 'a' as j+1 for simplicity but in my script 'a' is an array (the fourier transform of a signal)
Sorry for my bad english, I am french. T
I believe you will ultimately want something like this. One of the things that was confusing was what your loop variable c and j were doing. It seems like you wanted c=j, so I changed that below. The one thing you need to watch out for is that python objects are indexed from 0, whereas Matlab objects are index from 1. So below, if you actually start examining the values of i and j, you will see that they start from 0.
import numpy
L = 3;
C = 10;
N = 50; # Size of the Fourier array
U = numpy.zeros((L,C,N))
for i in range(L):
for j in range(C):
# Create a matrix of scalars, for testing
a = i*j*numpy.ones((N,));
U[i,j,:] = a;
I'm trying to write code to find A in a system of linear equations Ax=B, so I used LU decomposition. Now that I have L and U properly, I'm stuck in the forward substitution in order to get the y in B=Ly.
I wrote some code in MatLab that works perfectly, but I can't get the same results rewriting the code in C. So I was wondering if someone may know what i'm doing wrong, I'm not fully used to C.
Here's my code in MatLab:
y(1,1) = B(1,1)/L(1,1);
for i= 2:n
sum=0;
sum2=0;
for k = 1: i-1
sum = sum + L(i,k)*y(k,1);
end
y(i,1)=(B(i,1)-sum)/L(i,i);
end
where L is my lower triangle matrix, B is a vector of the same size, and n is 2498 in this case.
My C code is the following:
float sum = 0;
y_prev[0]=B[0]/(float)Low[0][0];
for (int i = 1; i < CONST; i++)
{
for (int k = 0; k < i-1; k++)
{
sum = sum +Low[i][k]*y_prev[k];
}
y_prev[i]= (B[i]- sum)/(float)Low[i][i];
}
One difference between the codes comes from the way you've changed the for loop indices to work with the zero based indexing in C. (I can't run the MATLAB version, and don't have some of the context for the code, so there may be other differences.)
The variables i and k have values which are smaller by 1 in the C code. This is exactly what you want for the loop indices, but a problem arises when you use i to control the number of iterations in the inner loop over k. This is i-1 in both versions of the code, even though i has different values. For instance, in the first iteration of the outer loop the inner loop runs once in the MATLAB code but not at all in the C one.
A possible fix would be to rewrite the inner loop in the C code as
for (int k = 0; k < i; k++)
{
sum = sum +Low[i][k]*y_prev[k];
}
A second difference is that you're resetting sum to zero in the MATLAB code but not in the C (the MATLAB code also has a sum2 which doesn't seem to be used?). This will cause differences in y_prev[i] for i>0.
Edit3: Optimized by limiting the initialization of the array to only odd numbers. Thank you #Ronnie !
Edit2: Thank you all, seems as if there's nothing more I can do for this.
Edit: I know Python and Haskell are implemented in other languages and more or less perform the same operation I have bellow, and that the complied C code will beat them out any day. I'm just wondering if standard C (or any libraries) have built-in functions for doing this faster.
I'm implementing a prime sieve in C using Eratosthenes' algorithm and need to initialize an integer array of arbitrary size n from 0 to n. I know that in Python you could do:
integer_array = range(n)
and that's it. Or in Haskell:
integer_array = [1..n]
However, I can't seem to find an analogous method implemented in C. The solution I've come up with initializes the array and then iterates over it, assigning each value to the index at that point, but it feels incredibly inefficient.
int init_array()
{
/*
* assigning upper_limit manually in function for now, will expand to take value for
* upper_limit from the command line later.
*/
int upper_limit = 100000000;
int size = floor(upper_limit / 2) + 1;
int *int_array = malloc(sizeof(int) * size);
// debug macro, basically replaces assert(), disregard.
check(int_array != NULL, "Memory allocation error");
int_array[0] = 0;
int_array[1] = 2;
int i;
for(i = 2; i < size; i++) {
int_array[i] = (i * 2) - 1;
}
// checking some arbitrary point in the array to make sure it assigned properly.
// the value at any index 'i' should equal (i * 2) - 1 for i >= 2
printf("%d\n", int_array[1000]); // should equal 1999
printf("%d\n", int_array[size-1]); // should equal 99999999
free(int_array);
return 0;
error:
return -1;
}
Is there a better way to do this? (no, apparently there's not!)
The solution I've come up with initializes the array and then iterates over it, assigning each value to the index at that point, but it feels incredibly inefficient.
You may be able to cut down on the number of lines of code, but I do not think this has anything to do with "efficiency".
While there is only one line of code in Haskell and Python, what happens under the hood is the same thing as your C code does (in the best case; it could perform much worse depending on how it is implemented).
There are standard library functions to fill an array with constant values (and they could conceivably perform better, although I would not bet on that), but this does not apply here.
Here a better algorithm is probably a better bet in terms of optimising the allocation:-
Halve the size int_array_ptr by taking advantage of the fact that
you'll only need to test for odd numbers in the sieve
Run this through some wheel factorisation for numbers 3,5,7 to reduce the subsequent comparisons by 70%+
That should speed things up.
In C, is there any built-in array slicing mechanism?
Like in Matlab for example,
A(1:4)
would produce =
1 1 1 1
How can I achieve this in C?
I tried looking, but the closest I could find is this: http://cboard.cprogramming.com/c-programming/95772-how-do-array-subsets.html
subsetArray = &bigArray[someIndex]
But this does not exactly return the sliced array, instead pointer to the first element of the sliced array...
Many thanks
Doing that in std C is not possible. You have to do it yourself.
If you have a string, you can use string.h library who takes care of that, but for integers there's no library that I know.
Besides that, after having what you have, the point from where you want to start your subset, is actually easy to implement.
Assuming you know the size of your 'main' array and that is an integer array, you can do this:
subset = malloc((arraySize-i)*sizeof(int)); //Where i is the place you want to start your subset.
for(j=i;j<arraySize;j++)
subset[j] = originalArray[j];
Hope this helps.
Thanks everyone for pointing out that there is no such built-in mechanism in C.
I tried using what #Afonso Tsukamoto suggested but I realized I needed a solution for multi-dimensional array. So I ended up writing my own function. I will put it in here in case anyone else is looking for similar answer:
void GetSlicedMultiArray4Col(int A[][4], int mrow, int mcol, int B[1][4], int sliced_mrow)
{
int row, col;
sliced_mrow = sliced_mrow - 1; //cause in C, index starts from 0
for(row=0; row < mrow; row++)
{
for (col=0; col < mcol; col++)
{
if (row==sliced_mrow) B[0][col]=A[row][col];
}
}
}
So A is my input (original array) and B is my output (the sliced array).
I call the function like this:
GetSlicedMultiArray4Col(A, A_rows, A_cols, B, target_row);
For example:
int A[][4] = {{1,2,3,4},{1,1,1,1},{3,3,3,3}};
int A_rows = 3;
int A_cols = 4;
int B[1][4]; //my subset
int target_row = 1;
GetSlicedMultiArray4Col(A, A_rows, A_cols, B, target_row);
This will produce a result (multidimensional array B[1][4]) that in Matlab is equal to the result of A(target_row,1:4).
I am new to C so please correct me if I'm wrong or if this code can be made better... thanks again :)
In C,as far as I know, array name is just regarded as a const pointer. So you never know the size of the subset. And also you can assign a arrary to a new address. So you can simply use a pointer instead. But you should manage the size of the subset yourself.