I cannot save a matrix to a file with Octave. Here is what happens:
A = [1 2 3; 4 5 6; 7 8 9]
dlmwrite("test.data", A)
Output:
A =
1 2 3
4 5 6
7 8 9
No file created.
Trying to save a 3D matrix:
A = [1 2 3; 4 5 6; 7 8 9]
A(:,:,2) = [10 11 12; 13 14 15; 16 17 18]
dlmwrite("test.data", A)
Output:
A =
1 2 3
4 5 6
7 8 9
A =
ans(:,:,1) =
1 2 3
4 5 6
7 8 9
ans(:,:,2) =
10 11 12
13 14 15
16 17 18
error: transpose not defined for N-D objects
error: called from
dlmwrite at line 202 column 7
test_3d at line 31 column 1
No file created.
So, my questions are:
Why is no file produced in either case?
What is the meaning of the error message about transpose, when I perform no such operation?
Does this only happen with Octave, or also with MATLAB?
Octave version: 6.3.0
I ran the test on my machine and god a similar error with Octave 5.1.0:
In my case I got error:
error: transpose not defined for N-D objects
error: called from
dlmwrite at line 195 column 7
In dlmwrite.m (Octave\Octave-5.1.0.0\mingw64\share\octave\5.1.0\m\io\dlmwrite.m).script I found:
They are basically attempting to transpose the incoming array. The transpose operator is defined for two-dimensional arrays but not for three-dimensional arrays, which is why an error is returned.
I ran the same test in MATLAB R2020a, which produced no error and output a file (test.data) with the following contents:
1,2,3,10,11,12
4,5,6,13,14,15
7,8,9,16,17,18
In either case, the documentation does not explicitly mention that the array must not have more than two dimensions, but it looks like the Matlab function is written to support more than two dimensions and the Octave equivalent does not.
With regards to the questions:
Why no file is produced in either case?
Since Octave uses a script to implement dlmwrite, whenever an error is identified the remainder of the script is not parsed. Therefore, the file is not created
What is the meaning of the error message about transpose, where I perform no such operation?
The error message indicates that Octave attempted to transpose (flip) an array of more than two dimensions, which is not supported by the transpose operator(').
Does this only happens with Octave, or also with MATLAB?
This does not happen in MATLAB R2020a. It looks like they have built in support for multi-dimensional arrays in this function.
It may be a good idea to create an Octave bug(https://www.gnu.org/software/octave/bugs). The dlmwrite function should either be updated to support more than two dimensions, or the documentation for the function (help dlmwrite) should explicitly state that the input parameter M must have no greater than two dimensions.
Related
My understanding of programming languages is limited, I have started 'coding' with matlab and wanted to transfer a simulation of mine from matlab to julia because there is no licensing fee. What I would like to know is in MATLAB I can auto populate array without ever initializing an array, while I know it is an inefficient way to it, I would like to know if there is similar way to do it on Julia.
Ex in MATLAB
for a in 1:10
x(a)=a;
end
will give me an array x = [ 1 2 3 4 5 6 7 8 9 10], is there a similar way to do that in julia? The way I have been doing it is declaring an empty array using Float64[] and append to it but it doesn't work the same way if the array is multidimensional.
my implementation in Julia for a 1D array
x = Float64[]
for a in 1:10
append!(x,a)
end
Any help regarding this will be greatly appreciated. Thank you!!!
MATLAB explicitly warns against the way you write this code and advises to preallocate for speed.
Julia, OTOH, cares more about performance and prohibits such pattern from the beginning. At the same time, it allows for more convenient and fast alternatives to do the same task.
julia> x = [a for a = 1:10] # OR x = [1:10;]
10-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
and for 2D arrays,
julia> x = [i+j-1 for i = 1:5, j = 1:5] # OR x = (1:5) .+ (1:5)' .- 1
5×5 Matrix{Int64}:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
And you have other convenience functions, like zeros(m,n), fill(val, dims), rand(Type, dims), etc., that you can use to initialize the arrays however you want.
Although #AboAmmar is correct that this generally isn't a good pattern, your code works if you use push! instead of append!. push! adds an element to a vector. append appends 2 vectors.
I have a matrix A
A =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
i have another matrix to specify the indices
index =
1 2
3 4
Now, i have got third matrix C from A
C = A(index)
C =
1 6
11 16
Problem: I am unable to understand how come i have received such a matrixC. I mean, what is logi behind it?
The logic behind it is linear indexing: When you provide a single index, Matlab moves along columns first, then along rows, then along further dimensions (according to their order).
So in your case (4 x 5 matrix) the entries of A are being accessed in the following order (each number here represents order, not the value of the entry):
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
Once you get used to it, you'll see linear indexing is a very powerful tool.
As an example: to obtain the maximum value in A you could just use max(A(1:20)). This could be further simplified to max(A(1:end)) or max(A(:)). Note that "A(:)" is a common Matlab idiom, used to turn any array into a column vector; which is sometimes called linearizing the array.
See also ind2sub and sub2ind, which are used to convert from linear index to standard indices and vice versa.
I have data that is output from a computational chemistry program (Gaussian09) which contains sets of Force Constant data. The data is arranged with indexes as the first 2-4 columns (quadratic, cubic and quartic FC's are calculated). As an example the cubic FC's look something like this, and MatLab has read them in successfully so I have the correct matrix:
cube=[
1 1 1 5 5 5
1 1 2 6 6 6
.
.
4 1 1 8 8 8
4 2 1 9 9 9
4 3 1 7 7 7 ]
I need a way to access the last 3 columns when feeding in the indices of the first 3 columns. Something along the lines of
>>index=find([cube(:,1)==4 && cube(:,2)==3 && cube(:,3)==1]);
Which would give me the row number of the data that is index [ 4 3 1 ] and allow me to read out the values [7 7 7] which I need within loops to calculate anharmonic frequencies.
Is there a way to do this without a bunch of loops?
Thanks in advance,
Ben
You have already found one way to solve this, by using & in your expression (allowing you to make non-scalar comparisons).
Another way is to use ismember:
index = find(ismember(cube(:,1:3),[4 3 1]));
Note that in many cases, you may not even need the call to find: the binary vector returned by the comparisons or ismember can directly be used to index into another array.
all.
I have a 15 element array = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15];.
I was wondering if there was a command such that it would step through iterations of the array without repeating itself. In other words, since there is a chance that randperm() will create the same matrix twice, I want to step through each permutation only once and perform a calculation.
I concede that there are factorial(15) permutations, but for my purposes, these two vectors (and similar) are identical and don't need to be counted twice:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
Thus, is there any way to step through this?
Thanks.
I think what you are looking for is perms. randperm returns a single random permutation, you want all the permutations.
So use
my_permuations = perms([1:15]);
If forward-backward is the same as backward-foward then you can use the top half of the list only...
my_permutation_to_use = my_permutations(1:length(my_permutations)/2, :);
You may compare all permutations, but this would require to store all past permutations. Instead a local decision is better. I recommend this simple rule:
A permutation is valid, if the first element is smaller than the last element.
A permutation is redundant, if the first element is larger than the last element.
For small sizes, this could simply be done with this code:
%generate all permutations
x=perms(1:10)
%select only the valid lines, remove all redundant lines
x(x(:,1)<x(:,end),:)
Remains the problem, that generating x for 1:15 breaks all memory limits and would require about 100h.
I'm using the CLUSTERGRAM object from the Bioinformatics Toolbox (ver 3.7).
MATLAB version R2011a.
I'd like to get permutation vectors for row and columns for clustergram, as I can do with dendrogram function:
x = magic(10);
>> [~,~,permrows] = dendrogram(linkage(x,'average','euc'))
permrows =
9 10 6 7 8 1 2 4 5 3
>> [~,~,permcols] = dendrogram(linkage(x','average','euc'))
permcols =
6 7 8 9 2 1 3 4 5 10
I found that the clustering is not the same from clustergram and dendrogram, most probably due to optimal leaf ordering calculation (I don't want to disable it).
For example, for clustergram from:
clustergram(x)
('average' and 'eucledian' are default methods for clustergram)
the vectors (as on the figure attached) should be:
permrows = [1 2 4 5 3 10 9 6 7 8];
permcols = [1 2 8 9 6 7 10 5 4 3];
So, how to get those vectors programmatically? Anybody well familiar with this object?
Do anyone can suggest a good alternative? I know I can create a similar figure combining imagesc and dendrogram functions, but leaf ordering is much better (optimal) in clustergram, than in dendrogram.
From looking at the documentation, I guess that get(gco,'ColumnLabels') and get(gco,'RowLabels'), where gco is the clustergram object, should give you the reordered labels. Note that the corresponding set-methods take in the labels in original order and internally reorders them.
Consequently, if you have used custom labels (set(gco,'RowLabels',originalLabels))
[~,permrows] = ismember(get(gco,'RowLabels'),originalLabels)
should return the row permutation.