Just adding getter/setter methods on my program makes my program super slow. Is there any explanation for this?
function set.x(obj,newx)
obj.x = newx;
end
function x = get.x(obj)
x = obj.x;
end
That's how I define them under my handle class.
Or have I just not implemented them correctly?
Edit
class definition goes...
classdef sensorlocest < handle
properties(GetAcess = 'public', SetAccess = 'private')
sensorId; % sensor id
X; % true x-coordainate
Y; % true y-coordinate
x; % estimate of X
y; % estimate of Y
end
methods
function sesnors = sensorlocest(x,y)
if nargin ~= 0
sesnors(49,1) = sensorlocest;
for k = 1:length(sensors)
sensors(k).sesnorId = k;
sensors(k).X = x.*rand;
sensors(k).Y = y.*rand;
end
end
function init(sensors,x,y)
N = length(sensors);
for i = 1:N
sensors(i).x = x.*rand;
sensors(i).y = y.*rand;
end
end
function set.x(sensors,newx)
sensors.x = newx;
end
function set.y(sensors,newy)
sensors.y = newy;
end
end
end
Nope, you are correct. They indeed have an overhead, check out this thread:
Is MATLAB OOP slow or am I doing something wrong?
Related
I have a class called "Edit"
function Edit:new(x,y,w,h,text,fnt)
o = {}
setmetatable(o,EditMt)
self.__index = self
self.x = x or 0
self.y = y or 0
self.width = w or 10
self.height = h or 10
self.text = text or ""
self.active = false
self.font = fnt or font
self.yo = -(self.height - self.font:getHeight()) / 2
return o
end
and that class has a function called draw(made with Löve2d)
function Edit:draw( )
if self.active then
love.graphics.setColor(255,255,255,255)
love.graphics.rectangle("fill",self.x,self.y,self.width,self.height)
love.graphics.setColor(0,0,0,255)
love.graphics.printf(self.text,self.font,self.x,self.y,self.width, "center",0,1,1,0,self.yo)
else
love.graphics.setColor(255,255,255,255)
love.graphics.rectangle("line",self.x,self.y,self.width,self.height)
love.graphics.printf(self.text,self.font,self.x,self.y,self.width, "center",0,1,1,0,self.yo)
end
end
and in my main i create 2 of them
edit1 = Edit:new(10,10,60,50,"1")
edit2 = Edit:new(80,10,60,50,"2")
and draw them in the callback
function love.draw( )
edit1:draw()
edit2:draw()
end
but it only draws edit2? if i switch the places in draw it still only draws edit2 but if i switch their places while creating them in the main it now only draws edit1?
This is the most common beginners mistake when they get into OOP in Lua.
You're assigning all those values to self which is Edit. But if you want to change your instance you need to assign them to o.
Otherwise each call to Edit.new will overwrite the values.
The second problem is that your instance o is a global. You need it to be local! Or you will overwrite your instances each time.
function Edit:new (x,y,w,h,text,fnt)
local o = {}
setmetatable(o, self)
self.__index = self
o.x = x or 0
o.y = y or 0
-- and so forth
return o
end
Read this:
https://www.lua.org/pil/16.html
http://lua-users.org/wiki/ObjectOrientedProgramming
You initiates your object not quite correct.
In new function you initiates your object and self in this function is your metatatable.
The other problem that you creates global object o.
So your new function must be:
function Edit:new(x,y,w,h,text,fnt)
local o = {}
setmetatable(o, self)
self.__index = self
o.x = x or 0
o.y = y or 0
o.width = w or 10
o.height = h or 10
o.text = text or ""
o.active = false
o.font = fnt or font
o.yo = -(o.height - o.font:getHeight()) / 2
return o
end
I'm talking about MovingGround:update(). It doesn't crash; It just doesn't do anything that's in the method.
I did other things in the method. I set the player pos to 100 100 but that didn't happen so there's (probably) no error in the method itself—at least not that makes it do nothing. The method just doesnt get called!! I think the question is pretty much says the rest! Sooooo.... Here's the code!
-- Grounds
Ground = {}
Ground.__index = Ground
function Ground:new(x,y,width,height)
grd = {}
setmetatable(grd, Ground)
grd.x = x
grd.y = y
grd.w = width
grd.h = height
grd.moving = false
return grd
end
function Ground:draw(r,g,b)
love.graphics.setColor(r,g,b)
love.graphics.rectangle("line",self.x,self.y,self.w,self.h)
end
function Ground:update()
end
MovingGround = {}
MovingGround.__index = MovingGround
function MovingGround:new(x,y,w,h,spdx,spdy,stepsx,stepsy)
grd = {}
setmetatable(grd, Ground)
grd.x = x
grd.y = y
grd.w = w
grd.h = h
grd.moving = true
grd.spdx = spdx
grd.spdy = spdy
grd.stepsxmax = stepsx
grd.stepsymax = stepsy
grd.stepsx = 0
grd.stepsy = 0
grd.xdir = 1
grd.ydir = 1
return grd
end
function MovingGround:draw(r,g,b)
love.graphics.setColor(r,g,b)
love.graphics.rectangle("line",self.x,self.y,self.w,self.h)
love.graphics.rectangle("fill",300,self.y,self.w,self.h)
end
function MovingGround:update()
if self.stepsx > self.stepsxmax or self.stepsx < 0 then self.spdx = -self.spdx self.dirx = -self.dirx end
if self.stepsy > self.stepsymax or self.stepsy < 0 then self.spdy = -self.spdy self.diry = -self.diry end
self.x = self.x + self.spdx
self.y = self.y + self.spdy
self.stepsx = self.stepsx + self.dirx
self.stepsy = self.stepsy + self.diry
end
-- Main
require"functions"
require"player"
require"grounds"
grounds= {}
width = love.graphics.getWidth()
height = love.graphics.getHeight()
function love.load()
test = Player:new(100,100,"w","a","s","d")
grounds[5] = Ground:new(2,2,25,595) --links
grounds[2] = Ground:new(2,2,795,25) --oben
grounds[3] = Ground:new(772,2,25,595) --rechts
grounds[4] = Ground:new(2,572,795,25) --unten
grounds[1] = MovingGround:new(50,400,100,20,0,3,0,15)
end
function love.draw()
test:draw(255,0,255)
love.graphics.print("y : " .. tostring(test.y),10,10)
love.graphics.print("x : " .. tostring(test.x),10,30)
love.graphics.print(test.spdy,10,60)
love.graphics.print(gd,10,90)
love.graphics.print(1000 / gd,10,150)
love.graphics.print(booltoString(test.onGround),10,120)
love.graphics.print(grounds[1].stepsy,10,210)
for i,v in ipairs(grounds) do
grounds[i]:draw(255,255,255)
end
end
function love.update(d)
gd = d
test:update(d)
for i,v in ipairs(grounds) do
grounds[i]:update()
end
end
function love.keypressed(key,code)
if key == "space" then test:jump(-700) end
end
I really recommend using a debugger to determine the cause of this issue. Here's a walkthrough:
Find a place where the update method is being called on a MovingGround object and set a breakpoint there.
Run your program with debugging enabled, until it reaches the breakpoint.
Step into the call to the update method. What method do you end up getting taken to? Is it the method you were expecting?
Now that you're inside of the update method, look at the metatable of self. Is the metatable MovingGround?
The metatable was set inside of MovingGround:new, so set a breakpoint at the beginning of MovingGround:new and restart the program. Run until it reaches the breakpoint.
Step forward (using "step over", not "step into") until you see that the metatable of grd has been set as you saw in step 4.
Look at the line that you just stepped over. What needs to be changed?
Spoiler: in MovingGround:new, the metatable is getting set to Ground instead of MovingGround.
You are supposed to pass in dt into any update function.
In this case, the function should be MovingGround:update(dt) (ground.lua) so that it updates every frame.
Similarly, in main.lua update function, the call should be grounds[i]:update(dt).
I'm trying to plot a function of two variables with pyplot in Julia. The working starting-point is the following (found here at StackOverflow):
function f(z,t)
return z*t
end
z = linspace(0,5,11)
t = linspace(0,40,4)
for tval in t
plot(z, f(z, tval))
end
show()
This works right for me and is giving me exactly what I wanted:
a field of lines.
My own functions are as follows:
## needed functions ##
const gamma_0 = 6
const Ksch = 1.2
const Kver = 1.5
function Kvc(vc)
if vc <= 0
return 0
elseif vc < 20
return (100/vc)^0.1
elseif vc < 100
return 2.023/(vc^0.153)
elseif vc == 100
return 1
elseif vc > 100
return 1.380/(vc^0.07)
else
return 0
end
end
function Kgamma(gamma_t)
return 1-((gamma_t-gamma_0)/100)
end
function K(gamma_t, vc)
return Kvc(vc)*Kgamma(gamma_t)*Ksch*Kver
end
I've tried to plot them as follows:
i = linspace(0,45,10)
j = linspace(0,200,10)
for i_val in i
plot(i,K(i,j))
end
This gives me the following Error:
isless has no method matching isless(::Int64, ::Array{Float64,1})
while loading In[51], in expression starting on line 3
in Kvc at In[17]:2 in anonymous at no file:4
Obviously, my function cant deal with an array.
Next try:
i = linspace(0,200,11)
j = linspace(0,45,11)
for i_val in i
plot(i_val,map(K,i_val,j))
end
gives me a empty plot only with axes
Can anybody please give me a hint...
EDIT
A simpler example:
using PyPlot
function P(n,M)
return (M*n^3)/9550
end
M = linspace(1,5,5)
n = linspace(0,3000,3001)
for M_val in M
plot(n,P(n,M_val))
end
show()
Solution
OK, with your help I found this solution for the shortened example which works for me as intended:
function P(n,M)
result = Array(Float64, length(n))
for (idx, val) in enumerate(n)
result[idx] = (M*val^3)/9550
end
return result
end
n = linspace(0,3000,3001)
for M_val = 1:5
plot(n,P(n,M_val))
end
show()
This gives me what I wanted for this shortened example. The remainig question is: could it be done in a simpler more elegant way?
I'll try to apply it to the original example and post it when I'll succed.
I don't completely follow all the details of what you're trying to accomplish, but here are examples on how you can modify a couple of your functions so that they accept and return arrays:
function Kvc(vc)
result = Array(Float64, length(vc))
for (idx, val) in enumerate(vc)
if val <= 0
result[idx] = 0
elseif val < 20
result[idx] = (100/val)^0.1
elseif val < 100
result[idx] = 2.023/(val^0.153)
elseif val == 100
result[idx] = 1
elseif val > 100
result[idx] = 1.380/(val^0.07)
else
result[idx] = 0
end
end
return result
end
function Kgamma(gamma_t)
return ones(length(gamma_t))-((gamma_t - gamma_0)/100)
end
Also, for your loop, I think you probably want something like:
for i_val in i
plot(i_val,K(i_val,j))
end
rather than plot(i, K(i,j), as that would just print the same thing over and over.
< is defined for scalars. I think you need to broadcast it for arrays, i.e. use .<. Example:
julia> x = 2
2
julia> x < 3
true
julia> x < [3 4]
ERROR: MethodError: no method matching isless(::Int64, ::Array{Int64,2})
Closest candidates are:
isless(::Real, ::AbstractFloat)
isless(::Real, ::Real)
isless(::Integer, ::Char)
in <(::Int64, ::Array{Int64,2}) at .\operators.jl:54
in eval(::Module, ::Any) at .\boot.jl:234
in macro expansion at .\REPL.jl:92 [inlined]
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at .\event.jl:46
julia> x .< [3 4]
1x2 BitArray{2}:
true true
I'm trying to do OOP in Lua, but it's not letting me change the vel_y value in the checkInput{} method. Any ideas how i can get this to work? By the way I'm using Love2D for this input stuff.
Player = {x = 100, y = 20, vel_x = 0, vel_y = 0}
function Player:new(o, x, y, vel_x, vel_y)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
length = 0
return o
end
function Player:getX()
return self.x
end
function Player:getY()
return self.y
end
function Player:update( dt )
--update velocity
self.x = self.x + self.vel_x
self.y = self.y + self.vel_y
checkInput()
end
function checkInput( dt )
if love.keyboard.isDown("w") and length < 5 then --press the right arrow key to push the ball to the right
length = length + 1
self.vel_y = 5
print("bruhddddddddddddddddddddddd")
elseif love.keyboard.isDown("a") then
elseif love.keyboard.isDown("s") then
elseif love.keyboard.isDown("d") then
end
end
I assume your system call player:update() firs? If so you should pass self and dt to checkInput
function Player:update( dt )
--update velocity
self.x = self.x + self.vel_x
self.y = self.y + self.vel_y
checkInput(self, dt) --<--
end
...
function checkInput( self, dt )
...
if you define checkInput as local (of course before Player:update) this may be similar to private method.
Player = {x = 100, y = 20, vel_x = 0, vel_y = 0} do
Player.__index = self -- we can do this only once
function Player:new(o, x, y, vel_x, vel_y)
o = setmetatable(o or {}, self) -- create object if user does not provide one
-- init o here
return o
end
function Player:getX() end
function Player:getY() end
-- Private method
local function checkInput(self, dt) end
function Player:update( dt )
...
checkInput(self, dt) -- call private method
end
end -- end clsss defenitioin
I am writing a Multiplier class that multiplies its two parameters. If parameters are not given, default value of 1 is given.
Now when I update one variable, I do not get the exact product. My code is as below:
classdef Multiplier
properties (SetAccess = public, GetAccess = public)
first;
second;
end
properties(SetAccess = immutable, GetAccess = public)
product;
end
methods
function obj = Multiplier(varargin)
if nargin == 0
obj.first = 1;
obj.second = 1;
end
if nargin == 1
obj.first = varargin{1};
obj.second = 1;
end
if nargin > 1
obj.first = varargin{1};
obj.second = varargin{2};
end
obj.product = obj.first * obj.second;
end
end
end
k = Multiplier
k.first = 5
k.product -> This should return 5
You should make your product property Dependent. See this post for an example.