In order to convert a Matlab code to C, I want to write it in a similar way to C first then its translation would become trivial.
I faced a problem with this line:
A = E*[SOLS' ; ones(1,10 ) ];
Where E is (9x4) real matrix and SOLS is (3x10) complex matrix. A should be a 9x10 complex matrix.
I translated this line as follows:
for i=1:9
for j=1:10
A(i,j)=E(i,1)*conj(SOLS(j,1))+E(i,2)*conj(SOLS(j,2))+E(i,3)*conj(SOLS(j,3))+ E(i,4);
end
end
I got the same result. When I replaced conj(X) by real(X)-i*imag(X)for example:
conj(SOLS(j,1)) by `real(SOLS(j,1))-imag(SOLS(j,1))*i`,
I got a wrong result and I don't understand why.
I'm doing this because in the C code, every complex number is represented by a struct with variable.re the real part and variable.im the imaginary part.
typedef struct COMPLEX{
float re;
float im;
}Complex;
I want to write a very similar matlab code to C to manipulate variables easily in C with getting a similar result with Matlab.
How to correct this please?
You are using i both as a looping index and sqrt(-1).
If you want to replace conj(SOLS(j,1)) use instead
real(SOLS(j,1))-imag(SOLS(j,1))*1i
Related
I have a function M that outputs complex numbers taking an input range of r's. Instead of just outputting a single complex number, I would like to have the function to output two values (the real and imaginary parts separately) for all the output complex vectors. I would prefer the function to be anonymous function.
I tried the following but did not work since I am just getting single output complex values:
r = linspace(1E-10,1.5,100);
%M= (0.5*((1i*r+0.135).* (1i*r+0.651)))./((1i*r+0.0965).* (1i*r+0.4555))
M= #(r)(0.5*((1i*r+0.135).* (1i*r+0.651)))./((1i*r+0.0965).* (1i*r+0.4555))
How do I separate the real and complex parts of a vector?
Create an anonymous function with a different variable to avoid confusion i.e. create M with:
M = #(k)(0.5*((1i*k+0.135).* (1i*k+0.651)))./((1i*k+0.0965).* (1i*k+0.4555));
then create another anonymous function, say N, that extracts real and imag values and then stacks the result.
N = #(k) [real(M(k)); imag(M(k))];
Call this anonymous function with N(r) to get your expected result.
Alternately if you have already calculated M as in your commented out code then you can do:
N = #(k) [real(k); imag(k)];
and then call it with N(M).
I got a piece of code here and I can't seem to figure out an efficient way of converting this piece of code to the Fortran 95 equivalent. I have tried several things already, but I'm always stuck on making 1D arrays from matrices and the other way around (the point is to reduce calculation time, and if I convert them, I can't think of another way than using loops again :/).
This is the piece of code:
do i=1,dim
do j=1,dim
Snorm(i,j)=Sval(j)/Sval(i)
Bnorm(i,j)=Bval(j)/Bval(i)
Pnorm(i,j)=Pval(j)/Pval(i)
enddo
enddo
How would you write that in Fortran95 code?
The equivalent of the matrix calculations in R is this:
Snorm <- t(Sval %*% t(1/Sval))
Bnorm <- t(Bval %*% t(1/Bval))
Pnorm <- t(Pval %*% t(1/Pval))
The equivalent of it in Python is this:
Snorm = (numpy.dot((Svalmat.T),(1/Svalmat))).T
Bnorm = (numpy.dot((Bvalmat.T),(1/Bvalmat))).T
Pnorm = (numpy.dot((Pvalmat.T),(1/Pvalmat))).T
with Svalmat etc the equivalent of Sval, but then columnmatrix
Anyone has an idea?
It is not worth changing in my opinion. It is valid Fortran 95. Especially if your goal is the calculation time. Any "clever" tricks with subarrays can introduce array temporaries.
The obvious try is forall or do concurrent
forall(i=1:dim, j=1:dim)
Snorm(i,j)=Sval(j)/Sval(i)
Bnorm(i,j)=Bval(j)/Bval(i)
Pnorm(i,j)=Pval(j)/Pval(i)
end forall
and the same with do concurrent.
Notice, that your original order of the loops is probably not efficient.
This is an extension of the previously asked question: link. In a short, I am trying to convert a C program into Matlab and looking for your suggestion to improve the code as the code is not giving the correct output. Did I convert xor the best way possible?
C Code:
void rc4(char *key, char *data){
://Other parts of the program
:
:
i = j = 0;
int k;
for (k=0;k<strlen(data);k++){
:
:
has[k] = data[k]^S[(S[i]+S[j]) %256];
}
int main()
{
char key[] = "Key";
char sdata[] = "Data";
rc4(key,sdata);
}
Matlab code:
function has = rc4(key, data)
://Other parts of the program
:
:
i=0; j=0;
for k=0:length(data)-1
:
:
out(k+1) = S(mod(S(i+1)+S(j+1), 256)+1);
v(k+1)=double(data(k+1))-48;
C = bitxor(v,out);
data_show =dec2hex(C);
has = data_show;
end
It looks like you're doing bitwise XOR on 64-bit doubles. [Edit: or not, seems I forgot bitxor() will do an implicit conversion to integer - still, an implicit conversion may not always do what you expect, so my point remains, plus it's far more efficient to store 8-bit integer data in the appropriate type rather than double]
To replicate the C code, if key, data, out and S are not already the correct type you can either convert them explicitly - with e.g. key = int8(key) - or if they're being read from a file even better to use the precision argument to fread() to create them as the correct type in the first place. If this is in fact already happening in the not-shown code then you simply need to remove the conversion to double and let v be int8 as well.
Second, k is being used incorrectly - Matlab arrays are 1-indexed so either k needs to loop over 1:length(data) or (if the zero-based value of k is used as i and j are) then you need to index data by k+1.
(side note: who is x and where did he come from?)
Third, you appear to be constructing v as an array the same size of data - if this is correct then you should take the bitxor() and following lines outside the loop. Since they work on entire arrays you're needlessly repeating this every iteration instead of doing it just once at the end when the arrays are full.
As a general aside, since converting C code to Matlab code can sometimes be tricky (and converting C code to efficient Matlab code very much more so), if it's purely a case of wanting to use some existing non-trivial C code from within Matlab then it's often far easier to just wrap it in a MEX function. Of course if it's more of a programming exercise or way to explore the algorithm, then the pain of converting it, trying to vectorise it well, etc. is worthwhile and, dare I say it, (eventually) fun.
I have a text file which contains a 64x64 matrix values and they are complex numbers. I want to read them from a file but I'm having difficulties. Either using the complex library of C or creating a new data type for complex numbers is okay for me, I just need them read correctly.
What I mean is, whether using:
#include <complex.h>
int complex matrix[64][64];
or creating a data type for it:
typedef struct {
int real, imag;
} Complex;
Complex matrix[64][64];
is okay for me as long as they are read correctly.
Below you can find 2x3 matrix, just to demonstrate how the numbers are in my file:
{{-32767, 12532 + 5341I, -3415 - 51331I}
{32767I, 32609 + 3211I, 32137 + 6392I}}
So as you can see some parts have both the real and imaginary part, some just the imaginary and some just the real part, and all the imaginary numbers have upper case 'i' letter at the end. If you could help me with that, I would be glad.
Two common design patterns apply:
1) Recursive descent parser that accepts a 'language'
2) State Machine
Both cases can benefit from a read_char() function, that exits with error if it encounters
anything else than '{', '}', 0-9, i, +, - and which skips all white spaces (ch<=32).
A state machine can be a bit more versatile: if at any point there is '+' or '-', one can just add or subtract the next value (ending with 'i' or non 'i') to the currently accumulated value. (Then the state machine is able to also calculate 1+2-1+1i while it goes...)
It doesn't matter how the number are organized, if they' re aligned in memory you can read them all at once:
Complex matrix[64][64];
fread(matrix,sizeof(Complex),64*64, your_file_pointer);
Same for writing:
fwrite(matrix, sizeof(Complex), 64*64, your_file_pointer);
Is there any way to "vector" assign an array of struct.
Currently I can
edges(1000000) = struct('weight',1.0); //This really does not assign the value, I checked on 2009A.
for i=1:1000000; edges(i).weight=1.0; end;
But that is slow, I want to do something more like
edges(:).weight=[rand(1000000,1)]; //with or without the square brackets.
Any ideas/suggestions to vectorize this assignment, so that it will be faster.
Thanks in advance.
This is much faster than deal or a loop (at least on my system):
N=10000;
edge(N) = struct('weight',1.0); % initialize the array
values = rand(1,N); % set the values as a vector
W = mat2cell(values, 1,ones(1,N)); % convert values to a cell
[edge(:).weight] = W{:};
Using curly braces on the right gives a comma separated value list of all the values in W (i.e. N outputs) and using square braces on the right assigns those N outputs to the N values in edge(:).weight.
You can try using the Matlab function deal, but I found it requires to tweak the input a little (using this question: In Matlab, for a multiple input function, how to use a single input as multiple inputs?), maybe there is something simpler.
n=100000;
edges(n)=struct('weight',1.0);
m=mat2cell(rand(n,1),ones(n,1),1);
[edges(:).weight]=deal(m{:});
Also I found that this is not nearly as fast as the for loop on my computer (~0.35s for deal versus ~0.05s for the loop) presumably because of the call to mat2cell. The difference in speed is reduced if you use this more than once but it stays in favor of the for loop.
You could simply write:
edges = struct('weight', num2cell(rand(1000000,1)));
Is there something requiring you to particularly use a struct in this way?
Consider replacing your array of structs with simply a separate array for each member of the struct.
weights = rand(1, 1000);
If you have a struct member which is an array, you can make an extra dimension:
matrices = rand(3, 3, 1000);
If you just want to keep things neat, you could put these arrays into a struct:
edges.weights = weights;
edges.matrices = matrices;
But if you need to keep an array of structs, I think you can do
[edges.weight] = rand(1, 1000);
The reason that the structs in your example don't get initialized properly is that the syntax you're using only addresses the very last element in the struct array. For a nonexistent array, the rest of them get implicitly filled in with structs that have the default value [] in all their fields.
To make this behavior clear, try doing a short array with clear edges; edges(1:3) = struct('weight',1.0) and looking at each of edges(1), edges(2), and edges(3). The edges(3) element has 1.0 in its weight like you want; the others have [].
The syntax for efficiently initializing an array of structs is one of these.
% Using repmat and full assignment
edges = repmat(struct('weight', 1.0), [1 1000]);
% Using indexing
% NOTE: Only correct if variable is uninitialized!!!
edges(1:1000) = struct('weight', 1.0); % QUESTIONABLE
Note the 1:1000 instead of just 1000 when indexing in to the uninitialized edges array.
There's a problem with the edges(1:1000) form: if edges is already initialized, this syntax will just update the values of selected elements. If edges has more than 1000 elements, the others will be left unchanged, and your code will be buggy. Or if edges is a different type, you could get an error or weird behavior depending on its existing datatype. To be safe, you need to do clear edges before initializing using the indexing syntax. So it's better to just do full assignment with the repmat form.
BUT: Regardless of how you initialize it, an array-of-structs like this is always going to be inherently slow to work with for larger data sets. You can't do real "vectorized" operations on it because your primitive arrays are all broken up in to separate mxArrays inside each struct element. That includes the field assignment in your question – it is not possible to vectorize that. Instead, you should switch a struct-of-arrays like Brian L's answer suggests.
You can use a reverse struct and then do all operations without any errors
like this
x.E(1)=1;
x.E(2)=3;
x.E(2)=8;
x.E(3)=5;
and then the operation like the following
x.E
ans =
3 8 5
or like this
x.E(1:2)=2
x =
E: [2 2 5]
or maybe this
x.E(1:3)=[2,3,4]*5
x =
E: [10 15 20]
It is really faster than for_loop and you do not need other big functions to slow your program.