Scientific/Exponential notation with sympy in an ipython notebook 2 - sympy

How can one force scientific notation to any number printed in a ipython notebook using display?
Example:
from sympy import *
init_printing()
a = Symbol('a')
aval = 1/100
display(Eq(a, aval))
produces
๐‘Ž=0.01
The desired output is
๐‘Ž=1.0 ยท 10โปยฒ
or something in that line.
This was partially answered here like 6 years ago, but the solution is not applicable to this case

Related

Sympy performance issue with solving exp related equation

I have an equation: f = (100*E**(-x*1600)-50), it takes a very long time to give a solution for x but in another online solver, it only takes a few ms. How can I do to boost the performance?
raw code:
f = (100*E**(-x*1600)-50)
solve(f,x)
Expected result:
If you just want the real solution (and not the many symbolic solutions) use nsolve. The bisect solvers is appropriated for this function with a steep gradient near the root. Defining lam = var('lam') gives
If you want a symbolic solution (but not the many imaginary ones) then solveset or the lower level _invert can be used:
>>> from sympy import solveset, var, Reals
>>> from sympy.solvers.solvers import _invert
>>> var('x')
x
>>> eq=(100*E**(-x*1600)-50)
>>> solveset(eq,x,Reals)
{log(2)/1600}
>>> from sympy.solvers.solvers import _invert
>>> _invert(eq,x)
(log(2)/1600, x)

Pvlib / Bird1984: North-facing element shows negative Irradiance

When using pvlib (but also the spectrl2 implementation provided by NREL), I obtain negative Irradiance for a north-facing panel.
Is this expected behaviour? Should the spectrum simply be cut at zero?
Added example code based on the tutorial below:
## Using PV Lib
from pvlib import spectrum, solarposition, irradiance, atmosphere
import pandas as pd
import matplotlib.pyplot as plt
# assumptions from the technical report:
lat = 49.88
lon = 8.63
tilt = 45
azimuth = 0 # North = 0
pressure = 101300 # sea level, roughly
water_vapor_content = 0.5 # cm
tau500 = 0.1
ozone = 0.31 # atm-cm
albedo = 0.2
times = pd.date_range('2021-11-30 8:00', freq='h', periods=6, tz="Europe/Berlin") # , tz='Etc/GMT+9'
solpos = solarposition.get_solarposition(times, lat, lon)
aoi = irradiance.aoi(tilt, azimuth, solpos.apparent_zenith, solpos.azimuth)
# The technical report uses the 'kasten1966' airmass model, but later
# versions of SPECTRL2 use 'kastenyoung1989'. Here we use 'kasten1966'
# for consistency with the technical report.
relative_airmass = atmosphere.get_relative_airmass(solpos.apparent_zenith,
model='kasten1966')
spectra = spectrum.spectrl2(
apparent_zenith=solpos.apparent_zenith,
aoi=aoi,
surface_tilt=tilt,
ground_albedo=albedo,
surface_pressure=pressure,
relative_airmass=relative_airmass,
precipitable_water=water_vapor_content,
ozone=ozone,
aerosol_turbidity_500nm=tau500,
)
plt.figure()
plt.plot(spectra['wavelength'], spectra['poa_global'])
plt.xlim(200, 2700)
# plt.ylim(0, 1.8)
plt.title(r"2021-11-30, Darmstadt, $\tau=0.1$, Wv=0.5 cm")
plt.ylabel(r"Irradiance ($W m^{-2} nm^{-1}$)")
plt.xlabel(r"Wavelength ($nm$)")
time_labels = times.strftime("%H:%M %p")
labels = [
"AM {:0.02f}, Z{:0.02f}, {}".format(*vals)
for vals in zip(relative_airmass, solpos.apparent_zenith, time_labels)
]
plt.legend(labels)
plt.show()
No, this is not expected behavior. I suspect the issue is caused by improper handling of angle-of-incidence values greater than 90 degrees, and essentially the same problem (for a different function) discussed here: https://github.com/pvlib/pvlib-python/issues/526
It's unfortunate that the reference implementation from NREL has the problem too (perhaps when the model was originally designed, nobody could conceive of a panel facing away from the sun!), but I think the pvlib implementation should be fixed regardless. I encourage you to file a bug report here: https://github.com/pvlib/pvlib-python/issues
In the meantime, I think you can resolve the issue in your own code by adding a line like aoi[aoi > 90] = 90 prior to passing it to spectrum.spectrl2, although be careful about this if you end up using aoi for other purposes later in the script. I would be interested to hear if the resulting spectra are consistent with your expectations.
Edit for posterity: a github issue has been opened here: https://github.com/pvlib/pvlib-python/issues/1348

Gekko - if3() statement for choosing between two expressions in ODE

I tried solving a differential equation having a logical condition in Gekko. I know that Gekko does not like these things but I supposed that simple if3() function in order to switch between the two given expressions (R1,R2) will get some solution. Here is a simple example code that failed - Solution not found.
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
A=1
B=1e-5
C=2
D=0.01
G=1
y0=120
m = GEKKO() # create GEKKO model
nt = 101
m.time = np.linspace(0,100,nt) # time points
y = m.Var(y0) # create GEKKO variable
R1 = m.Intermediate(-(y+A-A/(y/C+1)**(B/D))/G*(D*y+D*C))
R2 = m.Intermediate(-0.1*y)
z = m.Var() # This way - Solution not found
z = m.if3(y-60,R1,R2) #
m.Equation(y.dt()== z) #
#m.Equation(y.dt()== R1)
#m.Equation(y.dt()== R2)
# solve ODE
m.options.IMODE = 4
m.options.NODES = 5
m.solve(disp=False)
# plot results
plt.plot(m.time,y)
plt.xlabel('time')
plt.ylabel('y(t)')
Unfortunately, it seems I did not figure out yet how to overcome these problems by reading the article about Logical conditions in Optimization.
Best Regards,
Radovan
The posted script gives the error:
Exception: #error: Solution Not Found
To see additional details about the error, turn on the display with disp=True. This gives additional detail that indicates that the problem is infeasible.
Number of state variables: 2800
Number of total equations: - 2000
Number of slack variables: - 800
---------------------------------------
Degrees of freedom : 0
----------------------------------------------
Dynamic Simulation with APOPT Solver
----------------------------------------------
Iter: 1 I: -1 Tm: 13.07 NLPi: 9 Dpth: 0 Lvs: 0 Obj: 0.00E+00 Gap: NaN
Warning: no more possible trial points and no integer solution
Maximum iterations
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 13.116200000000001 sec
Objective : 0.
Unsuccessful with error code 0
---------------------------------------------------
Creating file: infeasibilities.txt
Use command apm_get(server,app,'infeasibilities.txt') to retrieve file
#error: Solution Not Found
A couple issues with the model:
z = m.Var() is not needed because the z = if3() function defines the variable.
IMODE=6 is needed because there are slack variables in the problem and an optimization mode is needed to solve the problem.
Try if2() instead of if3(). It seems to work better with the MPCC form than the Mixed Integer form.
Solver APOPT performs better for this problem. Try m.options.SOLVER=1.
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
A=1; B=1e-5; C=2; D=0.01; G=1
y0=120
m = GEKKO(remote=False) # create GEKKO model
nt = 101
m.time = np.linspace(0,50,nt) # time points
y = m.Var(y0) # create GEKKO variable
R1 = m.Intermediate(-(y+A-A/(y/C+1)**(B/D))/G*(D*y+D*C))
R2 = m.Intermediate(-0.1*y)
z = m.if2(y-60,0,1)
m.Equation(y.dt()== (1-z)*R1+z*R2)
# solve ODE
m.options.IMODE = 6
m.options.SOLVER = 1
m.options.NODES = 5
m.solve(disp=True)
# plot results
plt.subplot(2,1,1)
plt.plot(m.time,y)
plt.plot([0,50],[60,60],'r--')
plt.ylabel('y(t)'); plt.grid()
plt.subplot(2,1,2)
plt.plot(m.time,z)
plt.ylabel('z(t)'); plt.grid()
plt.xlabel('time')
plt.show()
The alternative to using an if statement in the model is to integrate in a loop and check the condition y>60 to switch to the other model.

PVLIB - DC Power From Irradiation - Simple Calculation

Dear pvlib users and devels.
I'm a researcher in computer science, not particularly expert in the simulation or modelling of solar panels. I'm interested in use pvlib since
we are trying to simulate the works of a small solar panel used for IoT
applications, in particular the panel spec are the following:
12.8% max efficiency, Vmp = 5.82V, size = 225 ร— 155 ร— 17 mm.
Before using pvlib, one of my collaborator wrote a code that compute the
irradiation directly from average monthly values calculated with PVWatt.
I was not really satisfied, so we are starting to use pvlib.
In the old code, we have the power and current of the panel calculated as:
W = Irradiation * PanelSize(m^2) * Efficiency
A = W / Vmp
The Irradiation, in Madrid, as been obtained with PVWatt, and this is
what my collaborator used:
DIrradiance = (2030.0,2960.0,4290.0,5110.0,5950.0,7090.0,7200.0,6340.0,4870.0,3130.0,2130.0,1700.0)
I'm trying to understand if pvlib compute values similar to the ones above, as averages over a day for each month. And the curve of production in day.
I wrote this to compare pvlib with our old model:
import math
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
import pvlib
from pvlib.location import Location
def irradiance(day,m):
DIrradiance =(2030.0,2960.0,4290.0,5110.0,5950.0,
7090.0,7200.0,6340.0,4870.0,3130.0,2130.0,1700.0)
madrid = Location(40.42, -3.70, 'Europe/Madrid', 600, 'Madrid')
times = pd.date_range(start=dt.datetime(2015,m,day,00,00),
end=dt.datetime(2015,m,day,23,59),
freq='60min')
spaout = pvlib.solarposition.spa_python(times, madrid.latitude, madrid.longitude)
spaout = spaout.assign(cosz=pd.Series(np.cos(np.deg2rad(spaout['zenith']))))
z = np.array(spaout['cosz'])
return z.clip(0)*(DIrradiance[m-1])
madrid = Location(40.42, -3.70, 'Europe/Madrid', 600, 'Madrid')
times = pd.date_range(start = dt.datetime(2015,8,15,00,00),
end = dt.datetime(2015,8,15,23,59),
freq='60min')
old = irradiance(15,8) # old model
new = madrid.get_clearsky(times) # pvlib irradiance
plt.plot(old,'r-') # compare them.
plt.plot(old/6.0,'y-') # old seems 6 times more..I do not know why
plt.plot(new['ghi'].values,'b-')
plt.show()
The code above compute the old irradiance, using the zenit angle. and compute the ghi values using the clear_sky. I do not understand if the values in ghi must be multiplied by the cos of zenit too, or not. Anyway
they are smaller by a factor of 6. What I'd like to have at the end is the
power and current in output from the panel (DC) without any inverter, and
we are not really interested at modelling it exactly, but at least, to
have a reasonable curve. We are able to capture from the panel the ampere
produced, and we want to compare the values from the measurements putting
the panel on the roof top with the values calculated by pvlib.
Any help on this would be really appreachiated. Thanks
Sorry Will I do not care a lot about my previous model since I'd like to move all code to pvlib. I followed your suggestion and I'm using irradiance.total_irrad, the code now looks in this way:
madrid = Location(40.42, -3.70, 'Europe/Madrid', 600, 'Madrid')
times = pd.date_range(start=dt.datetime(2015,1,1,00,00),
end=dt.datetime(2015,1,1,23,59),
freq='60min')
ephem_data = pvlib.solarposition.spa_python(times, madrid.latitude,
madrid.longitude)
irrad_data = madrid.get_clearsky(times)
AM = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
total = irradiance.total_irrad(40, 180,
ephem_data['apparent_zenith'], ephem_data['azimuth'],
dni=irrad_data['dni'], ghi=irrad_data['ghi'],
dhi=irrad_data['dhi'], airmass=AM,
surface_type='urban')
poa = total['poa_global'].values
Now, I know the irradiance on POA, and I want to compute the output in Ampere: It is just
(poa*PANEL_EFFICIENCY*AREA) / VOLT_OUTPUT ?
It's not clear to me how you arrived at your values for DIrradiance or what the units are, so I can't comment much the discrepancies between the values. I'm guessing that it's some kind of monthly data since there are 12 values. If so, you'd need to calculate ~hourly pvlib irradiance data and then integrate it to check for consistency.
If your module will be tilted, you'll need to convert your ~hourly irradiance GHI, DNI, DHI values to plane of array (POA) irradiance using a transposition model. The irradiance.total_irrad function is the easiest way to do that.
The next steps depend on the IV characteristics of your module, the rest of the circuit, and how accurate you need the model to be.

How is TF calculated in Sklearn

I have been experimenting with sklearn's Tfidfvectorizer.
I am only concerned with TF, and not idf, so my settings have use_idf = FALSE
Complete settings are:
vectorizer = TfidfVectorizer(max_df=0.5, max_features= n_features,
ngram_range=(1,3), use_idf=False)
I have been trying to replicate the output of .fit_transform but haven't managed to do it so far and was hoping someone could explain the calculations for me.
My toy example is:
document = ["one two three one four five",
"two six eight ten two"]
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
n_features = 5
vectorizer = TfidfVectorizer(max_df=0.5, max_features= n_features,
ngram_range=(1,3), use_idf=False)
X = vectorizer.fit_transform(document)
count = CountVectorizer(max_df=0.5, max_features= n_features,
ngram_range=(1,3))
countMat = count.fit_transform(document)
I have assumed the counts from the Count Vectorizer will be the same as the counts used int he Tfidf Vectorizer. So am trying to change the countMat object to match X.
I had missed a line from the documentation which says
Each row is normalized to have unit euclidean norm
So to anwer my own question - the answer is:
for i in xrange(countMat.toarray().__len__()):
row = countMat.toarray()[i]
row / np.sqrt(np.sum(row**2))
Although I am sure there is a more elegant way to code the result.