How do I delete a line in an array of lines given a value - matlab

In matlab, I stored every line I plotted like so:
app.cplxPlot(app.cplxPlotNumber)= plot(app.UIAxes[app.var.cplx(1);app.var.cplx(1)],[50;250], 'g');
To make things generic, it is as if I did this:
cplxPlot(location)=plot(app.UIAxes,[cplxPlot(1);cplxPlot(1)],[50;250],'g');
This basically stores a bunch of vertical lines. I want to now delete the line with a certain x value. In the command line of matlab, I did this simple if loop to see if my first plot has the x value of 20, and it worked.
if length(find(cplx1Plot(1).XData==value,1,'first'))==1
disp('wow')
end
But, in app designer, the exact same code :
if length(find(app.cplx1Plot(1).XData==value,1,'first'))==1
app.Label.Text='wow'
end
would display the error: "Dot indexing is not supported for variables of this type." Can someone tell me what I am doing wrong? It worked perfectly in a matlab script, but not on app designer and I am not sure why.
Follow up: I just used the class function, and apparently my vector is storing doubles in app-designer, but it stores class in regular matlab... I have no idea why the elements in the vector would ever be a double.
Follow up 2.0: Apparently, if I access a property to store a line, it is stored as a double, but if I choose to make it a local variable instead, it would be a line. I need this to be a property/global variable and don't get why in the world it would ever be stored as a double...
For instances, bob stores doubles in this scenario :
bob(1)= plot([.005;.005],[100;200],'g')
app.Label.Text=string(class(bob(1)));
But, bob stores doubles in this:
app.bob(1)= plot([.005;.005],[100;200],'g')
app.Label.Text=string(class(app.bob(1)));
For context, I declared bob in my properties like this:
bob

Related

When subclassing "double" with new properties in MATLAB, is there an easy way to access the data value?

Say I have a class subclassing double, and I want to add a string (Similar to the 'extendDouble' in the documentation). Is there an easy way to access the actual numeric value without the extra properties, particular for reassigning? Or if I want to change the value, will I have to recreate the value as a new member of the class with the new value and the same string?
e.g.
classdef myDouble < double
properties
string
end
methods
function obj = myDouble(s)
% Construct object (simplified)
obj.string = s;
end
end
end
----------
x = myDouble(2,'string')
x =
2 string
x = 3
x =
3 string
Short answer: NO. There is no easy way to access a single member of a class when the class contains more than one member. You'll always have to let MATLAB know which part of the class you want to manipulate.
You have multiple questions in your post but let's tackle the most interesting one first:
% you'd like to instanciate a new class this way (fine)
x = myDouble(2,'string')
x =
2 string
% then you'd like to easily refer to the only numeric part of your class
% for assignment => This can NEVER work in MATLAB.
x = 3
x =
3 string
This can never work in MATLAB because of how the interpreter works. Consider the following statements:
% direct assignment
(1) dummy = 3
% indexed assignments
(2) dummy(1) = 3
(3) dummy{1} = 3
(4) dummy.somefieldname = 3
You would like the simplicity of the first statement for assignment, but this is the one we cannot achieve. The statement 2, 3 and 4 are all possible with some fiddling with subasgn and subsref.
The main difference between (1) and [2,3,4] is this:
Direct assignment:
In MATLAB, when you execute a direct assignment to a simple variable name (without indexing with () or {} or a field name) like dummy=3, MATLAB does not check the type of dummy beforehand, in fact it does not even check whether the variable dummy exists at all. No, with this kind of assignment, MATLAB goes the quickest way, it immediately create a new variable dummy and assign it the type and value accordingly. If a variable dummy existed before, too bad for it, that one is lost forever (and a lot of MATLAB users have had their fingers bitten once or twice by this behavior actually as it is an easy mistake to overwrite a variable and MATLAB will not raise any warning or complaint)
Indexed assignments:
In all the other cases, something different happens. When you execute dummy(1)=3, you are not telling MATLAB "create a new dummy variable with that value", you are telling MATLAB, "find the existing dummy variable, find the existing subindex I am telling you, then assign the value to that specific subindex". MATLAB will happlily go on, if it finds everything it does the sub-assignment, or it might complains/error about any kind of misassignment (wrong index, type mismatch, indices length mismatch...).
To find the subindex, MATLAB will call the subassgn method of dummy. If dummy is a built-in class, the subassgn method is also built in and usually under the hood, if dummy is a custom class, then you can write your own subassgn and have full control on how MATLAB will treat the assignment. You can check for the type of the input and decide to apply to this field or another if it's more suitable. You can even do some range check and reject the assignment altogether if it is not suitable, or just assign a default value. You have full control, MATLAB will not force you to anything in your own subassgn.
The problem is, to trigger MATLAB to relinquish control and give the hand to your own subassgn, you have to use an indexed assignment (like [2,3 or 4] above). You cannot do that with type (1) assignment.
Other considerations: You also ask if you can change the numeric part of the class without creating a new object. The answer to that is no as well. This is because of the way value classes work in matlab. There could be a long explanation of what happens under the hood, but the best example is from the MATLAB example you referenced yourself. If we look at the class definition of ExtendDouble, then observe the custom subassgn method which will perform the change of numeric value, what happens there is:
obj = ExtendDouble(b,obj.DataString);
So even Mathworks, to change the numeric value of their extended double class, have to recreate a brand new one (with a new numeric value b, and transfering the old string value obj.DataString).

Is it possible to use fsolve if an existing script return a class structure?

I have a script Function.m such that for example, when I write TEST=Function(1,2), I have TEST.x1=4 and TEST.x2=[5,6,7]. I want to use fsolve to help me find input. To be precise, I want to define a function, say a=#(y)Function(1,y)-4 so that when I use [z,vector]=fsolve(#(y)a(y),5), matlab can help me to obtain z=2 and vector=[5,6,7].
I would like to solve it by defining the same structure New_Function.m as Function.m such that it returns x1 values, i.e., TEST=New_Function(1,2) gives TEST=4 only. Then I write new_a=#(y)New_Function(1,y)-4 and solve z=fsolve(#(y)new_a(y),5) and define new_vector=Function(1,z) so that I can access new_vector.x2.
I want to know if it is possible to do my task without defining a new script or amending the content in the existing script. How to write code?
Since Matlab does not allow further referencing the result of a function call, you may need to help yourself with getfield. In your example (provided I got it right), it would be something like New_Func = #(y) getfield(Function(1,y),'x1'). This would take one scalar and return one scalar, i.e., New_Func(y) gives the field value of the struct returned by Function(1,y) associated to the field x1.

`[~,ui] = Unique(Day)` what is this doing?

When looking at Matlab code I have stumbled upon the following line of code:
[~,ui] = Unique(Day)
(Where Day is the vector containing a numeric value of day like so: 1,2,3, etc.)
What is it doing? I have noticed that it creates some kind of unique identifiers for the numeric value of the day (i.e. for 1 to 31) as well as a variable called Volume. What is Volume?
[~,ui] = Unique(Day) evaluates the function Unique with input argument Day.
This function has 2 outputs, and if you want to use both, you would write
[a,b]=Unique(Day). However, if you need only second output, you can put ~ instead of the first argument. So, your first output will not be saved.
It is impossible to answer, what Volume means, because you didn't provide the code of the function Unique.

How MATLAB's "if" function handles multiple inputs

I ran a quick test to see how if deals with multiple input values. It appears that the default behavior is to apply and to the collection of values, but I couldn't find any documentation. Can anyone confirm or provide a counterexample?
>> if([1,1,1]) disp(sprintf('hi'));end;
hi
>> if([1]) disp(sprintf('hi'));end;
hi
>> if([1,1,0]) disp(sprintf('hi'));end;
EDIT: to clarify, I don't intend to try to use this "feature," but wanted to be sure I knew how erroneous input would be handled. Suppose, for example, your code read
if(my_function) and the (badly written) my_function usually returns a single value but occasionally returns multiple values. Good practice, of course , would parse the returned values appropriately and feed a single value to if.
I don't find any practical reason to create an if statement which depends on anything but a scalar.
Regarding what's done in MATLAB practically?
You may assume MATLAB applies the function all on the input of the if statement.
This will hold as intuition given the array is non empty.
For example, if we have array - array4Example which is not empty, the statement if on the array - if(array4Example) is equivalent of the statement if on the scalar - if(all(array4Example(:))).
This matches the documentation if the if function.

What does the . operator do in matlab?

I came across some matlab code that did the following:
thing.x=linspace(...
I know that usually the . operator makes the next operation elementwise, but what does it do by itself? Is this just a sub-object operator, like in C++?
Yes its subobject.
You can have things like
Roger.lastname = "Poodle";
Roger.SSID = 111234997;
Roger.children.boys = {"Jim", "John"};
Roger.children.girls = {"Lucy"};
And the things to the right of the dots are called fields.
You can also define classes in Matlab, instatiate objects of those classes, and then if thing was one of those objects, thing.x would be an instance variable in that object.
The matlab documentation is excellent, look up "fields" and "classes" in it.
There are other uses for ., M*N means multiploy two things, if M, N are both matrices, this implements the rules for matrix multiplication to get a new matrix as its result. But M.*N means, if M, N are same shape, multiply each element. And so no like that with more subtleties, but out of scope of what you asked here.
As #marc points out, dot is also used to reference fields and subfields of something matlab calls a struct or structure. These are a lot like classes, subclasses and enums, seems to me. The idea is you can have a struct data say, and store all the info that goes with data like this:
olddata = data; % we assume we have an old struct like the one we are creating, we keep a reference to it
data.date_created=date();
data.x_axis = [1 5 2 9];
data.notes = "This is just a trivial example for stackoverflow. I didn't check to see if it runs in matlab or not, my bad."
data.versions.current = "this one";
data.versions.previous = olddata;
The point is ANY matlab object/datatype/whatever you want to call it, can be referenced by a field in the struct. The last entry shows that we can even reference another struct in the field of a struct. The implication of this last bit is we could look at the date of creation of the previous verions:
data.versions.previous.date_created
To me this looks just like objects in java EXCEPT I haven't put any methods in there. Matlab does support java objects which to me look a lot like these structs, except some of the fields can reference functions.
Technically, it's a form of indexing, as per mwengler's answer. However, it can also be used for method invocation on objects in recent versions of MATLAB, i.e.
obj.methodCall;
However note that there is some inefficiency in that style - basically, the system has to first work out if you meant indexing into a field, and if not, then call the method. It's more efficient to do
methodCall(obj);