only one element tensors can be converted to python scalars - neural-network

def Log(A):
'''
theta = arccos((tr(A)-1)/2)
K=1/(2sin(theta))(A-A^T)
log(A)=theta K
'''
theta=torch.acos(torch.tensor((torch.trace(A)-1)/2))
K=(1/(2*torch.sin(theta)))*(torch.add(A,-torch.transpose(A,0,1)))
return theta*K
def tensor_Log(A):
blah=[[Log(A[i,j]) for j in range(A.shape[1])] for i in range(A.shape[0])]
new=torch.tensor(blah)
return new
ValueError: only one element tensors can be converted to Python scalars
during training to get the outputs of my network, the above function is producing the following error, it is called inside a custom layer and I do not know what it is referencing, any thoughts?

The issue in your list comprehension as blah is a list of list of tensors.
I would create a flat list of tensors by looping on A.shape[0] and A.shape[1] and then stack everything into a single tensor.
R = torch.stack([Log(A[i,j]) for i in range(A.shape[0]) for j in range(A.shape[1])])
You can then recover the desired format with reshape or view:
R.reshape(A.shape)

Related

Splice list of structs into arguments for function call - Matlab

I want to splice a list of arguments to pass to a function. For a vector I know that I can use num2cell and call the cell with curly braces (see this question), but in my case the list I want to splice originally has structs and I need to access one of their attributes. For example:
austen = struct('ids', ids, 'matrix', matrix);
% ... more structs defined here
authors = [austen, dickens, melville, twain];
% the function call I want to do is something like
tmp = num2cell(authors);
% myFunction defined using varargin
[a,b] = myFunction(tmp{:}.ids);
The example above does not work because Matlab expected ONE output from the curly braces and it's receiving 4, one for each author. I also tried defining my list of arguments as a cell array in the first place
indexes = {austen.ids, dickens.ids, melville.ids, twain.ids};
[a,b] = myFunction(indexes{:});
but the problem with this is that myFunction is taking the union and intersection of the vectors ids and I get the following error:
Error using vertcat
The following error occurred converting from double to struct:
Conversion to struct from double is not possible.
Error in union>unionR2012a (line 192)
c = unique([a;b],order);
Error in union (line 89)
[varargout{1:nlhs}] = unionR2012a(varargin{:});
What is the correct way for doing this? The problem is that I will have tens of authors and I don't want to pass al of them to myFunction by hand.
As #kedarps rightly pointed out I need to use struct2cell instead of num2cell. The following code does the trick
tmp = struct2cell(authors);
[a, b] = myFunction(tmp{1,:,:}); %ids is the first entry of the structs
I had never heard about struct2cell before! It doesn't even show up in the See also of help num2cell! It would be amazing to have an apropos function like Julia's....

How to extract columns of data from .txt files MATLAB

I have some data in a .txt file. that are separated by commas.
for example:
1.4,2,3,4,5
2,3,4.2,5,6
24,5,2,33.4,62
what if you want the average of columns, like first column (1.4,2 and 24)? or second column(2,3 and 5)?
I think putting the column in an array and using the built in mean function would work, but so far, I am only able to extract rows, not columns
instead of making another thread, I thought i'd edit this one. I am working on getting the average of each column of the well known iris data set.
I cut a small portion of the data:
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
delimiterln= ',';
data = importdata('iris.txt', delimiterln);
meanCol1 = mean(data(:,1))
meanCol2 = mean(data(:,2))
meanCol3 = mean(data(:,3))
meanCol4 = mean(data(:,4))
Undefined function 'sum' for input arguments of type 'cell'.
Error in mean (line 115)
y = sum(x, dim, flag)/size(x,dim);
Error in irisData(line 6)
meanCol1 = mean(data(:,1))
it looks like there is an error with handling data type...any thoughts on this? I tried getting rid of the last column, which are strings. and it seems to work without error. So i am thinking that it's because of the strings.
Use comma separated file reading function:
M = csvread(filename);
Now you have the matrix M:
col1Mean=mean(M(:,1));

Looping through documents in matlab

I am attempting to loop through the variable 'docs' which is a cell array that holds strings, i need to make a for loop that colllects the terms in a cell array and then uses command 'lower' and unique to create a dictionary.
Here is the code i've tried sp far and i just get errors
docsLength = length(docs);
for C = 1:docsLength
list = tokenize(docs, ' .,-');
Mylist = [list;C];
end
I get these errors
Error using textscan
First input must be of type double or string.
Error in tokenize (line 3)
C = textscan(str,'%s','MultipleDelimsAsOne',1,'delimiter',delimiters);
Error in tk (line 4)
list = tokenize(docs, ' .,-');
Generically, if you get an "must be of type" error, that means you are passing the wrong sort of input to a function. In this case you should look at the point in your code where this is taking place (here, in tokenize when textscan is called), and doublecheck that the input going in is what you expect it to be.
As tokenize is not a MATLAB builtin function, unless you show us that code we can't say what those inputs should be. However, as akfaz mentioned in comments, it is likely that you want to pass docs{C} (a string) to tokenize instead of docs (a cell array). Otherwise, there's no point in having a loop as it just repeatedly passes the same input, docs, into the function.
There are additional problems with the loop:
Mylist = [list; C]; will be overwritten each loop to consist of the latest version of list plus C, which is just a number (the index of the loop). Depending on what the output of tokenize looks like, Mylist = [Mylist; list] may work but you should initialise Mylist first.
Mylist = [];
for C = 1:length(docs)
list = tokenize(docs{C}, ' .,-');
Mylist = [Mylist; list];
end

How to select rows from character array that match char string and save them in a new array?

I have a char array A which basically contains a list of files names (each row one file)
(char, 526x26)
val =
0815_5275_UBA_A_1971.txt
0815_5275_UBA_A_1972.txt
0823_6275_UBA_A_1971.txt
0823_6275_UBA_A_1972.txt
0823_6275_UBA_A_1973.txt
...
I also have a variable
B = '0815_5275'
I'd like to select all rows (filenames) that start with B and save them in a new array C.
This should be simple, but somehow I can't make it work.
I've got this:
C = A(A(:,1:9) == B);
but I get the error message:
Error using ==
Matrix dimensions must agree.
I do not know in advance how many rows will match, so I can not pre-define an empty array.
thanks, any help is appreciated!
Try ismember(A(:, 1:numel(B)), B, 'rows') rather to get a logical vector that indexes only the rows you want
and now
A(C,:) to extract the rows
The reason you're getting a dimension mismatch error is because your A(:,1:9) has many rows but B only has one and Matlab does not automatically broadcast like Octave or Python. You could do it using either repmat or bsxfun but in this case ismember is the correct function to choose.

MATLAB "bug" (or really weird behavior) with structs and empty cell arrays

I have no idea what's going on here. I'm using R2006b. Any chance someone out there with a newer version could test to see if they get the same behavior, before I file a bug report?
code: (bug1.m)
function bug1
S = struct('nothing',{},'something',{});
add_something(S, 'boing'); % does what I expect
add_something(S.something,'test'); % weird behavior
end
function add_something(X,str)
disp('X=');
disp(X);
disp('str=');
disp(str);
end
output:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test');
It looks like the emptiness/nothingness of S.something allows it to shift the arguments for a function call. This seems like Very Bad Behavior. In the short term I want to find away around it (I'm trying to make a function that adds items to an initially empty cell array that's a member of a structure).
Edit:
Corollary question: so there's no way to construct a struct literal containing any empty cell arrays?
As you already discovered yourself, this isn't a bug but a "feature". In other words, it is the normal behavior of the STRUCT function. If you pass empty cell arrays as field values to STRUCT, it assumes you want an empty structure array with the given field names.
>> s=struct('a',{},'b',{})
s =
0x0 struct array with fields:
a
b
To pass an empty cell array as an actual field value, you would do the following:
>> s = struct('a',{{}},'b',{{}})
s =
a: {}
b: {}
Incidentally, any time you want to set a field value to a cell array using STRUCT requires that you encompass it in another cell array. For example, this creates a single structure element with fields that contain a cell array and a vector:
>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])
s =
strings: {'hello' 'yes'}
lengths: [5 3]
But this creates an array of two structure elements, distributing the cell array but replicating the vector:
>> s = struct('strings',{'hello','yes'},'lengths',[5 3])
s =
1x2 struct array with fields:
strings
lengths
>> s(1)
ans =
strings: 'hello'
lengths: [5 3]
>> s(2)
ans =
strings: 'yes'
lengths: [5 3]
ARGH... I think I found the answer. struct() has multiple behaviors, including:
Note If any of the values fields is
an empty cell array {}, the MATLAB
software creates an empty structure
array in which all fields are also
empty.
and apparently if you pass a member of a 0x0 structure as an argument, it's like some kind of empty phantom that doesn't really show up in the argument list. (that's still probably a bug)
bug2.m:
function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);
test case:
>> nothing = struct('something',{})
nothing =
0x0 struct array with fields:
something
>> bug2(nothing,'there')
number of arguments = 2
arg1 =
>> bug2(nothing.something,'there')
number of arguments = 1
arg1 =
there
This behaviour persists in 2008b, and is in fact not really a bug (although i wouldn't say the designers intended for it):
When you step into add_something(S,'boing') and watch the first argument (say by selecting it and pressing F9), you'd get some output relating to the empty structure S.
Step into add_something(S.something,'test') and watch the first argument, and you'd see it's in fact interpreted as 'test' !
The syntax struct.fieldname is designed to return an object of type 'comma separated list'. Functions in matlab are designed to receive an object of this exact type: the argument names are given to the values in the list, in the order they are passed. In your case, since the first argument is an empty list, the comma-separated-list the function receives starts really at the second value you pass - namely, 'test'.
Output is identical in R2008b:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test'); % weird behavior