Thanks Ed and Luis!

I've merged your responses, please see below inline:

Ed wrote:

> My approach to this would be, using current PDL (2.080), in multiple stages:

Is there anything you are doing here that is 2.080-specific?  I'm happy to 
use the latest version, just wondering if there is something particularly 
useful in 2.080 that is noteworthy for this process.

>  *  Read the data into a matrix ($m) with columns (freq,m11,a11,etc) as 
>    you seem to have already done (although you haven’t shown any code or 
>    real-but-minimal sample data which limits how much help people can 
>    provide)

(Ya, I've not written any PDL code for this yet, just traditional perl 
code.  I thought I'd sharpen my axe before cutting down the tree...)

>  *  Slice out the complex data, e.g. $c = $m->slice(‘1:-1’) so it’s 
>    columns (m11,a11,etc)
>
>  *  Reshape that with splitdim: $reshaped = $c->splitdim(0, 2) so 
>    columns (mag,angle)
>
>  *  Convert the polar format to rectangular: 
>    $angrad = $reshaped->slice(1) * $PDL::Transform::DEG2RAD;
>    $rect = $reshaped->slice(0) * $angrad->cos->append($angrad->sin)
>    so columns (real,imag) (your formula seems to not multiply the real 
>    by the magnitude which looks to me wrong)

Oops, you are right.  I dropped that when copy-pasting into the email.  
The current non-pdl proof-of-concept code actually does this serially for 
each line and uses Math::Matrix::Complex, but it is quite slow:

  Math::Complex->make($a*cos($b*pi()/180), $a*sin($b*pi()/180))

>  *  Convert that to cdouble: $cd = czip($rect->mv(0,-1)->dog) giving row 
>    vector of cdouble
>
>  *  Reshape that with splitdim: $m22 = $cd->splitdim(0,4)->splitdim(0,2) 
>    giving (2,2,n) where n is number of original rows (this might need 
>    transposing given your data is column-major – if you leave it 
>    column-major like Fortran, make sure your docs are VERY CLEAR about 
>    that since PDL’s idiom is 0th dim is columns)

This gives me an introduction to PDL functions I've not used before, thank 
you for that!

Question about the $m22 format (2,2,n): if I take two such (2,2,n) 
matrixes and do some operation like add or multiply, will it properly 
multiply each 2x2 complex matrix at each frequency assuming the 
frequencies are aligned in order?

About row vs col-major format: I will be converting them to row-major so 
it displays "normally" when I print debug output. 

The touchstone format is strange: for n-ports <= 2 they use column-major 
and for n-ports >2 the usey a multi-line row-major format so it looks like 
a (poorly-aligned) matrix.  Not sure why it wasn't just always been 
row-major, probably a backwards compatability thing when adding support
for >2-port S-parameter files at some point, but wanted it to look like a
matrix.


Luis Mochan wrote:

> use v5.12;
> use PDL;
> use PDL::Constants qw(PI);
> use PDL::IO::Misc;
> # read all data, skip first row
> my ($f, $M11, $A11, $M21, $A21, $M12, $A12, $M22, $A22)=rcols "rem.s2p", 
> {LINES=>"1:-1:1"};
> my $rows=$f->nelem;
> my $M=pdl($M11, $M12, $M21, $M22); # Indices: filerow, position
> my $R=pdl($A11, $A12, $A21, $A22)*PI/180; #   filerow, position
> my $S=$M*exp(i()*$R); #                filerow, position

Interesting that you used e^(i*theta) instead of cos and sin.  Is there a 
PDL performance benefit here, or just a simplified notation preference?

> my $Sm=$S->mv(0,-1) # position, filerow
>       ->reshape(2,2, $rows); # column, row, filerow
> say $f, $Sm, $Sm->info;
>
> rcols would read all the data into columns. For each row $M and $R would
> have the magnitudes and the angles in radians, and $S would have the
> corresponding complex numbers. Then, for each row I rearrange the four
> corresponding $S's into a 2x2 matrix by first getting the row index
> out of the way and then doing a reshape. I ran it with a file

The code example is very useful and `rcols` could be very helpful to read 
in the data.

I have the same question as above: correct me if I'm wrong, but it looks 
like you and Ed both produced a (2,2,n) matrix where n is the file row:

If I take two such $S matrixes and do some operation like add or multiply, 
will it properly multiply each 2x2 complex matrix at each frequency 
assuming the frequencies are aligned in order?

--
Eric Wheeler

> 
>  
> 
> Best regards,
> 
> Ed
> 
>  
> 
> From: Eric Wheeler
> Sent: 01 July 2022 08:36
> To: pdl-general@lists.sourceforge.net
> Subject: [Pdl-general] How do you create a set of cdouble matrices from 
> (real, imag) values?
> 
>  
> 
> Hello all,
> 
> I'm trying to read RF touchstone (.s2p) files that are in a format like so:
> 
> Freq(MHz)  MagS11  AngS11  MagS21  AngS21   MagS12  AngS12   MagS22  AngS22
> 100         0.588   50.208  0.770   -35.964  0.770   -35.964  0.588   50.208
> ...
> 200         0.589   51.209  1.771   -34.965  1.771   -34.965  1.589   51.209
> 
> There are thousands of these lines in a file, one line for each measured
> frequency.  Each line represents a complex scattering (S-parameter) matrix
> and the mag/angle format needs to be converted to a `cdouble` to work on
> the matrix mathematically.
> 
> A single-line 2x2 complex matrix might look as follows, where S_ji is a
> complex value:
> 
>  [ S11  S12 ]
>  [ S21  S22 ]
> 
> Since we are provided values in magnitude-angle format (in this example)
> they must be converted to cdoubles so we can work on them.  There are
> several formats: RI, DB, and MA.  For the MA (mag-angle) format this is
> the transform where $a is mag and $b is angle:
> 
>         $complex = cos($b*pi()/180) + $a*sin($b*pi()/180) * i
> 
> I can generate a vector of 2x4 matrices holding mag-angle pairs by reading
> the file line by line like this:
> 
> [
>   [
>    [ S11mag S11ang S12mag S12ang ]
>    [ S21mag S21ang S22mag S22ang ]
>   ]
>   ... for each line
> ]
> 
> I'm new to using PDL and at this point I'm not sure how to convert them to
> a computable form. Since the mag/angle values need to be manipulated in
> parallel before creating a cdouble out of them I'm not sure how to go
> about this.
> 
> Here are my questions:
> 
> 1. How can I efficiently apply the
>      real = cos($b*pi()/180)
>      imag = $a*sin($b*pi()/180)
>    transform to each mag/angle pair where $a is mag and $b is angle?
> 
> 2. How can I then (or simultaneously) convert the 2x4 real-imag matrix
>    from #1 into a 2x2 cdouble matrix to look something like this?
> 
>         [
>           [
>            [ S11  S12 ]
>            [ S21  S22 ]
>           ]
>           ... for each line where Sji are cdoubles
>         ]
> 
> 3. Now that I've described the issue, is there a better way to do this?
> 
> 
> Once they are in a matrix format then PDL can convert them efficiently to
> other matrix types (T, A, Z, Y) to create parallel or series circuits with
> matrix arithmetic at each frequency.  We can then optimize the RF filter
> circuits using component models published by manufacturers from actual
> measurements.
> 
> The resulting open-source tool will be comprised of Perl modules from this
> work and published on CPAN.
> 
> Thanks for your help!
> 
> --
> Eric Wheeler
> KJ7LNW
> 
> 
> _______________________________________________
> pdl-general mailing list
> pdl-general@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/pdl-general
> 
>  
> 
> 
> 
_______________________________________________
pdl-general mailing list
pdl-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-general

Reply via email to