scikits.bvp_solver generates ValueError: too many values to unpack - python-2.7

I will start with a very simple ODE, which generates the same error code by using scikits.bvp_solver as I applied to complex ODE. Below is the ODE and the boundary conditions:
f''''(x)=f(x), f(0)=0, f'(1)=1, f''(0)=1, f'''(1)=1
The code for solving this ODE:
import numpy
import scikits.bvp_solver as bvp
def Fode(x,y):
return numpy.array([y[1],y[2],y[3],y[0]])
def Fbc(ya,yb):
return (numpy.array([ya[0]]),numpy.array([yb[1]-1]),
numpy.array([ya[2]-1]),numpy.array([yb[3]-1]))
guess=numpy.array([0.0,0.0,0.0,0.0])
problem=bvp.ProblemDefinition (num_ODE=4,num_parameters=0,
num_left_boundary_conditions=2,
boundary_points=(0,1),
function=Fode,boundary_conditions=Fbc)
solution=bvp.solve(bvp_problem=problem,solution_guess=guess)
when I run this code, I receive:
I can not figure out what is the problem, since the same code works well for 2nd order ODE. Any comment is appreciated.

Your Fbc function should return exactly two arrays, one containing function value differences for boundary conditions at the left, the other one containing the values at the right.
See https://pythonhosted.org/scikits.bvp_solver/tutorial.html#defining-the-problem
https://pythonhosted.org/scikits.bvp_solver/examples/examples.example4.html

Related

Django: Problems passing a list and the results of the list treated by a function as two separate variables to the template

I'm trying to make CV website which has a sudoku generator and solver. The generator and solver are two separate functions in the functions.py file imported into the views.py file.
My sudokus are stored in a list of 9 lists of 9 ints.
from views.py:
from functions import *
def sudoku(request):
grid = make_sudoku() # generates unsolved sudoku list
solved = solve(grid) # generates solved list of unsolved list fed in.
count = [i for i in range(9)]
context = {
'grid': grid,
'solved': solved,
'count': count
}
return render(request, 'main/sudoku.html', context)
if I print grid, I get an unsolved sudoku list. If I print solved, I get a the same list which has been solved. Everything works dandy up until that point, but if I go to sudoku.html and type {{ grid }}, I get a solved sudoku list.
As the tree said to the lumberjack, I'm STUMPED! I'm completely baffled as to why this might happen because at no point in sudoku.html do I refer to grid or solved outside of passing them on to sudoku.js which actually makes the puzzle.
your solve() function probably is not only returning the solved grid but it'd also modify the existing grid and solve it in place, it's not making a copy but solving it on the same grid. read more about passing by value and passing by reference (here grid is being passes by reference)
https://flexiple.com/python/python-pass-by-reference/
additionally, you can replace
count = [i for i in range(9)]
by
count = list(range(9))

Django: Query gives zero results after first match in for loop

The following code works fine until the filter gets first match(es). After that on the following runs in the for loop, the query always returns 0. If in that result object would be a match for the next row also, it doesn't even see that, so I don't see this being a cache issue (which might have been far fetched anyhow).
for row in self._ordr.OrderRows.SalesOrderRow:
available = row.Row_amount - Slot.objects.filter(rows_ids=row.Row_id).count()
if available > 0 or row.Row_id in self.instance.rows_ids:
# some code
Any ideas what am I doing wrong here?
This is the models code on that rows_ids.
from django.db import models
from django_mysql.models import ListCharField
class Slot(models.Model):
rows_ids = ListCharField(base_field=models.IntegerField(), size=10, max_length=(10 * 21), null=True)
Went through the documentation once more, and apparently it's a ListCharField based issue. To find a match in all the options in it, you shouldn't compare it directly to the field, but rather to field__contains. So the correct code is:
for row in self._ordr.OrderRows.SalesOrderRow:
available = row.Row_amount - Slot.objects.filter(rows_ids__contains=row.Row_id).count()
if available > 0 or row.Row_id in self.instance.rows_ids:
# some code
Finally got it to work with this.

Fitting multiple data sets using lmfit without writting an objective function

This topic describes how to fit multiple data-sets using lmfit:
Python and lmfit: How to fit multiple datasets with shared parameters?
However it uses a fitting/objective function written by the user.
I was wondering if it's possible to fit multiple data-sets using lmfit without writing an objective function and using model.fit() method of the model class.
As an example: Lets say we have multiple data sets of (x,y) coordinates that we want to fit using the same model function in order to find the set of parameters that on average fit all the data best.
import numpy as np
from lmfit import Model, Parameters
from lmfit.models import GaussianModel
def gauss(x, amp, cen, sigma):
return amp*np.exp(-(x-cen)**2/(2.*sigma**2))
x1= np.arange(0.,100.,0.1)
x2= np.arange(0.,100.,0.09)
y1= gauss(x1, 1.,50.,5.)+ np.random.normal(size=len(x1), scale=0.1)
y2= gauss(x2, 0.8,48.4.,4.5)+ np.random.normal(size=len(x2), scale=0.1)
mod= GaussianModel()
params= mod.make_params()
mod.fit([y1,y2], params, x= [x1, x2])
I guess if this is possible the data has to be passed to mod.fit in the right type. The documentation only says that mod.fit takes an array-like data input.
I tried to give it lists and arrays. If I pass the different data sets as a list I get a ValueError: setting an array element with a sequence
If I pass an array I get an AttributeError: 'numpy.ndarray' has no atribute 'exp'
So am I just trying to do something that isn't possible or am I doing something wrong?
Well, I think the answer is "sort of". The lmfit.Model class is meant to represent a model for an array of data. So, if you can map your multiple datasets into a numpy ndarray (say, with np.concatenate), you can probably write a Model function to represent this by building sub-models for the different datasets and concatenating them in the same way.
I don't think you could do that with any of the built-in models. I also think that once you start down the road of writing complex model functions, it isn't a very big jump to writing objective functions. That is, what would be
def model_function(x, a, b, c):
### do some calculation with x, a, b, c values
result = a + x*b + x*x*c
return result
might become
def objective_function(params, x, data):
vals = params.valuesdict()
return data - model_function(x, vals['a'], vals['b'], vals['c'])
If that do_calc() is doing anything complex, the additional burden of unpacking the parameters and subtracting the data is pretty small. And, especially if some parameters would be used for multiple datasets and some only for particular datasets, you'll have to manage that in either the model function or the objective function. In the example you link to, my answer included a loop over datasets, picking out parameters by name for each dataset. You'll probably want to do something like that. You could probably do that in a model function by thinking of it as modeling the concatenated datasets, but I'm not sure you'd really gain a lot by doing that.
I found the problem. Actually model.fit() will handle arrays of multiple data sets just fine and perform a proper fit. The correct call of model.fit() with multiple data sets would be:
import numpy as np
from lmfit import Model, Parameters
from lmfit.models import GaussianModel
import matplotlib.pyplot as plt
def gauss(x, amp, cen, sigma):
"basic gaussian"
return amp*np.exp(-(x-cen)**2/(2.*sigma**2))
x1= np.arange(0.,100.,0.1)
x2= np.arange(0.,100.,0.1)
y1= gauss(x1, 1.,50.,5.)+ np.random.normal(size=len(x1), scale=0.01)
y2= gauss(x2, 0.8,48.4,4.5)+ np.random.normal(size=len(x2), scale=0.01)
mod= GaussianModel()
params= mod.make_params()
params['amplitude'].set(1.,min=0.01,max=100.)
params['center'].set(1.,min=0.01,max=100.)
params['sigma'].set(1.,min=0.01,max=100.)
result= mod.fit(np.array([y1,y2]), params,method='basinhopping',
x=np.array([x1,x2]))
print(result.fit_report(min_correl=0.5))
fig, ax = plt.subplots()
plt.plot(x1,y1, lw=2, color='red')
plt.plot(x2,y2, lw=2, color='orange')
plt.plot(x1,result.eval(x=x1), lw=2, color='black')
plt.show()
The problem in the original code actually lies in the fact that my data sets don't have the same length. However I'm not sure at all how to handle this in the most elegant way?

How to handle probability notation in python?

I'm newbie for python 2.7. I would like to create some function that knows which are variables in the given probability notation.
For example: Given a probability P(A,B,C|D,E,F) as string input. The function should return a list of events ['A','B','C'] and a list of sample spaces ['D','E','F']. If it is impossible to return two lists in the same time. Returning a list of two lists would be fine.
In summary:
Input:
somefunction('P(A,B,C|D,E,F)')
Expected output: [['A','B','C'],['D','E','F']]
Thank you in advance
A simple brute-force implementation. As #fjarri pointed out if you want to do anything more complex you might need a parser (like PyParser) or at least some regular expressions.
def somefunction(str):
str = str.strip()[str.index("(")+1:-1]
left, right = str.split("|")
return [left.split(","), right.split(",")]

NZEC error in python 2.7 MAXCOUNT codechef

BELOW is the code for the problem MAXCOUNT from codechef.com. The code on submission shows NZEC error.
The code takes first input t as no. of test cases, then for each test case takes input n a integer and the next line consists of space separated n integers Basically I need to return the maximum occuring integer and its count as output.
import numpy as np
import sys
t = int(raw_input())
for i in xrange(t):
n = raw_input()
n = int(n)
a = []
a = map(int, raw_input().split())
print a
count = np.bincount(a)
print np.argmax(count),np.max(count)
sys.exit(0)
Someone please help me out with this error.
The answer to your question is the use of the numpy module, which is not part of the standard library used on CodeChef. If you need to check numpy or another module in an online programming judge, a good way is to use a code sample that you know works and then add the import statement to the top before resubmitting.
For CodeChef in particular, try the basic test with the following code, with and without the import statement:
#Test for modules
import numpy
number_in = int(raw_input())
while number_in != 42:
print number_in
number_in = int(raw_input())
As a suggestion, the Counter() function from the collections module will work on CodeChef, you may want to try that instead of numpy. I find however that for many of the problems on that site without numpy or using PyPy it can be quite difficult to meet the timing requirements for solutions.