I have a square matrix file, and I want to load it into Perl. I want to operate like 2 dimensional array which in C is like matrix[14][50], and then it goes directly to row 14 column 50. Is there a way to do this?
And can I modify the input file directly or I have to load it into a variable, do the operation and then write it out?
I have written a module which is likely able to do what you need. Tie::Array::CSV. It creates a magical array of arrayrefs (a Perl 2D array), which allows row and element r/w access to a file. Depending on your column separator you might need to adjust the options (CSV is default).
It works very similarly with different syntax.
>matrix <- array(1:10000, dim=c(100,100)) #50 X 50 matrix
>somevariable <- matrix[14,51] #somevariable will now be 5014
Turn this into a R script
and call it from perl such as
my $var = `rscript arguments`; # $var is now the output of your rscript
Related
I have a txt file with a bunch of parameters created by the external program.
Let us consider a simple example:
input.txt
a= 1
b= 2
c= 3
I can read both names and values in matlab 2018a:
[names, values]=textread('input.txt','%s%f');
As a result, names will be a 3x1 cell array with entries a=, b= and so on, whereas values will be a conventional 3x1 array of doubles.
In my current workspace, I want to initialize the obtained variables (with the corresponding names) and set them equal to the corresponding values.
In the example above, variables a=1, b=2 and c=3 should be created in the current workspace.
I have no idea how to do it...
Thanks!
Edit: in my actual example variable names can contain many characters/numbers (by the standard convention, variable names always start with the letter, not a digit), e.g.
Rcirc1= 30.0
SaveStride= 1000
You can use a combination of regexp and assignin to achieve the desired output:
%Read data.
data = fileread('input.txt')
%Extract variable name and value in named groups.
s = regexp(data,'(?<var>[A-Z]\w+)\D+(?<val>\d+(?:\.\d+)?)','names');
%Loop over struct s contents to create variables in workspace.
cellfun(#(x,y) assignin('base',x,str2double(y)),{s.var},{s.val})
The assignments in the text file can be directly evaluated by MATLAB. You don't need to extract them. In order to silence the text printed for each line you can use evalc
evalc(fileread('input.txt'));
I have three m files using the same variables and carrying out calculations on these variables. I have made an index m file in which i have declared all the variables and I can share the variables to the remaining m files using the variable names. My problem is that the variable names change too often and then I have to change the variable names in all these files manually. How can I make a Matlab script which can automatically get the variable names and value from the index m file and put these to the remaining m files.
I feel like you just need a little example from where you could go on so here we go:
First calling each value with a different variable name. if you have a lot of values of the same type a array is easier like:
A0=0; A1=6; A2=12 %each one with its own name
B=zeros(16,1); %create an array of 16 numbers
B(1)= 0; %1 is the first element of an array so care for A0
B(2)= 6;
B(8)= 12;
disp(B); % a lot of numbers and you can each address individually
disp(B(8)); %-> 12
you can put all that in your script and try it. Now to the function part. Your function can have input, output, neither or both. If you just want to create data you wont need an input but an output.
save this as myfile1.m:
function output = myfile1()
number=[3;5;6]; %same as number(1)=3;number(2)=5;number(3)=6
%all the names just stay in this function and the variable name is chosen in the script
output = number; %output is what the file will be
end
and this as myfile2.m
function output = myfile2(input)
input=input*2;%double all the numbers
%This will make an error if "input" is not an array with at least 3
%elements
input(3)=input(3)+2; %only input(3) + 2;
output = input;
end
and now try
B=myfile1() %B will become the output of myfile1
C=myfile2(B) %B is the input of myfile2 and C will become the output
save('exp.mat','C')
I hope this will get you started.
This question already exists:
Generating vectors from multiple matrices
Closed 6 years ago.
I am really new in matlab. So i am trying to learn the very basics. I have 8 tsv files with names like 2004.07.01.0000.tsv, 2004.07.01.0300.tsv, where each file has 72 rows and 144 columns. I am trying to automatically import all of those files to matlab in a matrix form to calculate the mean, median, skewness (for data correction). What I did is that I imported one file (2004.07.01.0000.tsv) using matlab gui, then I generated a function called importfile. I am trying to use a for loop to access all the data in those files but I could not figure it out. I tried (not sure at all):
for fileNum=1:8;
startRow=1;
endRow=72;
filename
a=importfile(filename, startRow, endRow);
end
If your importfile() function works correctly, in this manner at every for-loop iteration you'll overwrite a with the most recent imported file. You should concatenate all your files (i.e. matrices) instead.
A matrix concatenation can either be done by rows (i.e. horizontal concatenation) or by columns (i.e. vertical concatenation). As I understand, you want a vertical concatenation in order to generate a unique matrix with 144 columns and as many rows as your single files contain.
Thus you should change the loop as follows
myMatrix=[];
for fileNum=1:8;
startRow=1;
endRow=72;
filename
myMatrix=[myMatrix ; importfile(filename, startRow, endRow)];
end
The vertical concatenation can be done by means of the ; operator, thus an instruction like A=[B ; C] will create a matrix A by concatenating matrices B and C. In your case you initialize myMatrix as empty and then you will vertically concatenate (in an iterative fashion) all outputs from importfile(), that are your .tsv files.
At the end of the loop, myMatrix should have size NxM where M is 144 and N is the sum of the number of rows across all your files (8*72).
Update
If you have to pass explicitly the filename to the importfile() function you can create a cell array of strings in which each element of the cell is a filename. Thus in our case the cell array will be something like:
filenames={'filename1.tsv','filename2.tsv',...,'filename8.tsv'};
obviously you must replace the strings inside the cell with the proper filenames and finally you can slightly edit the loop as follows
myMatrix=[];
for fileNum=1:8;
startRow=1;
endRow=72;
myMatrix=[myMatrix ; importfile(filenames{i}, startRow, endRow)];
end
In this manner, at every loop iteration the i-th filename will be given as input to importfile() and hopefully it'll be loaded.
For this to work you should (let's make things simple)
place your Matlab script and obviously the function importfile() in the same folder containing your .tsv files
set said folder as the Current Folder
or if you have the .tsv files in a given folder and your scripts in another folder, then the Current Folder must certainly will be the folder containing your scripts and the filenames inside the cell array filenames must contain the entire path, not just the proper filenames.
I have an input file having the following basic structure:
master header line(s)
block 1 header line(s)
... [m' x n] numerical matrix ...
block 2 header line(s)
... [m'' x n] numerical matrix ...
...
block N header line(s)
... [m(N) x n] numerical matrix ...
where n is constant, but m may assume different values (as indicated by the prime marks).
I am wondering if there is a simple way to load data of this organization into a cell array (or another structure of some kind) having the following form: each block of data (as defined by the header) is represented by a cell in a cell array, the contents of which are the numerical data in the form of a double array. To concretize that description, the desired MATLAB representation would appear as follows: cell{1} contains a double array containing the numerical data listed under the block 1 header; cell{2} contains a double array containing the numerical data listed under the block 2 header; etc.
Of course, there are simple alternatives, such as splitting the input file into individual block-specific files and sequentially reading each file into an element of a cell array via a loop statement, but I am interested to know whether there is a solution that does not require such manipulation.
I've had to do something similar. One way, as you say, is to divide into files. But really, since your file has a set structure:
1 - open the file
2 - read the first line (e.g. using fget)
3 - Read the header (e.g. using fget)
4 - read the next M rows (e.g. using fget, fread, etc.) and store as a matrix
5 - loop back to 3 except when eof.
(apologies for the pseudocode, I don't have access to Matlab on this computer)
Yes, this is still manipulation of the file, but it becomes extendable to when the file isn't as ordered as the example you gave (which is the case I have), and is extremely easy to read and debug. However, it will be slow if your file is hundreds of MBs.
I am trying to use MATLAB in order to generate a variable whose elements are either 0 or 1. I want to define this variable using some kind of concatenation (equivalent of Java string append) so that I can add as many 0's and 1's according to some upper limit.
I can only think of using a for loop to append values to an existing variable. Something like
variable=1;
for i=1:N
if ( i%2==0)
variable = variable.append('0')
else
variable = variable.append('1')
i=i+1;
end
Is there a better way to do this?
In MATLAB, you can almost always avoid a loop by treating arrays in a vectorized way.
The result of pseudo-code you provided can be obtained in a single line as:
variable = mod((1:N),2);
The above line generates a row vector [1,2,...,N] (with the code (1:N), use (1:N)' if you need a column vector) and the mod function (as most MATLAB functions) is applied to each element when it receives an array.
That's not valid Matlab code:
The % indicates the start of a comment, hence introducing a syntax error.
There is no append method (at least not for arrays).
Theres no need to increment the index in a for loop.
Aside of that it's a bad idea to have Matlab "grow" variables, as memory needs to be reallocated at each time, slowing it down considerably. The correct approach is:
variable=zeros(N,1);
for i=1:N
variable(i)=mod(i,2);
end
If you really do want to grow variables (some times it is inevitable) you can use this:
variable=[variable;1];
Use ; for appending rows, use , for appending columns (does the same as vertcat and horzcat). Use cat if you have more than 2 dimensions in your array.