I am using oct2py to run octave function with python.
It is working but I get an error when I try to multiply 2 matrix.
What can I do to solve the problem?
this is a sample matlab funcion
%% MATLAB
function lol = jk2(arg1,arg2)
arg1 = arg1;
arg2 = arg2;
lol = arg1*arg2;
end
this is the code to call the function
import oct2py
from oct2py import octave
a=3
b=4
octave.call("/MATLAB/jk2.m",a,b) # this call works
a=np.array([[1,2],[3,4]])
b=np.array([[5,6],[1,2]])
octave.call("/MATLAB/jk2.m",a,b) # this call report an errors
This is the error message
>>> octave.call("/home/donbeo/Documents/MATLAB/jk2.m",a,b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/oct2py-1.2.0-py2.7.egg/oct2py/session.py", line 210, in call
resp = self._eval(cmd, verbose=verbose)
File "/usr/local/lib/python2.7/dist-packages/oct2py-1.2.0-py2.7.egg/oct2py/session.py", line 350, in _eval
return self._session.evaluate(cmds, verbose, log, self.logger)
File "/usr/local/lib/python2.7/dist-packages/oct2py-1.2.0-py2.7.egg/oct2py/session.py", line 523, in evaluate
raise Oct2PyError(msg)
oct2py.utils.Oct2PyError: Oct2Py tried to run:
"""
[a__] = jk2(A__, B__)
"""
Octave returned:
binary operator '*' not implemented for 'int64 matrix' by 'int64 matrix' operations
>>>
Here is an example of where the line between Python and Octave gets blurry. Numpy interprets your arrays as being of integer type (because there are no explicit floats), but Octave would treat the arrays as Doubles. If you add a period anywhere in you array definitions, it will all work.
Fixed (tested) example:
from oct2py import octave
import numpy as np
a = np.array([[1, 2], [3, 4.]]) # notice the addition of the period
b = np.array([[5, 6], [1, 2], dtype=float]) # another way to specify floating point type
octave.call("/MATLAB/jk2.m", a, b) # this call works just fine
Related
I have a following problem. I am following this example about spatial regression in Python:
import numpy
import libpysal
import spreg
import pickle
# Read spatial data
ww = libpysal.io.open(libpysal.examples.get_path("baltim_q.gal"))
w = ww.read()
ww.close()
w_name = "baltim_q.gal"
w.transform = "r"
Example above works. But I would like to read my own spatial matrix which I have now as a list of lists. See my approach:
ww = libpysal.io.open(matrix)
But I got this error message:
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "/home/vojta/Desktop/INTERNET_HANDEL/ZASILKOVNA/optimal-delivery-branches/venv/lib/python3.8/site-packages/libpysal/io/fileio.py", line 90, in __new__
cls.__registry[cls.getType(dataPath, mode, dataFormat)][mode][0]
File "/home/vojta/Desktop/INTERNET_HANDEL/ZASILKOVNA/optimal-delivery-branches/venv/lib/python3.8/site-packages/libpysal/io/fileio.py", line 105, in getType
ext = os.path.splitext(dataPath)[1]
File "/usr/lib/python3.8/posixpath.py", line 118, in splitext
p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not list
this is how matrix looks like:
[[0, 2, 1], [2, 0, 4], [1, 4, 0]]
EDIT:
If I try to insert my matrix into the GM_Lag like this:
model = spreg.GM_Lag(
y,
X,
w=matrix,
)
I got following error:
warn("w must be API-compatible pysal weights object")
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 2, in <module>
File "/home/vojta/Desktop/INTERNET_HANDEL/ZASILKOVNA/optimal-delivery-branches/venv/lib/python3.8/site-packages/spreg/twosls_sp.py", line 469, in __init__
USER.check_weights(w, y, w_required=True)
File "/home/vojta/Desktop/INTERNET_HANDEL/ZASILKOVNA/optimal-delivery-branches/venv/lib/python3.8/site-packages/spreg/user_output.py", line 444, in check_weights
if w.n != y.shape[0] and time == False:
AttributeError: 'list' object has no attribute 'n'
EDIT 2:
This is how I read the list of lists:
import pickle
with open("weighted_matrix.pkl", "rb") as f:
matrix = pickle.load(f)
How can I insert list of lists into spreg.GM_Lag ? Thanks
Why do you want to pass it to the libpysal.io.open method? If I understand correctly this code, you first open a file, then read it (and the read method seems to be returning a List). So in your case, where you already have the matrix, you don't need to neither open nor read any file.
What will be needed though is what w is supposed to look like here: w = ww.read(). If it is a simple matrix, then you can initialize w = matrix. If the read method also format the data a certain way, you'll need to do it another way. If you could describe the expected behavior of the read method (e.g. what does the input file contain, and what is returned), it would be useful.
As mentioned, as the data is formatted into a libpysal.weights object, you must build one yourself. This can supposedly be done with this method libpysal.weights.W. (Read the doc too fast).
I have a matrix with symbolic variable in MATLAB like this:
syms x
f = [x^2 x^3 x^4];
save ('sym.mat','f')
Thus I saved the f matrix as sym.mat. Now I want to import this matrix into python. So I tried this:
import scipy.io as sio
matrix = sio.loadmat('sym.mat')
sym = matrix['f']
But it didn't work. I got this error, which is just a regular python keyerror.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'f'
However if f is not a symbolic matrix then this code works fine. Any ideas how I can deal with these matrices with symbolic variables?
Scipy can't load MATLAB symbolic variables.
The best way to deal with your problem is to convert your Symbolic matrix into Matrix of chars(not matlab strings since it will cause errors too)
So here is what I mean:
In MATLAB, you can do something like that:
syms x
f = [x^2 x^3 x^4];
for i = 1:numel(f)
if i == 1
f2 = char(f(i));
else
f2 = [f2 ',' char(f(i))];
end
end
save('sym.mat','f2')
This will display:
x^2,x^3,x^4
Now, In python you could do something like that:
import scipy.io as sio
path = 'H:\MatlabScripts'
matrix = sio.loadmat(path + '\sym.mat')
sym = matrix['f2'][0].split(',')
print(sym)
The result will be:
['x^2', 'x^3', 'x^4']
I am trying to find the laplace inverse of an expression for which all but one variable are already defined at the time of declaration:
from numpy import *
import mpmath as mp
p0 = 1
E = 2
c= 3
L = 4
x = 2.5
t = linspace(1,5,10)
ulaplace = []
def U(s):
return(c*p0*(-exp(L*s/c) + exp(s*(L + 2*x)/c))*exp(-s*x/c)/(E*s**2*(exp(2*L*s/c) + 1)))
for ti in t:
ulaplace.append(mp.invertlaplace(U, ti, method='talbot'))
But I am getting this error:
Traceback (most recent call last):
File "D:\TEMP\IDLEscripts\CompareAnalyticalSolutions2.py", line 46, in <module>
ulaplace.append(mp.invertlaplace(U, ti, method='talbot'))
File "C:\Python35\lib\site-packages\mpmath\calculus\inverselaplace.py", line 805, in invertlaplace
fp = [f(p) for p in rule.p]
File "C:\Python35\lib\site-packages\mpmath\calculus\inverselaplace.py", line 805, in <listcomp>
fp = [f(p) for p in rule.p]
File "D:\TEMP\IDLEscripts\CompareAnalyticalSolutions2.py", line 43, in U
return(c*p0*(-exp(L*s/c) + exp(s*(L + 2*x)/c))*exp(-s*x/c)/(E*s**2*(exp(2*L*s/c) + 1)))
TypeError: attribute of type 'int' is not callable
I also tried the lambda function format suggested by the doc website but still got the same error.
Does the mpmath.invertlaplace function require that everything be in numerical termsat the time of definition? I am asking because this worked:
>>> import mpmath as mp
>>> def F(s):
return 1/s
>>> mp.invertlaplace(F,5, method = 'talbot')
mpf('1.0')
If so, I need to be able to circumvent this. The whole point for me is to play around with the other variables and see how they affect the inverse laplacian. Furthermore one would think that the function gets evaluated before it is passed on to mpmath.
If not, then what on earth is going on here?
Allright I got it. Basically the function that mp.invertlaplace needs to itself only use mpmath defined functions. In the code provided in the original question I am using exp from the numpy library. So exp(x) is really numpy.exp(x). To make the code work it needs to call the mpmath.exp function as follows:
def U(s):
return -p0*mp.exp(s*x/c)/(E*s*(-s*mp.exp(L*s/c)/c - s*mp.exp(-L*s/c)/c)) + p0*mp.exp(-s*x/c)/(E*s*(-s*mp.exp(L*s/c)/c - s*mp.exp(-L*s/c)/c))
I have not tested the above on the reduced example I provided in the original question, since it is a subset of the more general script. However it should work and this appears to be the root of the problem.
in the example below, there is a 3d numpy matrix of size (4, 3, 3)+ a solution about how to calculate pinv of each of 4 of those 3*3 matrices in numpy. I also tried to use the same function worked in numpy, in theano hoping that it is implemented the same, but it failed. Any idea how to do it in theano?
dt = np.dtype(np.float32)
a=[[[12,3,1],
[2,4,1],
[2,4,2],],
[[12,3,3],
[2,4,4],
[2,4,5],],
[[12,3,6],
[2,4,5],
[2,4,4],],
[[12,3,3],
[2,4,5],
[2,4,6]]]
a=np.asarray(a,dtype=dt)
print(a.shape)
apinv=np.zeros((4,3,3))
print(np.linalg.pinv(a[0,:,:]).shape)
#numpy solution
apinv = map(lambda n: np.linalg.pinv(n), a)
apinv = np.asarray(apinv,dtype=dt)
#theano solution (not working)
at=T.tensor3('a')
apinvt = map(lambda n: T.nlinalg.pinv(n), at)
The error is:
Original exception was:
Traceback (most recent call last):
File "pydevd.py", line 2403, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "pydevd.py", line 1794, in run
launch(file, globals, locals) # execute the script
File "exp_thn_pinv_map.py", line 35, in <module>
apinvt = map(lambda n: T.nlinalg.pinv(n), at)
File "theano/tensor/var.py", line 549, in __iter__
raise TypeError(('TensorType does not support iteration. '
TypeError: TensorType does not support iteration. Maybe you are using builtin.sum instead of theano.tensor.sum? (Maybe .max?)
The error message is
Traceback (most recent call last):
File "D:/Dropbox/source/intro_theano/pinv.py", line 32, in <module>
apinvt = map(lambda n: T.nlinalg.pinv(n), at)
File "d:\dropbox\source\theano\theano\tensor\var.py", line 549, in __iter__
raise TypeError(('TensorType does not support iteration. '
TypeError: TensorType does not support iteration. Maybe you are using builtin.sum instead of theano.tensor.sum? (Maybe .max?)
This is occurring because, as the error message indicates, the symbolic variable at is not iterable.
The fundamental problem here is that you're incorrectly mixing immediately executed Python code with delayed execution Theano symbolic code.
You need to use a symbolic loop, not a Python loop. The correct solution is to use Theano's scan operator:
at=T.tensor3('a')
apinvt, _ = theano.scan(lambda n: T.nlinalg.pinv(n), at, strict=True)
f = theano.function([at], apinvt)
print np.allclose(f(a), apinv)
I am trying to find the maximum value in a scipy.sparse matrix. The docs here say there is a .max method. Oddly, however, this doesn't work for me:
>>> import scipy.sparse as sps
>>> a = sps.csr_matrix((3,3))
>>> a[0,0] = 1
>>> a.max()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/sparse/base.py", line 393, in __getattr__
raise AttributeError(attr + " not found")
AttributeError: max not found
Any idea why this might be happening?
(I am using scipy version 0.11.0)
Some archeology in the scipy docs website shows that method being introduced in scipy 13.0.
If you do not want to upgrade, you can get the maximum of the non-zero entries of your sparse matrix with a.data.max().
If you want it to be the maximum considering the zeros as well, which is what the .max() method does, do something along the lines of:
m = a.data.max()
if m < 0 and a.nnz < a.shape[0]*a.shape[1]:
m = 0