Rearranging Expression to a Standard Form for Transfer Function - function

I'm a newcomer to Python/Sympy and I'm hoping it can make life easier understanding control system topics. A common requirement for me is to cross-check equations developed in the literature against my own derivations. When it comes to transfer functions, the denominator is typically ordered with the higher orders of s on the left, with order decreasing moving to the right. The highest order s term has a unity coefficient.
Here's an example (taken from here):
I've developed my own transfer function using sympy and I'd like to rearrange it in the fashion just described.
import sympy as sp
from sympy import simplify
from IPython.display import display
s, tau_1, tau_2 = sp.symbols('s,tau_1,tau_2')
F = (1+s*tau_2)/(1+s*(tau_1+tau_2));
k_0, k_d, N = sp.symbols('k_0,k_d,N')
H = (k_0*k_d*F)/(s+((k_0*k_d*F/N)))
display(H.simplify())
Which yields:
Now, I'm not really expecting simplify to know which format I'd like the expression displayed, but I'm hoping there's an existing function or set of functions that will help me to arrange it the way I'd like. Is there?
FURTHER UPDATE:
After a bit of manipulation, I've managed to isolate the highest power and divide across by the coefficient top & bottom to leave the highest order term without a coefficient, as I wanted. It's not perfect by any stretch. An improvement would be to have each term stand alone and ordered highest to lowest as with most polynomial presentations. I notice that collect() doesn't order the power terms as you'd expect. What's that all about!?
import sympy as sp
from sympy import simplify
from sympy import poly
from sympy import degree
from IPython.display import display
s, tau_1, tau_2 = sp.symbols('s,tau_1,tau_2')
F = (1+s*tau_2)/(1+s*(tau_1+tau_2));
display(F)
k_0, k_d, N = sp.symbols('k_0,k_d,N')
H = (k_0*k_d*F)/(s+((k_0*k_d*F/N)))
display(H)
def normTF(expr):
H_c = expr.ratsimp().collect(s)
n,d=sp.fraction(H_c)
collected = sp.Poly(d, s).as_expr()
degree = sp.degree(collected, gen=s)
terms = dict(i.as_independent(s)[::-1] for i in sp.Add.make_args(collected))
sn=(n/terms[s**degree]).ratsimp().collect(s)
sd=(d/terms[s**degree]).ratsimp().collect(s)
return sn/sd
display(normTF(H))

Maybe this is what you want:
In [30]: H.cancel().collect(s)
Out[30]:
N⋅k₀⋅k_d⋅s⋅τ₂ + N⋅k₀⋅k_d
─────────────────────────────────────────────
2
k₀⋅k_d + s ⋅(N⋅τ₁ + N⋅τ₂) + s⋅(N + k₀⋅k_d⋅τ₂)

Related

Can gtsummary be used to predict an ordinal variable (several predictors of all kinds in one model), adjusted for confounding factors

i am trying to bulid a prediction model for an oridinal variable. I now that MASS:polr() function tragets this issue but i want to present it in a more approchable way. i thought gtsummary package may be sutiable
my code-
reg_tb<-tbl_uvregression(
reg_df,
include = c(a,b,c,d),
method = polr,
y = e,
exponentiate = TRUE,
pvalue_fun = ~style_pvalue(.x, digits = 2))
i now that tbl_uvregression() is a univariate model but under 'methods = ' i used the 'polr' option. i suspected polr can't be used in tbl_uvregression() to do an adjusted prediction model because after including 15 predictors, they all remained significant when runing the model (not reasonbele, several factors are strongly associated with each other).

How to find closest embedding vectors?

I have 100K known embedding i.e.
[emb_1, emb_2, ..., emb_100000]
Each of this embedding is derived from GPT-3 sentence embedding with dimension 2048.
My task is given an embedding(embedding_new) find the closest 10 embedding from the above 100k embedding.
The way I am approaching this problem is brute force.
Every time a query asks to find the closest embeddings, I compare embedding_new with [emb_1, emb_2, ..., emb_100000] and get the similarity score.
Then I do quicksort of the similarity score to get the top 10 closest embedding.
Alternatively, I have also thought about using Faiss.
Is there a better way to achieve this?
I found a solution using Vector Database Lite (VDBLITE)
VDBLITE here: https://pypi.org/project/vdblite/
import vdblite
from time import time
from uuid import uuid4
import sys
from pprint import pprint as pp
if __name__ == '__main__':
vdb = vdblite.Vdb()
dimension = 12 # dimensions of each vector
n = 200 # number of vectors
np.random.seed(1)
db_vectors = np.random.random((n, dimension)).astype('float32')
print(db_vectors[0])
for vector in db_vectors:
info = {'vector': vector, 'time': time(), 'uuid': str(uuid4())}
vdb.add(info)
vdb.details()
results = vdb.search(db_vectors[10])
pp(results)
Looks like it uses FAISS behind the scene.
Using you own idea, just make sure that the embeddings are in a matrix form, you can easily use numpy for this.
This is computed in linear time (in num. of embeddings) and should be fast.
import numpy as np
k = 10 # k best embeddings
emb_mat = np.stack([emb_1, emb_2, ..., emb_100000])
scores = np.dot(emb_mat, embedding_new)
best_k_ind = np.argpartition(scores, k)[-k:]
top_k_emb = emb_mat[best_k_ind]
The 10 best embeddings will be found in top_k_emb.
For a general solution inside a software project you might consider Faiss by Facebook Research.
An example for using Faiss:
d = 2048 # dimensionality of your embedding data
k = 10 # number of nearest neighbors to return
index = faiss.IndexFlatIP(d)
emb_list = [emb_1, emb_2, ..., emb_100000]
index.add(emb_list)
D, I = index.search(embedding_new, k)
You can use IndexFlatIP for inner product similarity, or indexFlatL2 for Euclidian\L2-norm distance.
In order to bypass memory issues (data>1M) refer to this great infographic Faiss cheat sheet at slide num. 7

Pretrained lightning-bolts VAE not doing proper inference on training dataset

I'm using the CIFAR-10 pre-trained VAE from lightning-bolts. It should be able to regenerate images with the quality shown on this picture taken from the docs (LHS are the real images, RHS are the generated)
However, when I write a simple script that loads the model, the weights, and tests it over the training set, I get a much worse reconstruction (top row are real images, bottom row are the generated ones):
Here is a link to a self-contained colab notebook that reproduces the steps I've followed to produce the pictures.
Am I doing something wrong on my inference process? Could it be that the weights are not as "good" as the docs claim?
Thanks!
First, the image from the docs you show is for the AE, not the VAE. The results for the VAE look much worse:
https://pl-bolts-weights.s3.us-east-2.amazonaws.com/vae/vae-cifar10/vae_output.png
Second, the docs state "Both input and generated images are normalized versions as the training was done with such images." So when you load the data you should specify normalize=True. When you plot your data, you will need to 'unnormalize' the data as well:
from pl_bolts.datamodules import CIFAR10DataModule
from pl_bolts.models.autoencoders import VAE
from pytorch_lightning import Trainer
import matplotlib.pyplot as plt
import numpy as np
import torch
from torchvision import transforms
torch.manual_seed(17)
np.random.seed(17)
vae = VAE(32, lr=0.00001)
vae = vae.from_pretrained("cifar10-resnet18")
dm = CIFAR10DataModule(".", normalize=True)
dm.prepare_data()
dm.setup("fit")
dataloader = dm.train_dataloader()
print(dm.default_transforms())
mean = torch.tensor(dm.default_transforms().transforms[1].mean)
std = torch.tensor(dm.default_transforms().transforms[1].std)
unnormalize = transforms.Normalize((-mean / std).tolist(), (1.0 / std).tolist())
X, _ = next(iter(dataloader))
vae.eval()
X_hat = vae(X)
fig, axes = plt.subplots(2, 10, figsize=(10, 2))
for i in range(10):
ax_real = axes[0][i]
ax_real.imshow(np.transpose(unnormalize(X[i]), (1, 2, 0)))
ax_real.get_xaxis().set_visible(False)
ax_real.get_yaxis().set_visible(False)
ax_gen = axes[1][i]
ax_gen.imshow(np.transpose(unnormalize(X_hat[i]).detach().numpy(), (1, 2, 0)))
ax_gen.get_xaxis().set_visible(False)
ax_gen.get_yaxis().set_visible(False)
Which gives something like this:
Without normalization it looks like:

Computing cosine_proximity loss between two outputs of the network

I'm using Keras 2.0.2 Functional API (Tensorflow 1.0.1) to implement a network that takes several inputs and produces two outputs a and b. I need to train the network using the cosine_proximity loss, such that b is the label for a. How do I do this?
Sharing my code here. The last line model.fit(..) is the problematic part because I don't have labeled data per se. The label is produced by the model itself.
from keras.models import Model
from keras.layers import Input, LSTM
from keras import losses
shared_lstm = LSTM(dim)
q1 = Input(shape=(..,.. ), name='q1')
q2 = Input(shape=(..,.. ), name='q2')
a = shared_lstm(q1)
b = shared_lstm(q2)
model = Model(inputs=[q1,q2], outputs=[a, b])
model.compile(optimizer='adam', loss=losses.cosine_proximity)
model.fit([testq1, testq2], [?????])
You can define a fake true label first. For example, define it as a 1-D array of ones of the size of your input data.
Now comes the loss function. You can write it as follows.
def my_cosine_proximity(y_true, y_pred):
a = y_pred[0]
b = y_pred[1]
# depends on whether you want to normalize
a = K.l2_normalize(a, axis=-1)
b = K.l2_normalize(b, axis=-1)
return -K.mean(a * b, axis=-1) + 0 * y_true
I have multiplied y_true by zero and added it just so that Theano does give not missing input warning/error.
You should call your fit function normally i.e. by including your fake ground-truth labels.
model.compile('adam', my_cosine_proximity) # 'adam' used as an example optimizer
model.fit([testq1, testq2], fake_y_true)

Solving Kepler's Equation computationally

I'm trying to solve Kepler's Equation as a step towards finding the true anomaly of an orbiting body given time. It turns out though, that Kepler's equation is difficult to solve, and the wikipedia page describes the process using calculus. Well, I don't know calculus, but I understand that solving the equation involves an infinite number of sets which produce closer and closer approximations to the correct answer.
I can't see from looking at the math how to do this computationally, so I was hoping someone with a better maths background could help me out. How can I solve this beast computationally?
FWIW, I'm using F# -- and I can calculate the other elements necessary for this equation, it's just this part I'm having trouble with.
I'm also open to methods which approximate the true anomaly given time, periapsis distance, and eccentricity
This paper:
A Practical Method for Solving the Kepler Equation http://murison.alpheratz.net/dynamics/twobody/KeplerIterations_summary.pdf
shows how to solve Kepler's equation using an iterative computing method. It should be fairly straightforward to translate it to the language of your choice.
You might also find this interesting. It's an ocaml program, part of which claims to contain a Kepler Equation solver. Since F# is in the ML family of languages (as is ocaml), this might provide a good starting point.
wanted to drop a reply in here in case this page gets found by anyone else looking for similar materials.
The following was written as an "expression" in Adobe's After Effects software, so it's javascriptish, although I have a Python version for a different app (cinema 4d). The idea is the same: execute Newton's method iteratively until some arbitrary precision is reached.
Please note that I'm not posting this code as exemplary or meaningfully efficient in any way, just posting code we produced on a deadline to accomplish a specific task (namely, move a planet around a focus according to Kepler's laws, and do so accurately). We don't write code for a living, and so we're also not posting this for critique. Quick & dirty is what meets deadlines.
In After Effects, any "expression" code is executed once - for every single frame in the animation. This restricts what one can do when implementing many algorithms, due to the inability to address global data easily (other algorithms for Keplerian motion use interatively updated velocity vectors, an approach we couldn't use). The result the code leaves behind is the [x,y] position of the object at that instant in time (internally, this is the frame number), and the code is intended to be attached to the position element of an object layer on the timeline.
This code evolved out of material found at http://www.jgiesen.de/kepler/kepler.html, and is offered here for the next guy.
pi = Math.PI;
function EccAnom(ec,am,dp,_maxiter) {
// ec=eccentricity, am=mean anomaly,
// dp=number of decimal places
pi=Math.PI;
i=0;
delta=Math.pow(10,-dp);
var E, F;
// some attempt to optimize prediction
if (ec<0.8) {
E=am;
} else {
E= am + Math.sin(am);
}
F = E - ec*Math.sin(E) - am;
while ((Math.abs(F)>delta) && (i<_maxiter)) {
E = E - F/(1.0-(ec* Math.cos(E) ));
F = E - ec * Math.sin(E) - am;
i = i + 1;
}
return Math.round(E*Math.pow(10,dp))/Math.pow(10,dp);
}
function TrueAnom(ec,E,dp) {
S=Math.sin(E);
C=Math.cos(E);
fak=Math.sqrt(1.0-ec^2);
phi = 2.0 * Math.atan(Math.sqrt((1.0+ec)/(1.0-ec))*Math.tan(E/2.0));
return Math.round(phi*Math.pow(10,dp))/Math.pow(10,dp);
}
function MeanAnom(time,_period) {
curr_frame = timeToFrames(time);
if (curr_frame <= _period) {
frames_done = curr_frame;
if (frames_done < 1) frames_done = 1;
} else {
frames_done = curr_frame % _period;
}
_fractime = (frames_done * 1.0 ) / _period;
mean_temp = (2.0*Math.PI) * (-1.0 * _fractime);
return mean_temp;
}
//==============================
// a=semimajor axis, ec=eccentricity, E=eccentric anomaly
// delta = delta digits to exit, period = per., in frames
//----------------------------------------------------------
_eccen = 0.9;
_delta = 14;
_maxiter = 1000;
_period = 300;
_semi_a = 70.0;
_semi_b = _semi_a * Math.sqrt(1.0-_eccen^2);
_meananom = MeanAnom(time,_period);
_eccentricanomaly = EccAnom(_eccen,_meananom,_delta,_maxiter);
_trueanomaly = TrueAnom(_eccen,_eccentricanomaly,_delta);
r = _semi_a * (1.0 - _eccen^2) / (1.0 + (_eccen*Math.cos(_trueanomaly)));
x = r * Math.cos(_trueanomaly);
y = r * Math.sin(_trueanomaly);
_foc=_semi_a*_eccen;
[1460+x+_foc,540+y];
You could check this out, implemented in C# by Carl Johansen
Represents a body in elliptical orbit about a massive central body
Here is a comment from the code
True Anomaly in this context is the
angle between the body and the sun.
For elliptical orbits, it's a bit
tricky. The percentage of the period
completed is still a key input, but we
also need to apply Kepler's
equation (based on the eccentricity)
to ensure that we sweep out equal
areas in equal times. This
equation is transcendental (ie can't
be solved algebraically) so we
either have to use an approximating
equation or solve by a numeric method.
My implementation uses
Newton-Raphson iteration to get an
excellent approximate answer (usually
in 2 or 3 iterations).