What is wrong with my function in Octave? - gnuplot

I just tried to create my first function in octave, it looks as follows:
function hui(x)
if(0 <= x && x <2)
retval = (1.5 * x + 2)
elseif(2<= x && x <4)
retval = (-x + 5)
elseif(4<= x && x < 6)
retval = (0.5 * x)
elseif(6<= x && x < 8)
retval = (x - 3)
elseif(8<= x && x <=10)
retval = (2 * x - 11)
endif
endfunction
but if I try to plot it using: x=0:0.1:10; plot(x, hui(x));
It shows a plot witch seems a little bit strange.
What did I wrong?
Thanks in advance
John

You'll have to pardon my rustiness with the package, but you need to change the code around a bit. Notably, the notation 0<=x is incorrect, and must be x>=0. Since hui is operating on a vector, I believe you need to take that into account when constructing your return value.
I'm sure there are more effective ways of vectorizing this, but basically, While stepping over the input vector, I added the latest value onto the return vector, and at the end lopping off the initial 0 that I had put in. I put in a sentinel value in case the input didn't fulfill one of the criteria (it was always taking the "else" path in your code, so putting something there could have alerted you to something being wrong).
function [retval] = hui(x)
retval = 0
for i=1:size(x,2)
if(x(i)>=0 && x(i) <2)
retval = [retval (1.5 * x(i) + 2)];
elseif( x(i)>=2 && x(i) <4)
retval = [retval (-1*x(i) + 5)];
elseif(x(i)>=4 && x(i) < 6)
retval = [retval (0.5 * x(i))];
elseif(x(i)>=6 && x(i) < 8)
retval = [retval (x(i) - 3)];
elseif(x(i)>=8 && x(i) <=10)
retval = [retval (2 * x(i) - 11)];
else
retval = -999;
endif
endfor
retval = retval(2:size(retval,2));
endfunction

x is a vector, so you either need to loop through it or vectorise your code to removing the need.
As you're using Octave, it's worth vectorising everything you possibly can. The easiest way I can think of doing this is:
x = 0:0.1:10;
y = x;
y(x >= 0 & x < 2) = x(x >= 0 & x < 2) * 1.5 + 2;
y(x >= 2 & x < 4) = x(x >= 2 & x < 4) * -1 + 5;
y(x >= 4 & x < 6) = x(x >= 4 & x < 6) * 0.5;
y(x >= 6 & x < 8) = x(x >= 6 & x < 8) - 3;
y(x >= 8 & x < 10) = x(x >= 8 & x < 10) * 2 - 11;
The y(x >= a & x < b) syntax is logical indexing. Alone, x >= a & x < b gives you a vector of logical values, but combined with another vector you get the values which meet the condition. Octave will also let you do assignments like this.

Related

Get a certain combination of numbers in Python

Is there a efficient and convenient solution in Python to do something like -
Find largest combination of two numbers x and y, with the following conditions -
0 < x < 1000
0 < y < 2000
x/y = 0.75
x & y are integers
It's easy to do it using a simple graphing calculator but trying to find the best way to do it in Python
import pulp
My_optimization_prob = pulp.LpProblem('My_Optimization_Problem', pulp.LpMaximize)
# Creating the variables
x = pulp.LpVariable("x", lowBound = 1, cat='Integer')
y = pulp.LpVariable("y", lowBound = 1, cat='Integer')
# Adding the Constraints
My_optimization_prob += x + y #Maximize X and Y
My_optimization_prob += x <= 999 # x < 1000
My_optimization_prob += y <= 1999 # y < 2000
My_optimization_prob += x - 0.75*y == 0 # x/y = 0.75
#Printing the Problem and Constraints
print(My_optimization_prob)
My_optimization_prob.solve()
#printing X Y
print('x = ',pulp.value(x))
print('y = ',pulp.value(y))
Probably just -
z = [(x, y) for x in range(1, 1000) for y in range(1, 2000) if x/y==0.75]
z.sort(key=lambda x: sum(x), reverse=True)
z[0]
#Returns (999, 1332)
This is convenient, not sure if this is the most efficient way.
Another possible relatively efficient solution is -
x_upper_limit = 1000
y_upper_limit = 2000
x = 0
y = 0
temp_variable = 0
ratio = 0.75
for i in range(x_upper_limit, 0, -1):
temp_variable = i/ratio
if temp_variable.is_integer() and temp_variable < y_upper_limit:
x = i
y = int(temp_variable)
break
print(x,y)

VBA results in #VALUE! only when For loop is used

I am writing a function with a For loop, and ultimately the value of the function will depend on the output of the For loop. For now as a test, the value of the function is a constant. If the For loop is in the code, the function results in #Value!. If I remove the For loop, the output is the specified constant value. How does the For loop need to be specified to avoid this? Good values for Tc and Th as a test would be 100 and 300, respectively.
Function kndT(material As Integer, Tc As Double, Th As Double) As Variant
Dim x As Double
Select Case material
Case 4
If Th > 300 Then
Tmax = 300
Else
Tmax = Th
End If
A = 0.07918
b = 1.0957
c = -0.07277
D = 0.08084
e = 0.02803
f = -0.09464
g = 0.04179
h = -0.00571
i = 0
End Select
hh = (Tmax - Tc) / 999
fi = 0
nc = 1
For i = 1 To 999
Temp = (Tc + i * hh)
x = Log(Temp) / Log(10#)
y = A + b * x + c * x ^ 2 + D * x ^ 3 + e * x ^ 4 + f * x ^ 5 + g * x ^ 6 + h * x ^ 7 + i * x ^ 8
fn = 10 ^ y
If nc = 3 Then
fi = fi + 2 * fn
nc = 1
Else
fi = fi + 3 * fn
nc = nc + 1
End If
Next i
kndT = 2
End Function

Why this Fuction cannot be called

I have this list that I want to sort based on bubble sort, and there is a function in code (Swap()) is refusing to work. I don't know why. there is the code
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
size = len(score)
x = 0
COMPS = size - 1
def swap():
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
# The Sort Array Function
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This function not working.
swap()
x += 1
y += 1
#Display Array Function
def displayArray():
x = 0
while x < size:
print(score[x])
x += 1
SortArray()
displayArray()
but inserting the swap() code, thus the code under the swap() and replacing it underneath the SortArray(), below the if condition; just like this:
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This Works
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
x += 1
y += 1
then it works, so I want to know why the swap() function doesn't get called under the SortArray()
I want to know why the swap() function doesn't get called under the SortArray()
Actually, it IS called - which you can check by yourself adding a couple print() calls within or using the step debugger - but it doesn't do what you think it should do, because you're confusing local and global variables.
In SortArray() you define a local variable named x (it's defined as local because you assign it in the function), and this is obviously the one you expect swap() to use. But in your swap function, you use a variable x which is neither an argument of the function nor assigned within the function (both of which would make it a local variable), so it's resolved as the global x declared above.
IOW, swap uses the global x why you'd expect it to use the one which is local to SortArray(). This is also why the second version works, since this time it uses the proper variable.
The solution is to remove the global x and explicitely pass the correct value to swap(), ie:
def swap(x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
swap(x)
x += 1
y += 1
And while you're at it, you should also to the same with score - actually, you should avoid globals as much as possible (and believe me, you can write a lot of code without using globals):
def swap(score, x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray(score):
comps = len(score) - 1
y = 0
while y < comps:
x = 0
while x < comps:
if score[x] > score[x + 1]:
swap(score, x)
x += 1
y += 1
def displayArray(score):
x = 0
while x < len(score):
print(score[x])
x += 1
if __name__ == "__main__":
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
SortArray(score)
displayArray(score)
And now your functions can be used with any list or sequence. They are still totally unpythonic but that's obviously not the point here (python has one of the most optimized sort algorithm builtin anyway).

An error with some simple lists and if statements in python

I wrote a code in python 3 but I get an error on the following line of code:
if x > blacks[i*2] and y < blacks[(i*2)+1] and ((x - blacks[i*2]) / (blacks[(i*2)+1]-y) <= 1 :
I don't think the problem is related with the rest of the code because I get the error even when I try using this 'if statement' in a very simple code:
blacks = [0,0,0,0,0]
i = 1
x = 0
y = 0
if x > blacks[i*2] and y < blacks[(i*2)+1] and ((x - blacks[i*2]) / (blacks[(i*2)+1]-y) <= 1 :
blacks[i * 2] = blacks[i * 2]+4
blacks[(i * 2) + 1] = blacks[(i * 2)+1] - 2
Am I missing something really obvious?
The problem is right here
(x - blacks[i*2]) / (blacks[(i*2)+1]-y)
Both of those values on either side of the / evaluate to 0, therefore you're dividing 0 by 0.
You're missing the right parentheses at the end of the expression in the if statement, or rather you have an extra left parentheses before (x - blacks[i*2]), which should be corrected as follows:
blacks = [0,0,0,0,0]
i = 1
x = 0
y = 0
if x > blacks[i*2] and y < blacks[(i*2)+1] and (x - blacks[i*2]) / (blacks[(i*2)+1]-y) <= 1:
blacks[i * 2] = blacks[i * 2]+4
blacks[(i * 2) + 1] = blacks[(i * 2)+1] - 2

How can I speed up this code, it has a very big input file

Could you please help me speed up this code?
It takes a very long time to run because of how big the input file is, thank you to anyone who helps out.
racers = [int(file[0].split()[0]) / float(x) for x in file[0].split()[1::]]
print("hi")
def av(race):
race = race.split()
j = 0
while j != len([float(race[0]) / float(x) for x in race[1::]]):
racers[j] = [float(race[0]) / float(x) for x in race[1::]][j] + racers[j]
j += 1
for i in range(1, len(file)):
av(file[i])
a = min(racers)
del(racers[racers.index(min(racers))])
b = min(racers)
c = b-a
h = int(c)
c-=h
m = int(c * 60)
c-=m/60
s = round(c * 60 * 60)
print(str(h) + "h" + str(m) + "m" + str(s) + "s")

Resources