The Following is the basic skeleton for my MATLAB program. Each box is a class definition.
Scroll down for the error.
Note: 1. Each Class has a custom constructor
The Error
Undefined function or variable 'Troom'.
Error in ==> wall>wall.wall at 31
function o = wall(Tr)
Error in ==> mainfile at 5
w1 = wall();
This comes when I create an object of Class wall from another file "mainfile"
Question
Why is this happening?
Am I getting wrong in the concepts of OOP for Matlab specific?
How do I resolve this?
Thanks in Advance!
PS: Code
function o = wall()
Tr = o.Troom*2;
o.N = round(1/o.dx) + 1;
o.T = Tr * ones(o.N,1);
o.Tinf = Tr;
o.update_properties();
end
Code 2
classdef wall
properties
dx = 0.01;
dt = 0.4;
L = 0.16;
N;
tlimit = 1505.2;
sbc = 5.670400e-8 % The Stefan-Boltzmann Constant
a;
hi; % Surface Conductivity of Inner Surface
bi;
ho; % Surface Conductivity of Outer Surface
bo;
lamb;
Troom = 298; % Room Temperature (K)
Tinf;
T;
room = compartment();
conc = concrete();
fire = fireProperties(Troom);
end
room = compartment();
conc = concrete();
fire = fireProperties(Troom);
Yeah, there's your problem right there. Troom can't be used in the context of the properties block. Either put the constant in for Troom or move these into the constructor where they belong.
Related
This seems like a really simple question but I've been at this for a couple of hours and need an outsiders perspective.
I'm migrating a start of a game to Godot from Unity.
I'm selecting an area of tiles (startDragPosition, endDragPosition, both Vector2 objects) from a TileMap and setting them to a certain tile. Currently the dragging only works if the direction is top->bottom and left->right, so if the ending x and y are larger than the starting x and y
In Unity(C#) I had a few simple lines to flip the rectangle values if it was dragged in reverse.
if (end_x < start_x) {
int tmp = end_x;
end_x = start_x;
start_x = tmp;
}
if (end_y < start_y) {
int tmp = end_y;
end_y = start_y;
start_y = tmp;
}
However in when I try a similar approach in Godot it is not working for some reason. I'm thinking that I'm messing up somewhere earlier and any help would be appreciated. If there is an easier way of doing this please tell me I'm fairly new to Godot itself.
Here is the function responsible for dragging in my Godot script(GD)
func Drag():
if(Input.is_action_just_pressed("click")):
startDragPosition=get_global_mouse_position()
if(Input.is_action_pressed("click")):
endDragPosition=get_global_mouse_position()
print("01 START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
print("01 END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
if(endDragPosition.x<startDragPosition.x):
var temp = endDragPosition.x
endDragPosition.x=startDragPosition.x
startDragPosition.x=temp
if(endDragPosition.y<startDragPosition.y):
var temp = endDragPosition.y
endDragPosition.y=startDragPosition.y
startDragPosition.y=temp
for x in range(startDragPosition.x,endDragPosition.x):
for y in range(startDragPosition.y,endDragPosition.y):
get_node("../DragPreview").set_cell((stepify(x-8,16))/16,(stepify(y-8,16))/16,0)
#get_node("../DragPreview").update_bitmask_area(Vector2((stepify(x-8,16))/16,(stepify(y-8,16))/16))
if(Input.is_action_just_released("click")):
print("START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
print("END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
startDragPosition=null
endDragPosition=null
When you drag, you always write to endDragPosition.
When you drag to the left or drag up, and you update endDragPosition, it will have smaller coordinates than it had before. Because of that you swap the coordinates with startDragPosition… And then you keep dragging left or up, and that updates endDragPosition again. The original startDragPosition is lost.
Either you work with a copy when you are deciding the start and end:
var start = startDragPosition
var end = endDragPosition
if(end.x<start.x):
var temp = end.x
end.x=start.x
start.x=temp
if(end.y<start.y):
var temp = end.y
end.y=start.y
start.y=temp
for x in range(start.x,end.x):
for y in range(start.y,end.y):
# whatever
pass
Or you forget this swapping shenanigans, and give the loops a step:
var start = startDragPosition
var end = endDragPosition
for x in range(start.x,end.x,sign(end.x-start.x)):
for y in range(start.y,end.y,sign(end.y-start.y)):
# whatever
pass
I have the following objective function:
I am not sure how to write it in cvx.
This is my try:
cvx_begin sdp
variable Q(T,n,N)
%variable X_0T*Q(:,:,N) symmetric
obj = trace(X_0T*Q(:,:,N));
for j = 1:N-1
obj= obj + trace(X_0T*Q(:,:,j)))
subject to
[X_0T*Q(:,:,j+1)-eye(n), X_1T*Q(:,:,j); Q(:,:,j)'*X_1T', X_0T*Q(:,:,j)] >= 0;
X_0T*Q(:,:,1) >= eye(n);
end
minimize(obj)
cvx_end
K_cvx_df = -U_01T*Q(:,:,N)*pinv(X_0T*Q(:,:,N))
However, when I try to solve it for N going to infinity, it gives me a different solution from the infinite time horizon case, which is
cvx_begin sdp
variable Q(T,n)
minimize( trace(X_0T*Q))
subject to
[X_0T*Q-eye(n), X_1T*Q; Q'*X_1T', X_0T*Q] >= 0
cvx_end
K_cvx_d = -U_01T*Q*inv(X_0T*Q)
Is it possible to define a MATLAB class such that the objects from this class can be called like any other function?
IOW, I'm asking whether one can write in MATLAB the equivalent of something like the following Python class:
# define the class FxnClass
class FxnClass(object):
def __init__(self, template):
self.template = template
def __call__(self, x, y, z):
print self.template % locals()
# create an instance of FxnClass
f = FxnClass('x is %(x)r; y is %(y)r; z is %(z)r')
# call the instance of FxnClass
f(3, 'two', False)
...
[OUTPUT]
x is 3; y is 'two'; z is False
Thanks!
I do not know, whether MATLAB directly supports what you want, but MATLAB does support first-class functions; closures might therefore provide a useable substitute, for instance:
function f = count_call(msg)
calls = 0;
function current_count()
disp(strcat(msg, num2str(calls)));
calls = calls + 1;
end
f = #current_count;
end
In this case, current_count closes over calls (and msg). That way you can express functions that depend on some internal state. You would use it this way:
g = count_call('number of calls: ') % returns a new function ("__init__")
g() % "__call__"
I will be interested to see if this is possible without simply creating a java method in Matlab. I know you can do the following
classdef ExampleObject
properties
test;
end
methods
function exampleObject = ExampleObject(inputTest)
exampleObject.test=inputTest;
end
function f(exampleObject,funcInput)
disp(funcInput+exampleObject.test);
end
end
end
>> e=ExampleObject(5);
>> f(e,10)
15
But as far as my knowledge goes, if you tried to override the call function you'd run into a conflict with Matlab's parenthetical subscript reference subsref. You can find a reference here showing how to overwrite that, and you might be able to get it to do what you want...but it doesn't seem like good form to do so. Not sure how Matlab would handle a call to an object (as opposed to a function) without it getting confused with this.
One way is to override the feval function for your class:
classdef FxnClass < handle
properties
template
end
methods
function obj = FxnClass(t)
obj.template = t;
end
function out = feval(obj, varargin)
out = sprintf(obj.template, varargin{:});
end
end
end
This would be used as:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> feval(f, 3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Now if you want to provide additional syntactic sugar, you could redefine the subsref function for your class as #Salain suggested. Add the following to the previous class definition:
classdef FxnClass < handle
...
methods
function out = subsref(obj, S)
switch S(1).type
case '.'
% call builtin subsref, so we dont break the dot notation
out = builtin('subsref', obj, S);
case '()'
out = feval(obj, S.subs{:});
case '{}'
error('Not a supported subscripted reference');
end
end
end
end
Now you could simply write:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Personally I don't particularly like overriding the subsref or subsasgn functions. They are used for too many cases, and its sometimes hard to get them write. For example all the following will eventually call the subsref method with different input:
f(..)
f.template
f.template(..)
f(..).template
f(..).template(..)
There is also the case of the end keyword which could appear in indexing, so you might have to also override it as well in some cases. Not to mention that objects can also be concatenated into arrays, which makes things even more complicated:
>> ff = [f,f];
>> ff(1) % not what you expect!
That said, I think #Frank's suggestion to use nested functions with closures is more elegant in this case:
function f = FxnClass(t)
f = #call;
function out = call(varargin)
out = sprintf(t, varargin{:});
end
end
which is called as before:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3, 'two', false)
If you mean that you want a class to hold a method which you use like a normal function (eg. defined in an m-file), then yes, Matlab does support static methods.
A static method runs independently of any instances of that class, in fact, you don't even need to instantiate a class to use its static methods.
Matlab does not support static fields, however, so you would have to instantiate such a class first, and then set its fields before using the functions (which presumably make use of these fields, since you are asking this question).
Given the limitation with static members, you might be better off with closures, as described by Frank.
I want to create a subclass, ess say, to the built-in ss class. I'd like to be able to convert an existing ss object to an ess object and at the same time add the missing properties, e.g. w, by something like this
sys=ss(a,b,c,d);
esys=ess(sys,w);
but I can't figure out how to setup the constructor correctly. What is the best way to achieve this? My code currently looks like this
classdef ess < ss
properties
w
end
methods
function obj = ess(varargin)
if nargin>0 && isa(varargin{1},'StateSpaceModel')
super_args{1} = sys;
else
super_args = varargin;
end
obj = obj#ss(super_args{:});
end
end
end
But this does not work as I get the following error:
>> ess(ss(a,b,c,d))
??? When constructing an instance of class 'ess', the constructor must preserve
the class of the returned object.
Of course I could copy all the object properties by hand but it seems to me that there should be some better way.
Here is an example of what I had in mind:
classdef ss < handle
properties
a
b
end
methods
function obj = ss(varargin)
args = {0 0}; %# default values
if nargin > 0, args = varargin; end
obj.a = args{1};
obj.b = args{2};
end
end
end
and:
classdef ess < ss
properties
c
end
methods
function obj = ess(c, varargin)
args = {};
if nargin>1 && isa(varargin{1}, 'ss')
args = getProps(varargin{1});
end
obj#ss(args{:}); %# call base-class constructor
obj.c = c;
end
end
end
%# private function that extracts object properties
function props = getProps(ssObj)
props{1} = ssObj.a;
props{2} = ssObj.b;
end
Lets test those classes:
x = ss(1,2);
xx = ess(3,x)
I get:
xx =
ess handle
Properties:
c: 3
a: 1
b: 2
Methods, Events, Superclasses
Suppose I have the following class which calculates the solution to the quadratic equation:
classdef MyClass < handle
properties
a
b
c
end
properties (Dependent = true)
x
end
methods
function x = get.x(obj)
discriminant = sqrt(obj.b^2 - 4*obj.a*obj.c);
x(1) = (-obj.b + discriminant)/(2*obj.a);
x(2) = (-obj.b - discriminant)/(2*obj.a);
end
end
end
Now suppose I run the following commands:
>>quadcalc = MyClass;
>>quadcalc.a = 1;
>>quadcalc.b = 4;
>>quadcalc.c = 4;
At this point, quadcalc.x = [-2 -2]. Suppose I call quadcalc.x multiple times without adjusting the other properties, i.e., quadcalc.x = [-2 -2] every single time I ask for this property. Is quadcalc.x recalculated every single time, or will it just "remember" [-2 -2]?
Yes, x is recalculated every single time. This is kind of the point of having a dependent property, since it guarantees that the result in x is always up to date.
If you want to make x a "lazy dependent property", you may want to look at the suggestions in my answer to this question.