Computing.Net > Forums > Programming > batch transpose a matrix

batch transpose a matrix

Reply to Message Icon

Original Message
Name: maxbre
Date: February 4, 2008 at 02:22:32 Pacific
Subject: batch transpose a matrix
OS: win2k
CPU/Ram: 1 gb
Model/Manufacturer: fujitsu
Comment:

Hello
I have this problem to sort out hopefully by means of a batch script

Given a 3x3 matrix called A

A c1 c2 c3
r1 1 2 3
r2 4 5 6
r3 7 8 9

I have to transpose it (switch of rows with columns) so that to obtain a new matrix called At:

A r1 r2 r3
c1 1 4 7
c2 2 5 8
c3 3 6 9


What I have managed up to now is the following script

for /f "tokens=1-4" %%b in (a.txt) do (
echo %%b >>at.txt
echo %%c >>at.txt
echo %%d >>at.txt
echo %%e >>at.txt
)

which is giving as a result:

a
c1
c2
c3
r1
1
2
3
r2
4
5
6
r3
7
8
9


and then in order to fully accomplish my task I need to ?move every single package made of 4 rows? side by side in a different file (to do);
but because all my attempt seems to me quite goofy I?m wondering if there is a better way to do it (certainly it is); any hints much appreciated?

max


Report Offensive Message For Removal


Response Number 1
Name: IVO
Date: February 4, 2008 at 03:58:48 Pacific
Reply: (edit)

As to transpose a matrix you have to set a[i,j]:=a[j,i], the following batch does the job

@Echo Off
SetLocal EnableDelayedExpansion

Type Nul > A.tmp
Set n=1
For /F "tokens=1-4" %%a in (A.txt) Do (
Echo.[1,!n!]%%a>> A.tmp
Echo.[2,!n!]%%b>> A.tmp
Echo.[3,!n!]%%c>> A.tmp
Echo.[4,!n!]%%d>> A.tmp
Set /A n+=1
)

Sort < A.tmp > At.tmp

Type Nul > At.txt
Set row=
Set n=0
For /F "tokens=2 delims=]" %%j in (At.tmp) Do (
Set row=!row! %%j
Set /A n+=1
If !n! equ 4 (
Echo.!row:~1!>> At.txt
Set row=
Set n=0)
)

Del A*.tmp
:: End_Of_Batch


Report Offensive Follow Up For Removal

Response Number 2
Name: Mechanix2Go
Date: February 4, 2008 at 04:10:52 Pacific
Reply: (edit)

Hi IVO,

Mine is rough, but it 'works'. LOL

:: transpose 4X4 matrix

@echo off > newfile
setLocal EnableDelayedExpansion

set /a N+=1

for /f "tokens=1-4 delims= " %%a in (%1) do (
set v!N!=%%a& set /a N+=1
set v!N!=%%b& set /a N+=1
set v!N!=%%c& set /a N+=1
set v!N!=%%d& set /a N+=1
)
echo !v1! !v5! !v9! !v13! >> newfile
echo !v2! !v6! !v10! !v14! >> newfile
echo !v3! !v7! !v11! !v15! >> newfile
echo !v4! !v8! !v12! !v16! >> newfile



=====================================
If at first you don't succeed, you're about average.

M2



Report Offensive Follow Up For Removal

Response Number 3
Name: klint
Date: February 4, 2008 at 07:10:46 Pacific
Reply: (edit)

Why are you lot using batch to work with matrices? What have you got against proper programming languages?


Report Offensive Follow Up For Removal

Response Number 4
Name: maxbre
Date: February 4, 2008 at 07:36:56 Pacific
Reply: (edit)

Hi IVO, M2 and klint

As usual you are giving me a lot of food for my poor brain; I’ve been carefully studying your batch lessons (both perfectly working) and now I’m pointing out some questions:

To Ivo:
I understand (almost) well what you did until the sorting of At.tmp but then I get a little in trouble with the interpretation of your last part of the script; please check if it’s right what I struggled to understand so far:

Set row=
:: create an empty variable called row
Set n=0
:: create a numerical variable called n

For /F "tokens=2 delims=]" %%j in (At.tmp) Do (
:: for command to extract the second token

Set row=!row! %%j
:: create a new variable called row composed by a space (empty) and the token %%j

Set /A n+=1
::create a numerical incremental variable called n

If !n! equ 4 (
::test if on the numerical variable called n

Echo.!row:~1!>> At.txt
:: mmmh????

Set row=
:: emptying the variable row

Set n=0)
:: resetting the variable n to zero
)

and most of all I’m wondering why there is no echoing for the token less than row 4 (but they appear in the final result)? Missing some points…


To M2:
After some long (and slow - sorry for this -) thought I understand your concatenation of the variable N passing each time an incremental number to next set command;
but why the echoing of the dynamic variables is not inside the brackets of the do command? And why are not the variables loosing memory of their content?

To klint:
Nothing against proper programming but sometimes is so useful to have the “freedom” to work without any superimposed structure…

bye and thank you all
max


Report Offensive Follow Up For Removal

Response Number 5
Name: Mechanix2Go
Date: February 4, 2008 at 21:47:00 Pacific
Reply: (edit)

"but why the echoing of the dynamic variables is not inside the brackets of the do command?"

Within the FOR loop it sets the vars; then outside it ECHOs into a file. The vars keep their value until you ENDLOCAL or until the BAT quits.



=====================================
If at first you don't succeed, you're about average.

M2



Report Offensive Follow Up For Removal


Response Number 6
Name: IVO
Date: February 5, 2008 at 03:25:45 Pacific
Reply: (edit)

As you stated the script is made up by two sections, the first one does fission the matrix into its atomic elements prefixing them with the transposed indexes, then after sorting to the transposed sequence the target matrix has to be constructed again by fusion of four elements on each line.

Here is why the echoing is performed only after the fourth tick of the counter: previously the items are stacked at each At.tmp read into the variable row.

The statement "Set row=!row! %%j" just takes the previuos set row and adds to it the new accessed item from At.tmp.

As the quoted statement adds a space at the begnning of each created row, when echoing, the extra space is discarded by referring the substring of row starting at position 2 (~1 as syntax starts from 0).

By the way, M2's solution is straightforward, but mine is suitable to be generalized to transpose whatever matrix of dimension [i,j].

I hope this clarifies.


Report Offensive Follow Up For Removal

Response Number 7
Name: Mechanix2Go
Date: February 5, 2008 at 03:41:32 Pacific
Reply: (edit)

Hi IVO,

Yeah, I couldn't figure out how to generalize. But I thought you would.

:)


=====================================
If at first you don't succeed, you're about average.

M2



Report Offensive Follow Up For Removal

Response Number 8
Name: maxbre
Date: February 5, 2008 at 05:26:10 Pacific
Reply: (edit)

Hi IVO & M2

TO IVO

now I see what you mean when you say:
"the echoing is performed only after the fourth tick of the counter: previously the items are stacked at each At.tmp read into the variable row"
i.e. the echo releases the row variable content after the fourth tick because until then it accumulates its content, right?

TO M2
thank also to your hints, now it's clear why the echo command is placed outside the for loop (it was a sort of similar problem above described for the row variable accumulating the content until the echoing is releasing it)


TO BOTH YOU
let me then point out a further question:
I do agree that ivo’s batch "is suitable to be generalized to transpose whatever matrix of dimension [i,j]" but I'm also wondering if there is an ‘intrinsic’ limitation given the fact that, as far as I know, the number of used tokens may not be bigger than 26, right? therefore a maximum matrix handled by the script is a 26*26 matrix, or not?
On the other hand I'm pretty sure you can find a workaround to sort out this limitation (if it really exists)

well that's all for now, bye and thanks to you all great masters of batch scripting...

max


Report Offensive Follow Up For Removal

Response Number 9
Name: IVO
Date: February 5, 2008 at 08:48:31 Pacific
Reply: (edit)

Well, eventually here is the general version of the script to transpose a (text file stored) matrix.

The code auto-detects the matrix rank [i,j] and the matrix does not need to be a square one.

Take that as a sophisticated joke as I agree with klint that programming is better to perform these computations. To fly to the Moon you can relay on chemical rockets, but to jump to Mars a nuclear engine is required!

And the below code has no limits (almost tokens related) as it does'nt relay on tokens to detect columns.

Usage: BatchName [pathname][filename]

@Echo Off
SetLocal EnableDelayedExpansion

Echo.
If "%1"=="" (
Echo. Usage: %0 [pathname][filename]
GoTo :EOF)
If not exist %~f1 (
Echo. %~f1 not found
GoTo :EOF)

Echo. Transposing %~f1 into %~dpn1t.txt
Echo.

Type Nul > %~dpn1.tmp
Set i=0
For /F "delims=" %%i in (%~f1) Do (
Set /A i+=1
If !i! lss 100 Set i=0!i!
If !i! lss 10 Set i=0!i!
Set j=0
For %%a in (%%i) Do (
Set /A j+=1
If !j! lss 100 Set j=0!j!
If !j! lss 10 Set j=0!j!
Echo.[!j!,!i!]%%a>> %~dpn1.tmp
)
)

Type Nul > %~dpn1t.txt
Set row=
Set n=0
For /F "tokens=2 delims=]" %%j in ('Sort ^< %~dpn1.tmp') Do (
Set row=!row! %%j
Set /A n+=1
If !n! equ %i% (
Echo.!row:~1!>> %~dpn1t.txt
Set row=
Set n=0
)
)

Del %~dpn1.tmp
:: End_Of_Batch


Report Offensive Follow Up For Removal

Response Number 10
Name: maxbre
Date: February 5, 2008 at 23:46:22 Pacific
Reply: (edit)

well ivo, I think I've enough to learn here for the next few years; thank you again for your last script (it's really amazing).
Finally I do perfectly agree with all you about the need to taylor the right tool for every different objectve: i.e. a surgeon will never use (hopefully) a chainsaw to cut a body nor a woodsman will use a lancet to slash a tree!
bye
max

ps I'm not sure I've got every point of your last batch (too high!) but I do not want to bother you further with many other trivial questions...

pps what do you think about python? I'm moving now my first steps on it, do you think it's worth?
...right, klint?


Report Offensive Follow Up For Removal

Response Number 11
Name: Mechanix2Go
Date: February 6, 2008 at 00:25:00 Pacific
Reply: (edit)

"Take that as a sophisticated joke as I agree with klint that programming is better to perform these computations. To fly to the Moon you can relay on chemical rockets, but to jump to Mars a nuclear engine is required!"

Depends on how much time you've got.

http://www.nasa.gov/mission_pages/n...

9 1/2 years to Pluto. No passengers.



=====================================
If at first you don't succeed, you're about average.

M2



Report Offensive Follow Up For Removal

Response Number 12
Name: Mechanix2Go
Date: February 6, 2008 at 01:13:39 Pacific
Reply: (edit)

"the right tool"

Like a rusty pocket knife for a field trach?

:)



=====================================
If at first you don't succeed, you're about average.

M2



Report Offensive Follow Up For Removal

Response Number 13
Name: klint
Date: February 6, 2008 at 07:04:55 Pacific
Reply: (edit)

Sorry for the delay in coming back to this thread. I stopped reading it when my mind was about to explode.

maxbre, you asked about Python. It's certainly gaining in popularity. Its syntax is more concise than Java (and, some people may argue, more readable) especially when manipulating complex data structures. You have to decide whether you want to learn the current Python 2.5/6 or wait a little and learn the forthcoming, totally revamped from scratch, Python 3.


Report Offensive Follow Up For Removal

Response Number 14
Name: FishMonger
Date: February 6, 2008 at 09:28:10 Pacific
Reply: (edit)


#!perl

use warnings;
use strict;
use Math::Matrix;

my @AoA;
open FILE, '<', 'A.txt' or die $!;
while ( <FILE> ) {
chomp;
push @AoA, [split ' '];
}

my $matrix = new Math::Matrix(@AoA);
$matrix = $matrix->transpose;

open FILE, '>', 'A_transposed.txt' or die $!;
for my $row ( 0..@{$matrix} - 1 ) {
print FILE "@{$matrix->[$row]}" . "\n";
}



Report Offensive Follow Up For Removal

Response Number 15
Name: IVO
Date: February 7, 2008 at 10:12:01 Pacific
Reply: (edit)

Just for sake of correctness, the general version of the script to transpose a matrix I posted as Response #9 suffers a bug due to the weird MS octal notation in batch (i.e. 07 + 1 = 010). So here the right code.

@Echo Off & SetLocal EnableDelayedExpansion
:: Transpose a matrix of rank [i,j] with i,j < 1000
:: stored in a txt file, each row fitting one line

Echo.
If "%1"=="" (Echo. Usage: %0 [pathname][filename] & GoTo :EOF)
If not exist %~f1 (Echo. %~f1 not found & GoTo :EOF)
Echo. %~f1 transposed to %~dpn1t%~x1
Echo.

Type Nul > %~dpn1.tmp
Set i=0
For /F "delims=" %%i in (%~f1) Do (
Set /A i+=1
Set m=!i!
If !i! lss 100 Set m=0!m!
If !i! lss 10 Set m=0!m!
Set j=0
For %%a in (%%i) Do (
Set /A j+=1
Set n=!j!
If !j! lss 100 Set n=0!n!
If !j! lss 10 Set n=0!n!
Echo.[!n!,!m!]%%a>> %~dpn1.tmp
)
)

Type Nul > %~dpn1t%~x1
Set row=
Set j=0
For /F "tokens=2 delims=]" %%a in ('Sort ^< %~dpn1.tmp') Do (
Set row=!row! %%a
Set /A j+=1
If !j! equ %i% (
Echo.!row:~1!>> %~dpn1t%~x1
Set row=
Set j=0
)
)
Del %~dpn1.tmp
:: End_Of_Batch


Report Offensive Follow Up For Removal

Response Number 16
Name: maxbre
Date: February 8, 2008 at 00:43:36 Pacific
Reply: (edit)

thanks to all for your valuable informations; I'm still doing something on Python: I like the tideness of its syntax (and also because it's free!)
klint do you think it would be a comlete different world the new version of Python so that it's not worth working on it untill the new release?
bye
max



Report Offensive Follow Up For Removal

Response Number 17
Name: klint
Date: February 8, 2008 at 02:07:38 Pacific
Reply: (edit)

I haven't looked at Python for about a year now (too busy with other things) but I would say it's still worth learning 2.x because the concepts are still valid. Also, Python 3 is still in alpha test phase, and if your intention is too actually start using Python right now (instead of just reading about it) then go ahead and use the current released version. On the Windows platform, there's a good package called ActivePython (from activestate.com), which includes the current version of Python together with an integrated development environment and libraries for using Win32 functions (and it's also free.)


Report Offensive Follow Up For Removal






Use following form to reply to current message:

   Name: From My Computing.Net Settings
 E-Mail: From My Computing.Net Settings

Subject: batch transpose a matrix

Comments:

 


  Homepage URL (*): 
Homepage Title (*): 
         Image URL: 
 
Data Recovery Software




Have you ever used OpenOffice?

Yes, as my main suite.
Yes, occationally.
Yes, but only once.
No, never.


View Results

Poll Finishes In 5 Days.
Discuss in The Lounge