Related
I am trying to find the Lotka-Volterra ODE PARAMETERS(alpha,beta,gamma,delta) from a set of (x , y, t) data (full code at the bottom)
Lotka-Volterra Equations
I believe the error is at gradLoss=loss.grad as print(loss) returns a real number while print(gradLoss) returns a 'NoneType', none value. I have been trying to run this code for hours but to no avail because "parameter -= delta*gradLoss" will not compute since gradLoss is not a number.
Here is the code:
parameter = torch.tensor([1.0137, 1.0269, 3.1526, 3.1884])
T = torch.linspace(0,25,51)
T1 = torch.zeros(len(t))
T1 = T[::500]
delta = 1e-2
n = 100
for k in range(n):
parameter = torch.tensor(parameter,requires_grad=True)
X,Y = Euler2(T, parameter[0], parameter[1], parameter[2], parameter[3], x0, y0, 0.001,25001)
loss = torch.norm(torch.tensor(X[0::500])-x)**2/torch.norm(x)**2 + torch.norm(torch.tensor(Y[0::500])-y)**2/torch.norm(y)**2
gradLoss = loss.grad <-- I believe the error is here
#with torch.no_grad():
parameter -= delta*gradLoss
if i%1 == 0:
LOSS = loss.item()
print(i, loss.item(), torch.norm(gradLoss).item())
Thanks for your help!
Best, Sacha
Rest of code:
def Euler2(t,alpha,beta,gamma,delta,x0,y0,dt,n):
alpha = alpha*torch.ones(n)
beta = beta*torch.ones(n)
gamma = gamma*torch.ones(n)
delta = delta*torch.ones(n)
X = np.zeros(n+1)
X[0] = x0
Y = np.zeros(n+1)
Y[0] = y0
for k in range(0,(n)):
X[k+1] = X[k] * (1 + alpha[k] * dt - Y[k] * beta[k] * dt)
Y[k+1] = Y[k] * (1 - gamma[k] * dt + X[k] * delta[k] * dt)
return X,Y
# x - nematodes x 1M
# y - beetle x 1M
# t - time (days)
x = torch.tensor([0.9072, 0.9439, 1.0234, 1.1035, 1.1090, 1.0245, 0.9154, 0.8933, 0.9323,
1.0302, 1.0849, 1.1195, 1.0420, 0.9284, 0.8924, 0.9400, 1.0293, 1.0969,
1.1002, 1.0344, 0.9469, 0.8910, 0.9462, 1.0291, 1.1030, 1.1044, 1.0212,
0.9352, 0.8931, 0.9307, 1.0190, 1.0974, 1.1122, 1.0311, 0.9513, 0.8962,
0.9312, 1.0082, 1.0987, 1.1100, 1.0528, 0.9421, 0.8953, 0.9381, 1.0322,
1.0880, 1.0964, 1.0296, 0.9347, 0.9083, 0.9300])
y = torch.tensor([0.8904, 0.8330, 0.8469, 0.9896, 1.1478, 1.1858, 1.0542, 0.9010, 0.8234,
0.8798, 0.9858, 1.1443, 1.2132, 1.0522, 0.8866, 0.8183, 0.8391, 0.9799,
1.1201, 1.2016, 1.0743, 0.9211, 0.8288, 0.8564, 0.9669, 1.1408, 1.2024,
1.0740, 0.9199, 0.8314, 0.8341, 0.9772, 1.1274, 1.1932, 1.0701, 0.9253,
0.8209, 0.8557, 0.9552, 1.1337, 1.2164, 1.0808, 0.9151, 0.8288, 0.8526,
0.9553, 1.1160, 1.1834, 1.0864, 0.8934, 0.8376])
t = torch.tensor([ 0.0000, 0.5000, 1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000,
4.0000, 4.5000, 5.0000, 5.5000, 6.0000, 6.5000, 7.0000, 7.5000,
8.0000, 8.5000, 9.0000, 9.5000, 10.0000, 10.5000, 11.0000, 11.5000,
12.0000, 12.5000, 13.0000, 13.5000, 14.0000, 14.5000, 15.0000, 15.5000,
16.0000, 16.5000, 17.0000, 17.5000, 18.0000, 18.5000, 19.0000, 19.5000,
20.0000, 20.5000, 21.0000, 21.5000, 22.0000, 22.5000, 23.0000, 23.5000,
24.0000, 24.5000, 25.0000])
I want to convert a point from a rectangle area to a mapping rectangle area which convert point is in the same scale.
For instance, the samll area has 4 points from (mx0, my0) to (mx3, my3), and the big area is from (x0, y0) to (x3, y3) .
Now that can get the input (intput_x, intput_y) to get the output (x,y) as the follow:
input (100, 100), get output (0, 0).
input (150, 100), get output (1920, 0).
input (100, 150), get output (0, 1080).
input (150, 150), get output (19200, 1080).
Assume the intput (intput_x, intput_y) = (110, 120), and the output (x, y) can get (384, 432).
The described as the diagram: click me.
Here is the python code:
import numpy as np
def interp(x, xp, fp, is_loop_test=True):
if (is_loop_test==True):
for i in range(100, 151):
bb = np.interp(i, xp, fp)
print(f'{i}, bb: {bb}')
return bb
else:
return np.interp(x, xp, fp)
if __name__ == '__main__':
in_x, in_y = 110, 120
xp = (100, 150)
fp = (0, 1920)
yp = (100, 150)
fyp = (0, 1080)
x, y = interp(in_x, xp, fp, False), interp(in_y, yp, fyp, False)
print(f'(x, y): ({x}, {y})')
I can using numpy interp() function to get the output with Python. However, I want to implement the same thing with Java without using numpy.
I have found the similar liner interp function named evaluate() in Java, I calculated the input x: 110, and the output was 251.40625.
It's not my expect value 384. I have no idea where is wrong.
Here's the Jave code:
public class Interp{
public static void main(String[] args){
float fraction = 0.078125f; // 150/1920=0.078125f
float startValue = 110.0f; // intput x
float endValue = 1920.0f; // 0 to 1920
float aa = evaluate(fraction, startValue, endValue);
System.out.println("x: " + aa);
}
public static Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
Could you help me or give me some idea to solve this problem? Thanks a lot!
you can use library like apache commons math to do same thing as numpy.
It is not recommended to implement it by yourself, it is difficult to do better.
Class org.apache.commons.math3.analysis.interpolation.LinearInterpolator meets your needs.
Code Example:
import org.apache.commons.math3.analysis.interpolation.LinearInterpolator;
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
// Test on commons-math3 version 3.6.1
public class InterpolatorTest {
public static void main(String[] args){
// will output 384.0
System.out.println(interpolator(110f, new double[]{100d, 150d}, new double[]{0d, 1920d}));
// will output 432.0
System.out.println(interpolator(120f, new double[]{100d, 150d}, new double[]{0d, 1080d}));
}
public static double interpolator(double value, double[] x, double[] y) {
LinearInterpolator interpolator = new LinearInterpolator();
PolynomialSplineFunction function = interpolator.interpolate(x, y);
return function.value(value);
}
}
Thanks for you help. I think I can solve it!
Here is my solution :D
Python version:
def interp(input_vlaue, small_area, big_area):
small_area_x = small_area[2][0] - small_area[0][0]
big_area_x = big_area[2][0] - big_area[0][0]
small_area_y = small_area[2][1] - small_area[0][1]
big_area_y = big_area[2][1] - big_area[0][1]
out_x = (big_area_x / small_area_x) * (input_vlaue[0] - small_area[0][0])
out_y = (big_area_y / small_area_y) * (input_vlaue[1] - small_area[0][1])
output = [out_x, out_y]
return output
if __name__ == '__main__':
intput_poiint = [110, 120]
small_area = [(100, 100), (150, 100), (150, 150), (100, 150)]
big_area = [(0, 0), (1920, 0), (1920, 1080), (0, 1080)]
convert_output = interp(input_vlaue=intput_poiint, small_area=small_area, big_area=big_area)
print(f'\nintput_poiint: {intput_poiint}')
print(f'\nconvert_output: {convert_output}')
Java version:
public class Interp{
public static void main(String[] args){
float [] intput_value = new float[2];
float [] small_area_left_up_point = new float[2];
float [] small_area_right_down_point = new float[2];
float [] big_area_left_up_point = new float[2];
float [] big_area_right_down_point = new float[2];
float [] fraction_small = new float[2];
float [] fraction_big = new float[2];
float [] output = new float[2];
intput_value[0] = (float) 110;
intput_value[1] = (float) 120;
small_area_left_up_point[0] = (float) 100;
small_area_left_up_point[1] = (float) 100;
small_area_right_down_point[0] = (float) 150;
small_area_right_down_point[1] = (float) 150;
big_area_left_up_point[0] = (float) 0;
big_area_left_up_point[1] = (float) 0;
big_area_right_down_point[0] = (float) 1920;
big_area_right_down_point[1] = (float) 1080;
fraction_small[0] = small_area_right_down_point[0] - small_area_left_up_point[0];
fraction_small[1] = small_area_right_down_point[1] - small_area_left_up_point[1];
fraction_big[0] = big_area_right_down_point[0] - big_area_left_up_point[0];
fraction_big[1] = big_area_right_down_point[1] - big_area_left_up_point[1];
output[0] = interp(intput_value[0], fraction_small[0], fraction_big[0], small_area_left_up_point[0]);
output[1] = interp(intput_value[1], fraction_small[1], fraction_big[1], small_area_left_up_point[1]);
System.out.println("(intput_x, intput_y): " + intput_value[0] +", "+ intput_value[1]);
System.out.println("(output_x, output_y): " + output[0] +", "+ output[1]);
}
public static Float interp(float input_value, float small_fraction, float big_fraction, float mapping_left_point){
return (big_fraction/small_fraction) * (input_value-mapping_left_point);
}
}
Both version input (110, 120) can get the output (384, 432).
I am pleased to convert it! :D
So I'd like to see if it's possible to implement non max suppression in nodejs from google clouds vision API responses, for example a response looks like this:
[
{
"mid": "/m/09728",
"languageCode": "",
"name": "Bread",
"score": 0.8558391332626343,
"boundingPoly": {
"vertices": [],
"normalizedVertices": [
{
"x": 0.010737711563706398,
"y": 0.26679491996765137
},
{
"x": 0.9930269718170166,
"y": 0.26679491996765137
},
{
"x": 0.9930269718170166,
"y": 0.7275580167770386
},
{
"x": 0.010737711563706398,
"y": 0.7275580167770386
}
]
}
},
{
"mid": "/m/052lwg6",
"languageCode": "",
"name": "Baked goods",
"score": 0.6180902123451233,
"boundingPoly": {
"vertices": [],
"normalizedVertices": [
{
"x": 0.010737711563706398,
"y": 0.26679491996765137
},
{
"x": 0.9930269718170166,
"y": 0.26679491996765137
},
{
"x": 0.9930269718170166,
"y": 0.7275580167770386
},
{
"x": 0.010737711563706398,
"y": 0.7275580167770386
}
]
}
},
{
"mid": "/m/02wbm",
"languageCode": "",
"name": "Food",
"score": 0.5861617922782898,
"boundingPoly": {
"vertices": [],
"normalizedVertices": [
{
"x": 0.321802020072937,
"y": 0.2874892055988312
},
{
"x": 0.999139130115509,
"y": 0.2874892055988312
},
{
"x": 0.999139130115509,
"y": 0.6866284608840942
},
{
"x": 0.321802020072937,
"y": 0.6866284608840942
}
]
}
}
]
So actually the bounding box that should be on the outside is food like so:
I've found examples in Python to do this, but that means I need to use subprocesses in Node to execute the python script and then pull back the response, which kinda feels a bit dirty.
Obviously those box values from google need multiplying by the image height and width, so if we assume it's 288 X 512 for example:
const left = Math.round(vertices[0].x * 288);
const top = Math.round(vertices[0].y * 512);
const width = Math.round((vertices[2].x * 288)) - left;
const height = Math.round((vertices[2].y * 512)) - top;
My adapted script is like so(just hard codes the threshold and takes the array of boxes from the command line):
# import the necessary packages
import numpy as np
import sys
import json
# Malisiewicz et al.
def non_max_suppression_fast():
overlapThresh = 0.3
boxes = json.loads(sys.argv[1])
# if there are no boxes, return an empty list
if len(boxes) == 0:
return []
# if the bounding boxes integers, convert them to floats --
# this is important since we'll be doing a bunch of divisions
if boxes.dtype.kind == "i":
boxes = boxes.astype("float")
# initialize the list of picked indexes
pick = []
# grab the coordinates of the bounding boxes
x1 = boxes[:,0]
y1 = boxes[:,1]
x2 = boxes[:,2]
y2 = boxes[:,3]
# compute the area of the bounding boxes and sort the bounding
# boxes by the bottom-right y-coordinate of the bounding box
area = (x2 - x1 + 1) * (y2 - y1 + 1)
idxs = np.argsort(y2)
# keep looping while some indexes still remain in the indexes
# list
while len(idxs) > 0:
# grab the last index in the indexes list and add the
# index value to the list of picked indexes
last = len(idxs) - 1
i = idxs[last]
pick.append(i)
# find the largest (x, y) coordinates for the start of
# the bounding box and the smallest (x, y) coordinates
# for the end of the bounding box
xx1 = np.maximum(x1[i], x1[idxs[:last]])
yy1 = np.maximum(y1[i], y1[idxs[:last]])
xx2 = np.minimum(x2[i], x2[idxs[:last]])
yy2 = np.minimum(y2[i], y2[idxs[:last]])
# compute the width and height of the bounding box
w = np.maximum(0, xx2 - xx1 + 1)
h = np.maximum(0, yy2 - yy1 + 1)
# compute the ratio of overlap
overlap = (w * h) / area[idxs[:last]]
# delete all indexes from the index list that have
idxs = np.delete(idxs, np.concatenate(([last],
np.where(overlap > overlapThresh)[0])))
# return only the bounding boxes that were picked using the
# integer data type
return boxes[pick].astype("int")
Is anyone able to give me any pointers here please? I'm pretty sure it's just about calculating the total area of the each box, but I can't quite get my brain around it.
Ok so actually this is pretty simple if you use Tensorflow.js - use the following function to take the response from google vision:
Note 288 and 512 are my image width and height you'll need to setup your own.
function nonMaxSuppression(objects){
return new Promise((resolve) => {
// Loop through the objects and convert the vertices into the right format.
for (let index = 0; index < objects.length; index++) {
const verts = objects[index].boundingPoly.normalizedVertices;
// As above note 288 and 512 are image width and image height for me.
const left = Math.round(verts[0].x * 288);
const top = Math.round(verts[0].y * 512);
const width = Math.round((verts[2].x * 288)) - left;
const height = Math.round((verts[2].y * 512)) - top;
// we need an array of boxes AND an array of scores
this.boxes.push([left, top, width, height]);
this.scores.push(objects[index].score);
}
// Params are boxes, scores, max number of boxes to select.
const theBox = tf.image.nonMaxSuppression(this.boxes, this.scores, 2);
// the function returns the box number that matched from this.boxes, seems like it's not zero based at least in my tests so we need to - 1 to get the index from the original array.
resolve(theBox.id -1 );
});
}
Ta-dah banana!
I'm trying to achieve the pattern below.
Got as far as doing the first line, then I have no clue how to code the rest of the pattern.
Here's what I've done so far:
#Timothy Shek
from graphics import*
#open Graph Window
def main():
win = GraphWin("Example",100,100)
x = 7
y = 7
radius = 5
while x<=30 :
centre = Point(x,y)
circle1 = Circle(centre,radius)
circle1.setFill("red")
circle1.draw(win)
x = x+10
while x>=35 and x<=65 :
centre = Point(x+5,y)
circle2 = Circle(centre,radius)
circle2.setFill("red")
circle2.draw(win)
x = x+10
print(x)
while x>=67:
centre = Point(x+10,y)
circle1 = Circle(centre,radius)
circle1.setFill("red")
circle1.draw(win)
x = x+10
main()
I got it guys, thanks
Heres the solution
#Timothy Shek
from graphics import*
#open Graph Window
def main():
win = GraphWin("Patch2" ,100,100)
for x in (5, 15, 25, 40,50,60,75,85,95):
for y in (5, 15, 25, 40,50,60,75,85,95):
c = Circle(Point(x+2,y), 5)
d = Circle(Point(x+2,y), 5)
c.draw(win)
d.draw(win)
c.setFill("Red")
d.setFill("Red")
if x==15 or x==50 or x== 85:
if y==15 or y==50 or y== 85:
c2 = Circle(Point(x+2,y),5)
c2.draw(win)
c2.setFill("White")
main()
While there is nothing wrong with your solution, this is a bit more performant
from graphics import *
def main():
win = GraphWin("Patch2" ,100,100)
coords = [5, 15, 25, 40, 50, 60, 75, 85, 95]
centers = set([coords[i] for i in range(1, len(coords), 3)])
for i in xrange(len(coords)):
for j in xrange(i+1):
x, y = (coords[i], coords[j])
c1 = Circle(Point(x+2,y), 5)
c2 = Circle(Point(y+2,x), 5)
c1.draw(win)
c2.draw(win)
if x in centers and y in centers:
c1.setFill("White")
c2.setFill("White")
else:
c1.setFill("Red")
c2.setFill("Red")
main()
Update: "Better" version
And since I got bored and I liked this problem (yes, I program when I'm bored) I made a fully parameter-ized version which you can do some fun stuff with, like.
Probably over your head :) But maybe you learn something from it, so I'm posting it.
from graphics import *
def drawPattern(scale):
# Inner method: Draw a square of circles given the top-left point
def drawSquare(win, xCoord, yCoord, squareSize=30, numCircles=3, scale=1, scaleCircles=False, outer_color="Red", inner_color="White"):
# Overwrite the default scaling
if scale > 1:
squareSize *= scale
if scaleCircles:
numCircles *= scale
radius = squareSize/(numCircles*2) # Divide by 2 since it's the radius
from math import sqrt, floor
centerDiff = (2*radius) * floor(sqrt(numCircles)) # Used for drawing off-color circles
# xrange uses an exclusive stop value, so go one value past to make inclusive
for x in xrange(radius, squareSize+radius, radius*2):
for y in xrange(squareSize-radius, x-radius, -radius*2):
c1 = Circle(Point(x+xCoord+2,y+yCoord), radius)
c2 = Circle(Point(y+yCoord+2,x+xCoord), radius)
c1.draw(win)
c2.draw(win)
if (centerDiff < x < squareSize - centerDiff) and (centerDiff < y < squareSize - centerDiff):
c1.setFill(inner_color)
c2.setFill(inner_color)
else:
c1.setFill(outer_color)
c2.setFill(outer_color)
win = GraphWin("Patch2 (x{})".format(scale), 100*scale,100*scale)
coords = [0, 35, 70]
for x in coords:
for y in coords:
drawSquare(win, x*scale, y*scale, scale=scale) # normal (boring) version
# drawSquare(win, x*scale, y*scale, scale=scale, scaleCircles=True, outer_color="Blue") # Picture version
def main():
drawPattern(3)
main()
I am trying to compile and use a c library in python using ctypes module. The library is strangely working fine on Linux machine but throwing SIGSEGV on Cygwin64.
import ctypes
import numpy as np
import pdb
xbry = np.array([0.9, 0.1, 0.2, 0.9])
ybry = np.array([0.9, 0.9, 0.1, 0.1])
beta = np.array([1.0, 1.0, 1.0, 1.0])
nx = 30
ny = 30
ul_idx = 0
nnodes=14
precision=1.0e-12
nppe=3
newton=True
thin=True
checksimplepoly=True
verbose=True
_libgridgen = np.ctypeslib.load_library('libgridgen.dll', '/home/Nikhil/python/octant/gridgen')
print _libgridgen
_libgridgen.gridgen_generategrid2.restype = ctypes.c_void_p
_libgridgen.gridnodes_getx.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_double))
_libgridgen.gridnodes_gety.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_double))
_libgridgen.gridnodes_getnce1.restype = ctypes.c_int
_libgridgen.gridnodes_getnce2.restype = ctypes.c_int
_libgridgen.gridnodes_getnx.restype = ctypes.c_int
_libgridgen.gridnodes_getny.restype = ctypes.c_int
_libgridgen.gridmap_build.restype = ctypes.c_void_p
nbry = len(xbry)
nsigmas = ctypes.c_int(0)
sigmas = ctypes.c_void_p(0)
nrect = ctypes.c_int(0)
xrect = ctypes.c_void_p(0)
yrect = ctypes.c_void_p(0)
ngrid = ctypes.c_int(0)
xgrid = ctypes.POINTER(ctypes.c_double)()
ygrid = ctypes.POINTER(ctypes.c_double)()
_gn = _libgridgen.gridgen_generategrid2(
ctypes.c_int(nbry),
(ctypes.c_double * nbry)(*xbry),
(ctypes.c_double * nbry)(*ybry),
(ctypes.c_double * nbry)(*beta),
ctypes.c_int(ul_idx),
ctypes.c_int(nx),
ctypes.c_int(ny),
ngrid,
xgrid,
ygrid,
ctypes.c_int(nnodes),
ctypes.c_int(newton),
ctypes.c_double(precision),
ctypes.c_int(checksimplepoly),
ctypes.c_int(thin),
ctypes.c_int(nppe),
ctypes.c_int(verbose),
ctypes.byref(nsigmas),
ctypes.byref(sigmas),
ctypes.byref(nrect),
ctypes.byref(xrect),
ctypes.byref(yrect) )
print 'run getx'
x = _libgridgen.gridnodes_getx(_gn)
print 'reshape result.'
x = np.asarray([x[0][i] for i in range(ny*nx)])
x.shape = (ny, nx)
print 'run gety'
y = _libgridgen.gridnodes_gety(_gn)
print 'reshape result.'
y = np.asarray([y[0][i] for i in range(ny*nx)])
y.shape = (ny, nx)
backtrace
Program received signal SIGSEGV, Segmentation fault.
0x0000000542596595 in gridnodes_getx (gn=0x45ab50) at gridnodes.c:789
789 return gn->gx;
(gdb) backtrace
0 0x0000000542596595 in gridnodes_getx (gn=0x45ab50) at gridnodes.c:789
and this is the c code backtrace is referring to
int gridnodes_getnx(gridnodes* gn)
{
return gn->nx;
}
int gridnodes_getny(gridnodes* gn)
{
return gn->ny;
}
double** gridnodes_getx(gridnodes* gn)
{
return gn->gx;
}
double** gridnodes_gety(gridnodes* gn)
{
return gn->gy;
}
I would appreciate if some one can help me with this.
I managed to solve the issue by using a class
class gridnodes (ctypes.Structure):
_fields_ = [
('nx',ctypes.c_int), \
('ny',ctypes.c_int), \
('gx', ctypes.c_double), \
('gy', ctypes.c_double)]
and replacing
_libgridgen.gridgen_generategrid2.restype = ctypes.c_void_p
by
_libgridgen.gridgen_generategrid2.restype = ctypes.POINTER(gridnodes)
I also tried the suggestion by #eryksun and that works as well..