I'm using MATLAB to access a postgresql database. I'm running into problems trying to access a column of type boolean[]:
x;#% x is a <1x1 org.postgresql.jdbc4.Jdbc4Array>
When accessing real[] values, I can take the following approach:
double(x.getArray());
Unfortunately, with a boolean[] this leads to the following error message:
Undefined function 'toDouble' for input arguments of type 'logical'.
So I figured converting to logical first may work:
logical(x.getArray());
Except this doesn't work either.
Error using logical
Conversion to logical from java.lang.Boolean[][] is not possible.
The problem may arise because java.lang.Boolean doesn't derive from java.lang.Number, however the MATLAB docs on conversion of java return types make it seem like this shouldn't be a problem.
Am I doing something wrong here? How do I get from the fetch result to a logical array usable in MATLAB? If all else fails, I can rebuild the tables with arrays of numeric types instead of boolean[], but it seems like this should be possible without going that far.
I suspect that this is due to the difference in Java between Boolean (an object) and boolean, a primitive. Matlab conversions are really set up to handle primitives, not necessarily their associated object wrappers.
I think that this conversion requires a loop, as follows:
%Setup test
b = java.lang.Boolean.FALSE;
array = java.lang.reflect.Array.newInstance(b.getClass(), [5 6]);
for ix1=1:length(array);
for ix2 = 1:(length(array(1)));
array(ix1, ix2)=b;
end;
end;
%Now `array` is an initialize 2D Java array of type Boolean.
%To convert to a Matlab logical array
matArray = false(length(array), length(array(1))); %Initialize
for ix1=1:size(matArray, 1);
for ix2 = 1:size(matArray, 2);
matArray(ix1, ix2)=(array(ix1, ix2).booleanValue());
%The `booleanValue()` method converts from `Boolean` class to `boolean` primitive
end;
end;
Related
I know the line(X,Y) command returns a line object.
Thats why I dont understand the following code:
myline=line([1 2],[1 1]);
x=[];
x(2,2)=myline
This returns
x = [0 0; 0 7.0001]
Why? Why the 7.0001? why is x(2,2) not a line object?
isfloat(x(2,2)) %this returns true
isgraphics(x(2,2),'line') %this also returns true!
set(x(2,2),'LineStyle','--') %this works fine
x(2,2)+1 %this also works fine!
How can x(2,2) be a float and a line object at the same time?? And why is it a float at the beginning?
If the answer to this question is long and complicated, I am also happy with just a link to somewhere, where this behaviour is explained.
(I know these are technically more than one question. But it seems to me they all belong together and have the same answer)
What you're seeing here is a combination of MATLAB's assignment rules together with the compatibility layer between the old and new handle graphics systems.
Firstly, when you make a assignment into an array (including when you assign "off the end" of the array), the type of that array never changes - instead, the type of the right-hand-side is converted (if possible) to match the array you're assigning into. In your case, by executing x = [], you're making x be a 0x0 array of type double. When you assign to the (2,2) element, the line object is converted to double.
The fact that you can convert a line object to a double value is for compatibility with MATLAB's old implementation of handle graphics. The original handle graphics system was developed before MATLAB had a fully-featured object-oriented programming system, and so instead of things like line objects, all graphics objects were represented by unique double-precision numbers. In the new system, to maintain backwards compatibility with old code, it's still possible to treat line objects etc. as double-precision numbers.
You can see this behaviour explicitly by calling
double(myline)
You can use gobjects to assign an empty array of graphics placeholder elements instead if you wish:
myline = line([1 2],[1 1])
x = gobjects(0);
x(2,2) = myline;
class(x(2,2)) % gets 'matlab.graphics.primitive.Line'
I defined the following class
classdef TimerManager < handle
methods (Access = private)
function obj = TimerManager()
end
end
methods (Static)
function singleObj = getInstance(varargin)
varargin{1}
singleObj = TimerManager();
end
end
methods
function foo(obj)
end
end
end
I found the following code works differently w/ or w/o ;
Is this expected? or if I missed anything?
>> TimerManager.getInstance(0).foo()
ans =
0
>> TimerManager.getInstance(0).foo();
Index exceeds matrix dimensions.
Error in TimerManager.getInstance (line 13)
varargin{1}
If I use nargin in side getInstance, it is 0 if I put ; at the end.
Your error has nothing to do with the semi-colon. This has to do with the way that MATLAB handles subscripted referencing of objects (subsref).
The (Detailed) Issue
In MATLAB, you cannot "chain" subscripted referencing. For example if we create a cell array, we can't immediately index into this cell array without first assigning it to a temporary variable:
X1 = {'X1', 'X2', 'X3'}{1}
Error: Unbalanced or unexpected parenthesis or bracket.
The same applies for accessing the property or method of an object which is returned by a function. In your case, TimerManager.getInstance returns an instance which you must first assign to a temporary variable before being able to access it's foo method.
instance = TimerManager.getInstance(0);
fooResult = instance.foo();
MATLAB makes an attempt to throw an error or warning when it thinks that you're trying to "chain" these subscript references together, but if there is a scenario where an order of subscript operations is valid, then it is unable to throw the appropriate error. You are experiencing one of those cases.
The syntax that you are using is something like the following:
a.b(c).d()
This is valid if a.b is an array of structs with a field of d which is a function handle. In this case, c is an index.
When MATLAB parses this, it's going to retrieve the value of a.b, then ensure that c is a positive integer (a valid index) and is within the bounds of the array a.b. Then once that's been confirmed, MATLAB will access the d field and invoke it.
If we go back to your code for a second, we can comment out the varargin{1} line and get a more useful error message.
TimerManager.getInstance(0).foo();
Subscript indices must either be real positive integers or logicals.
Ok so that kind of makes sense, MATLAB is treating TimerManager.getInstance as a struct array and trying to index into it with the 0 which is obviously invalid and results in the error.
With respect to the actual error that you reported, note above that I said that before applying subscript referencing on the supposed struct array, MATLAB needs to first get the current value of TimerManager.getInstance. Because MATLAB thinks that this is just a struct array it's not going to pass any input arguments to it and this is resulting in varargin being empty and the error that you're seeing.
So your statement is functionally the same as:
instance = TimerManager.getInstance; % No input arguments
instance(0).foo() % Indexing error
Note that this does work if the "input" to getInstance is 1 since this is a valid index into the 1 x 1 array of TimerManager instances returned when you call Timermanager.getInstance with no inputs.
TimerManager.getInstance(1).foo();
Potential Solutions
Use a temporary variable
instance = TimerManager.getInstance(0);
fooResult = instance.foo();
Or use the method(obj) notation for invoking the method rather than the obj.method() notation.
foo(TimerManager.getInstance(0))
A Note on Octave
None of this is going to be an issue in Octave since it allows "chaining" these subscript references together without the need for a temporary variable.
I want to train data on various labels using svm and want svm model as array of struct. I am doing like this but getting the error:
Subscripted assignment between dissimilar structures.
Please help me out
model = repmat(struct(),size);
for i=1:size
model(i) = svmtrain(train_data,labels(:,i),'Options', options);
end
A structure array in MATLAB can only contain structures with identical fields. By first creating an array of empty structures1 and then trying to fill it with SVMStruct structures, you try to create a mixed array with some empty structures, and some SVMStruct structures. This is not possible, thus MATLAB complains about "dissimilar structures" (not-equal structures: empty vs. SVMStruct).
To allocate an array of structs, you will have to specify all fields during initialization and fill them all with initial values - which is rather inconvenient in this case. A very simple alternative is to drop this initialization, and run your loop the other way around2,3:
for ii=sizeOfLabels:-1:1
model(ii) = svmtrain(train_data,labels(:,ii),'Options', options);
end
That way, for ii=sizeOfLabels, e.g. ii=100, MATLAB will call model(100)=..., while model doesn't exist yet. It will then allocate all space needed for 100 SVMStructs and fill the first 99 instances with empty values. That way you pre-allocate the memory, without having to worry about initializing the values.
1Note: if e.g. size=5, calling repmat(struct(),size) will create a 5-by-5 matrix of empty structs. To create a 1-by-5 array of structs, call repmat(struct(),1,size).
2Don't use size as a variable name, as this is a function. If you do that, you can't use the size function anymore.
3i and j denote the imaginary unit in MATLAB. Using them as a variable slows the code down and is error-prone. Use e.g. k or ii for loops instead.
I'm using the unit testing framework in MATLAB and I noticed something weird. In this example:
classdef MyTest < matlab.unittest.TestCase
methods (Test)
function testEqual(testCase)
x = [1:3 7:8];
y = 1:5;
resultLogical = x == y;
resultDouble = [1 1 1 0 0];
assert(isequal(resultLogical, resultDouble), 'not equal')
verifyEqual(testCase, resultLogical, resultDouble)
end
end
end
When I run this with results = run(MyTest);, the unit test fails in the verifyEqual statement because resultLogical and resultDouble have different classes, even though the assert statement is successful because isequal understands that both objects are numeric equivalents.
Is there a way around this? I find myself constantly writing
verifyTrue(testCase, isequal(resultLogical, resultDouble))
when I need to compare two arrays of different types. Is this the only way? I don't see any of the qualifications that would work better than this, unfortunately.
verifyEqual is more strict than isequal because this is usually the desired behavior when automated testing. If you are testing an algorithm that accepts an int8 and should then return an int8, providing the expected value as an int8 will catch the bug that can occur if the algorithm incorrectly returns a double. This strictness also applies to other attributes of the value such as its sparsity, complexity, and size.
In your case, if you do not care about the class of the object then you can cast the actual value to the type of the expected value such as:
verifyEqual(testCase, double(resultLogical), resultDouble);
This will result in better diagnostics than using verifyTrue. Hope that helps!
Suppose I have a column matrix pols containing vectors of [theta, rho, z].
Which means, if I have 9 such vectors, it will be a 9x3 matrix.
It is quite handy to have them arranged as such, because I can just feed any one of them to functions like pol2cart:
cart3 = pol2cart(pols(3,:));
and for a certain vector, I can find its components via the indices 1, 2, 3:
rho5 = pols(5,2);
But sometimes the matrix is actually within another wider matrix, and could be in the middle instead of the beginning, such that the above might become:
rho5 = pols(5,6);
In order to make the code more readable in case someone else has to maintain it, is there anyway to refer to an index via a unique name? Like
rho5 = pols(5).rho;
where it could be defined earlier that .rho maps to the column which has the value of rho.
I've ventured into converting matrices to cells then to array using mat2cell and cell2struct but it doesn't seem practical. Or, I could make an array of structs, but then I lose the ability to do pol2cart(pols), and instead must do
pol2cart(pols.theta, pols.rho, pols.z);
So to repeat the question: can I map the indices to unique names?
For the default MATLAB data types, no, you can't really do that. You could, however, create your own new data type (i.e. class object) to store your data. Within the class definition you would overload the subsref method to define how subscripted referencing (i.e. using (), {}, or .) behaves for your new object. This could get rather tricky with regards to dealing with arrays of objects, but it is possible.
Note that you would also have to create overloaded methods for all the existing functions you want to use on your new data type. Specifically, you would have to create a pol2cart method for your object that could internally call the built-in pol2cart function with the appropriate pieces of data from your object passed as arguments.
...And this brings me to a simpler solution for your current situation. Instead of making a whole new type of class object, you could create a structure array (or scalar structure of arrays) to store your data and simply create a new overloaded pol2cart function specifically for struct data types that will simplify the calling syntax.
I discuss more details of overloading functions for built-in data types in two other answers here and here. In short, you would create a folder called #struct and place it in a folder on your MATLAB path. In this #struct folder you would then put this overloaded function:
function varargout = pol2cart(polarCoordinates)
[varargout{1:nargout}] = pol2cart(polarCoordinates.theta, ...
polarCoordinates.rho, ...
polarCoordinates.z);
end
Note that this is a stream-lined version of the function, without error checks on the input, etc. Now, let's make some sample data:
pols = rand(9, 3); %# A 2-D array of data
polStruct = struct('theta', pols(:, 1), ... %# Convert it to a scalar
'rho', pols(:, 2), ... %# structure of arrays
'z', pols(:, 3));
And you could access the rho value of the fifth row as follows:
rho5 = pols(5,2);
rho5 = polStruct.rho(5);
If you wanted to convert from polar to cartesian coordinates, here's how you would do it for each data type:
[X,Y,Z] = pol2cart(pols(:,1), pols(:,2), pols(:,3)); %# Calls the built-in one
[X2,Y2,Z2] = pol2cart(polStruct); %# Calls the overloaded one
And you can check that they each give identical results as follows:
>> isequal([X Y Z],[X2 Y2 Z2])
ans =
1 %# True!
OK, the formal answer is probably "no" as given by woodchips above. However, if you really want to do something like that, you might be able to use a semi-hack. Specifically, you can define a class and overload an operator to achieve (almost) what you want. Unfortunately, I see that Matlab doesn't allow overloading ., so you have to use some other operator. (see edit below)
Just to give you the idea, here is a class that returns the i-th row of a matrix M by M^i.
classdef Test
properties
M;
end
methods
function this = Test(M)
this.M = M;
end
function res = mpower(this, i)
res = this.M(i, :);
end
end
end
And it can be run like this:
>> tmp = Test([1 2; 3 4]);
>> tmp^1
ans =
1 2
>> tmp^2
ans =
3 4
Use at your own risk! :)
Edit:
I was wrong above. As mentioned in gnovice's answer you can actually define the . operator for a custom class using method subsref.
No. You cannot do so. As simple as that.