PresentationΒΆ
First damper datasetΒΆ
Import damper dyno data:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('datasets/dyno/Dempari-Ullman.csv', sep=';', decimal=",")
column_names = list(df)
Plot all variables, using the Pyplot tutorial:
plt.figure()
for i in column_names:
plt.plot(df[column_names[0]],df[i])
plt.title("Ullman damper")
plt.xlabel(column_names[0])
plt.ylabel(i)
plt.show()
See the force as a function of the damper's position:
time = df[column_names[0]]
position = df[column_names[7]]
force = df[column_names[8]]
plt.plot(position,force)
plt.title("Ullman damper")
plt.xlabel(column_names[7])
plt.ylabel(column_names[8])
plt.show()
Now we can calculate the velocity by integrating the position:
velocity = []
for i in range(1, len(time)-1):
v = (position[i+1]-position[i-1])/(time[i+1]-time[i-1])
velocity = velocity + [v]
# print(len(time))
# print(velocity)
plt.plot(velocity,force[1:len(force)-1])
plt.title("Ullman damper")
plt.xlabel("Velocity [mm/s]")
plt.ylabel(column_names[8])
Text(0, 0.5, 'Load(8503:Load) (kN)')
Now I see that this is the wrong dataset. This is a test done on a very low speed Instron universal testing machine, not on a damper dynamometer. So it doesn't give useful info.
Second damper datasetΒΆ
Let's try importing better data (with help from Stack Overflow and I saved the data to a v7 version of a mat file from MATLAB, as suggested here):
# Source - https://stackoverflow.com/a
# Posted by Gilad Naor, modified by community. See post 'Timeline' for change history
# Retrieved 2025-12-11, License - CC BY-SA 4.0
import scipy.io as scio
ullman = scio.loadmat('datasets/dyno/python_ullman.mat')
ullman.keys()
# print(ullman['a'])
# print(ullman.values())
# print(ullman.items())
dict_keys(['__header__', '__version__', '__globals__', 'a'])
I can load the .mat file. Let's look at the header:
ullman['__header__']
b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Thu Dec 11 09:23:40 2025'
ullman['__version__']
'1.0'
ullman['__globals__']
[]
The variable that I saved as a MATLAB .mat file was called a. Let's have a look at it:
ullman['a']
array([[(array([[(array(['C:\\Users\\svava\\Documents\\CTW Automation\\Data\\SAFESeat1-Ullman.dctw'],
dtype='<U66'), array([[(array([[(array(['Notes'], dtype='<U5'), array([], dtype='<U1'), array(['Notes : Ullman dynamics damper from Ullman Biscaya seat. Unknown adjustment. There seems to be an adjustment screw.'],
dtype='<U115')) ]],
dtype=[('Name', 'O'), ('Description', 'O'), ('Value', 'O')]), array([[(array(['Amplitude'], dtype='<U9'), array(['mm'], dtype='<U2'), array([[25.02304691]]))],
[(array(['RodForce'], dtype='<U8'), array(['N'], dtype='<U1'), array([[166.04866452]]))],
[(array(['SampleFrequency'], dtype='<U15'), array(['Hz'], dtype='<U2'), array([[1000]], dtype=uint16))],
[(array(['Speed'], dtype='<U5'), array(['m/s'], dtype='<U3'), array([[0.6]]))],
[(array(['Stroke'], dtype='<U6'), array(['mm'], dtype='<U2'), array([[50.04609382]]))],
[(array(['RodDiameter'], dtype='<U11'), array(['mm'], dtype='<U2'), array([[16.]]))],
[(array(['RodForceReboundReading'], dtype='<U22'), array(['N'], dtype='<U1'), array([[157.22724199]]))],
[(array(['Frequency'], dtype='<U9'), array(['Hz'], dtype='<U2'), array([[3.81620057]]))],
[(array(['RodForceCompressionReading'], dtype='<U26'), array(['N'], dtype='<U1'), array([[174.87008706]]))],
[(array(['GasPressure'], dtype='<U11'), array(['bar'], dtype='<U3'), array([[8.25858306]]))]],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')]), array([[(array(['Displacement'], dtype='<U12'), array(['mm'], dtype='<U2'), array([[-7.86976738, -7.86999614, -7.87182926, ..., 24.33937498,
24.21426138, 24.07536487]], shape=(1, 45548))) ],
[(array(['Force'], dtype='<U5'), array(['N'], dtype='<U1'), array([[-136.48410812, -136.4807845 , -136.45690685, ..., 91.31654695,
77.52026951, 64.22820974]], shape=(1, 45548))) ],
[(array(['Temperature'], dtype='<U11'), array(['C'], dtype='<U1'), array([[30.02929688, 30.02929688, 29.9987793 , ..., 30.79223633,
30.85327148, 30.79223633]], shape=(1, 45548))) ],
[(array(['Velocity'], dtype='<U8'), array(['m/s'], dtype='<U3'), array([[3.13236326e-05, 6.23623033e-04, 3.65981696e-03, ...,
7.96180025e-02, 8.00163916e-02, 1.41805509e-01]], shape=(1, 45548))) ],
[(array(['Time'], dtype='<U4'), array(['s'], dtype='<U1'), array([[0.0000e+00, 1.0000e-03, 2.0000e-03, ..., 4.5545e+01, 4.5546e+01,
4.5547e+01]], shape=(1, 45548))) ]],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])) ]],
dtype=[('fields', 'O'), ('constants', 'O'), ('signals', 'O')])) ]],
dtype=[('File', 'O'), ('Data', 'O')]),) ]],
dtype=[('files', 'O')])
This data structure is really annoying. I need to dig deep into it to find the actual data.
ullman['a'][0][0][0][0][0][0][0][0]
'C'
OK, now I'm finally getting somewhere:
ullman['a'][0][0][0][0][0][1][0][0][1]
array([[(array(['Amplitude'], dtype='<U9'), array(['mm'], dtype='<U2'), array([[25.02304691]]))],
[(array(['RodForce'], dtype='<U8'), array(['N'], dtype='<U1'), array([[166.04866452]]))],
[(array(['SampleFrequency'], dtype='<U15'), array(['Hz'], dtype='<U2'), array([[1000]], dtype=uint16))],
[(array(['Speed'], dtype='<U5'), array(['m/s'], dtype='<U3'), array([[0.6]]))],
[(array(['Stroke'], dtype='<U6'), array(['mm'], dtype='<U2'), array([[50.04609382]]))],
[(array(['RodDiameter'], dtype='<U11'), array(['mm'], dtype='<U2'), array([[16.]]))],
[(array(['RodForceReboundReading'], dtype='<U22'), array(['N'], dtype='<U1'), array([[157.22724199]]))],
[(array(['Frequency'], dtype='<U9'), array(['Hz'], dtype='<U2'), array([[3.81620057]]))],
[(array(['RodForceCompressionReading'], dtype='<U26'), array(['N'], dtype='<U1'), array([[174.87008706]]))],
[(array(['GasPressure'], dtype='<U11'), array(['bar'], dtype='<U3'), array([[8.25858306]]))]],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
Let's try to get at the Amplitude data:
ullman['a'][0][0][0][0][0][1][0][0][1][0]
array([(array(['Amplitude'], dtype='<U9'), array(['mm'], dtype='<U2'), array([[25.02304691]]))],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
ullman['a'][0][0][0][0][0][1][0][0][1][0][0]
np.void((array(['Amplitude'], dtype='<U9'), array(['mm'], dtype='<U2'), array([[25.02304691]])), dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
Here's the title 'Amplitude':
ullman['a'][0][0][0][0][0][1][0][0][1][0][0][0]
array(['Amplitude'], dtype='<U9')
And here's the actual number:
ullman['a'][0][0][0][0][0][1][0][0][1][0][0][2]
array([[25.02304691]])
Finally, a number! Let's try to get at the timeseries:
ullman['a'][0][0][0][0][0][1][0][0][2]
array([[(array(['Displacement'], dtype='<U12'), array(['mm'], dtype='<U2'), array([[-7.86976738, -7.86999614, -7.87182926, ..., 24.33937498,
24.21426138, 24.07536487]], shape=(1, 45548))) ],
[(array(['Force'], dtype='<U5'), array(['N'], dtype='<U1'), array([[-136.48410812, -136.4807845 , -136.45690685, ..., 91.31654695,
77.52026951, 64.22820974]], shape=(1, 45548))) ],
[(array(['Temperature'], dtype='<U11'), array(['C'], dtype='<U1'), array([[30.02929688, 30.02929688, 29.9987793 , ..., 30.79223633,
30.85327148, 30.79223633]], shape=(1, 45548))) ],
[(array(['Velocity'], dtype='<U8'), array(['m/s'], dtype='<U3'), array([[3.13236326e-05, 6.23623033e-04, 3.65981696e-03, ...,
7.96180025e-02, 8.00163916e-02, 1.41805509e-01]], shape=(1, 45548))) ],
[(array(['Time'], dtype='<U4'), array(['s'], dtype='<U1'), array([[0.0000e+00, 1.0000e-03, 2.0000e-03, ..., 4.5545e+01, 4.5546e+01,
4.5547e+01]], shape=(1, 45548))) ]],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
ullman_displacement_name = ullman['a'][0][0][0][0][0][1][0][0][2][0][0][0][0]
ullman_displacement_unit = ullman['a'][0][0][0][0][0][1][0][0][2][0][0][1][0]
ullman_displacement = ullman['a'][0][0][0][0][0][1][0][0][2][0][0][2][0][11500:]
ullman['a'][0][0][0][0][0][1][0][0][2][1]
array([(array(['Force'], dtype='<U5'), array(['N'], dtype='<U1'), array([[-136.48410812, -136.4807845 , -136.45690685, ..., 91.31654695,
77.52026951, 64.22820974]], shape=(1, 45548))) ],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
ullman_force_name = ullman['a'][0][0][0][0][0][1][0][0][2][1][0][0][0]
ullman_force_unit = ullman['a'][0][0][0][0][0][1][0][0][2][1][0][1][0]
ullman_force = ullman['a'][0][0][0][0][0][1][0][0][2][1][0][2][0][11500:]
Force vs. displacement (football plot)ΒΆ
plt.plot(ullman_displacement,ullman_force)
plt.xlabel(ullman_displacement_name + ' [' + ullman_displacement_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
import numpy as np
k = np.polyfit(ullman_displacement, ullman_force,1)
print(k[1])
k_eval = np.poly1d(k)
plt.plot(ullman_displacement,k_eval(ullman_displacement),color='red')
plt.text(15,-460,'k = ' + str(round(k[1])) + ' N/mm',color='red')
plt.plot(ullman_displacement,ullman_force)
plt.title("Linear fit to find the stiffness due to the nitrogen charge")
plt.xlabel(ullman_displacement_name + ' [' + ullman_displacement_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
185.5948566809324
ullman['a'][0][0][0][0][0][1][0][0][2][1]
array([(array(['Force'], dtype='<U5'), array(['N'], dtype='<U1'), array([[-136.48410812, -136.4807845 , -136.45690685, ..., 91.31654695,
77.52026951, 64.22820974]], shape=(1, 45548))) ],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
Now I need to find the velocity timeseries:
ullman['a'][0][0][0][0][0][1][0][0][2][3]
array([(array(['Velocity'], dtype='<U8'), array(['m/s'], dtype='<U3'), array([[3.13236326e-05, 6.23623033e-04, 3.65981696e-03, ...,
7.96180025e-02, 8.00163916e-02, 1.41805509e-01]], shape=(1, 45548))) ],
dtype=[('Name', 'O'), ('Units', 'O'), ('Value', 'O')])
ullman_velocity_name = ullman['a'][0][0][0][0][0][1][0][0][2][3][0][0][0]
ullman_velocity_unit = ullman['a'][0][0][0][0][0][1][0][0][2][3][0][1][0]
ullman_velocity = ullman['a'][0][0][0][0][0][1][0][0][2][3][0][2][0][11500:]
I also want to plot the raw data and for that I need the time:
ullman_time_name = ullman['a'][0][0][0][0][0][1][0][0][2][4][0][0][0]
print(ullman_time_name)
Time
ullman_time_unit = ullman['a'][0][0][0][0][0][1][0][0][2][4][0][1][0]
ullman_time = ullman['a'][0][0][0][0][0][1][0][0][2][4][0][2][0][11500:]
Raw data plotsΒΆ
plt.subplot(3,1,1)
plt.plot(ullman_time,ullman_displacement)
plt.ylabel(ullman_displacement_name)
plt.subplot(3,1,2)
plt.plot(ullman_time,ullman_velocity)
plt.ylabel(ullman_velocity_name)
plt.subplot(3,1,3)
plt.plot(ullman_time,ullman_force)
plt.xlabel(ullman_time_name)
plt.ylabel(ullman_force_name)
plt.show()
Force vs. velocityΒΆ
plt.plot(ullman_velocity,ullman_force)
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
Velocity peaksΒΆ
In order to construct a PVP plot (peak velocity vs. peak force), I need to find the velocity peaks. I can use scipy.signal.find_peaks to do that:
import scipy.signal as signal
ullman_velocity_peaks_positive = signal.find_peaks(ullman_velocity, prominence=0.2)
# print(ullman_velocity_peaks_positive)
ullman_velocity_peaks_negative = signal.find_peaks(-ullman_velocity, prominence=0.2)
# ullman_velocity_peaks_negative2 = -1*ullman_velocity_peaks_negative
# print(ullman_velocity_peaks_negative2)
ullman_velocity_peaks = [ullman_velocity_peaks_negative, ullman_velocity_peaks_positive]
# print(ullman_velocity_peaks)
#print(ullman_velocity_peaks)
plt.plot(ullman_velocity,ullman_force)
plt.scatter(ullman_velocity[ullman_velocity_peaks_negative[0]], ullman_force[ullman_velocity_peaks_negative[0]],color = 'red')
plt.scatter(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],color = 'lime')
plt.title("Velocity peaks found using scipy.signal.find_peaks")
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
Damping curve (PVP plot)ΒΆ
If I plot only the velocity peaks, I get the damping curve of the damper (the PVP plot):
plt.scatter(ullman_velocity[ullman_velocity_peaks_negative[0]], ullman_force[ullman_velocity_peaks_negative[0]],color = 'red')
plt.scatdata:image/png;base64,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RUWFHnroIaWlpSkiIkJdunTRX//6V+82ZeB3119/venevbvZtGmT2bRpk+nevbsZPnz4OV/z2WefmQ4dOpj777/ffPTRR2b//v3mX//6lzly5Iifug6cxsxXjbVr15rLL7/cJCUlmWeeeca3jQYJT+frxIkTZvDgwWblypXm448/Nps3bzZ9+/Y1vXv39mPX/rFixQrTsmVL8/zzz5s9e/aYnJwc06ZNG/Pll1/WWf/555+b1q1bm5ycHLNnzx7z/PPPm5YtW5rVq1f7ufPA8XTOcnJyzBNPPGE++OADs2/fPjNz5kzTsmVL89FHH/m588DwdL5qnDhxwlx44YVmyJAh5vLLL/dPs0GgMfM1YsQI07dvX5Ofn28OHDhg3n//ffPee+95tS/CkZ/t2bPHSDL/+c9/HGObN282kszHH39c7+vGjBljbr/9dn+0GFQaO1/GGFNUVGSSk5PNrl27TFpaWrMIR+czX84++OADI6nB/6CHmp/85CdmwoQJLmOXXHKJefDBB+usnzFjhrnkkktcxu69915z1VVX+azHYOPpnNWlW7du5pFHHvF2a0GpsfM1ZswY89vf/tY8/PDDzSoceTpfb775pomJiTHHjh3zaV8cVvOzzZs3KyYmRn379nWMXXXVVYqJidGmTZvqfE1VVZVef/11XXzxxRo6dKg6deqkvn376pVXXvFT14HTmPmSqucsKytL999/v3784x/7o9Wg0Nj5OltpaaksFovatWvngy4Do7KyUlu3btWQIUNcxocMGVLv3GzevLlW/dChQ/Xhhx/qzJkzPus1WDRmzs5WVVWl8vJydejQwRctBpXGztfSpUu1f/9+Pfzww75uMag0Zr5ee+019enTR3PnzlVycrIuvvhiTZ8+XadPn/Zqb4QjPyspKVGnTp1qjXfq1EklJSV1vubo0aM6efKkHn/8cV1//fVat26dbrrpJtlsNm3YsMHXLQdUY+ZLkp544gmFhYVpypQpvmwv6DR2vpx99913evDBBzV27NgmdWPMr7/+Wna7XfHx8S7j8fHx9c5NSUlJnfXff/+9vv76a5/1GiwaM2dne/rpp3Xq1CmNHj3aFy0GlcbM16effqoHH3xQf//73xUW1rzuBd+Y+fr888+1ceNG7dq1S2vXrtX8+fO1evVqTZo0yau9EY68ZNasWbJYLOd8fPjhh5Iki8VS6/XGmDrHpep/eUnSyJEj9etf/1o9e/bUgw8+qOHDh4fsyaG+nK+tW7dqwYIFWrZsWb01ocaX8+XszJkzuvXWW1VVVaVFixZ5/XMEg7PnoaG5qau+rvGmzNM5q7F8+XLNmjVLK1eurDO0N1XuzpfdbtfYsWP1yCOP6OKLL/ZXe0HHkz9fVVVVslgs+vvf/66f/OQn+vnPf6558+Zp2bJlXt171Lxiqg/dd999uvXWW89Zk56erh07dujIkSO1tn311Ve10nONuLg4hYWFqVu3bi7jl156qTZu3Nj4pgPIl/NVUFCgo0eP6oILLnCM2e12TZs2TfPnz9cXX3xxXr0Hgi/nq8aZM2c0evRoHThwQO+8806T2mskVf89slqttf5FevTo0XrnJiEhoc76sLAwxcbG+qzXYNGYOauxcuVKjR8/XqtWrdLgwYN92WbQ8HS+ysvL9eGHH2rbtm267777JFV/+RtjFBYWpnXr1unaa6/1S++B0Jg/X4mJiUpOTlZMTIxj7NJLL5UxRkVFReratatXeiMceUlcXJzi4uIarOvXr59KS0v1wQcf6Cc/+Ykk6f3331dpaamuvvrqOl8THh6uK6+8Up988onL+L59+5SWlnb+zQeAL+crKyur1n+Mhw4dqqysLN11113n33wA+HK+pB+C0aeffqp33323SX7xh4eHq3fv3srPz9dNN93kGM/Pz9fIkSPrfE2/fv30z3/+02Vs3bp16tOnj1q2bOnTfoNBY+ZMqt5j9Itf/ELLly/XsGHD/NFqUPB0vqKjo7Vz506XsUWLFumdd97R6tWr1blzZ5/3HEiN+fPVv39/rVq1SidPnlTbtm0lVX8XtmjRQikpKd5rzqene6NO119/venRo4fZvHmz2bx5s7nssstqXWr9ox/9yOTl5Tme5+XlmZYtW5olS5aYTz/91CxcuNBYrVZTUFDg7/b9rjHzdbbmcrWaMZ7P15kzZ8yIESNMSkqK2b59uykuLnY8KioqAvERfKbmsuEXXnjB7Nmzx+Tm5po2bdqYL774whhjzIMPPmiysrIc9TWX8v/61782e/bsMS+88EKzvZTf3Tl7+eWXTVhYmPnjH//o8mfpxIkTgfoIfuXpfJ2tuV2t5ul8lZeXm5SUFDNq1Cize/dus2HDBtO1a1fzy1/+0qt9EY4C4NixY2bcuHEmKirKREVFmXHjxpnjx4+71EgyS5cudRl74YUXzEUXXWRatWplLr/8cvPKK6/4r+kAaux8OWtO4cjT+Tpw4ICRVOfj3Xff9Xv/vvbHP/7RpKWlmfDwcHPFFVeYDRs2OLbdeeedZuDAgS7169evN7169TLh4eEmPT3dLF682M8dB54nczZw4MA6/yzdeeed/m88QDz9M+asuYUjYzyfr71795rBgwebyMhIk5KSYqZOnWq+/fZbr/ZkMea/ZxcCAACAq9UAAACcEY4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4ABK309HTNnz8/aN/P+X0tFossFotOnDjh9fc/l5qf265dO7/+XKApIxwB8Lobbrih3juxb968WRaLRR999JGfu5K2bNmie+65x/HcYrHolVde8cp7P/rooyouLna5W/j5yMzM1J/+9KcG64qLi30S+IDmjHAEwOvGjx+vd955R19++WWtbX/961/Vs2dPXXHFFX7vq2PHjmrdurVP3jsqKkoJCQmyWCzn/V7ffPONNm3apBtuuKHB2oSEBK8FMgDVCEcAvG748OHq1KmTli1b5jL+7bffauXKlRo/frwkadOmTRowYIAiIyOVmpqqKVOm6NSpU/W+78GDBzVy5Ei1bdtW0dHRGj16tI4cOeJS89prr6lPnz5q1aqV4uLiZLPZHNucD6ulp6dLkm666SZZLBalp6friy++UIsWLfThhx+6vOfChQuVlpYmT25FuWzZMrVr107/+te/9KMf/UitW7fWqFGjdOrUKb344otKT09X+/btNXnyZNntdpfXvv7667r88suVnJys48ePa9y4cerYsaMiIyPVtWtXLV261O0+AHiOcATA68LCwnTHHXdo2bJlLoFi1apVqqys1Lhx47Rz504NHTpUNptNO3bs0MqVK7Vx40bdd999db6nMUY33nijvvnmG23YsEH5+fnav3+/xowZ46h5/fXXZbPZNGzYMG3btk1vv/22+vTpU+f7bdmyRZK0dOlSFRcXa8uWLUpPT9fgwYNrhY+lS5cqOzvb471C3377rZ599lmtWLFC//d//6f169fLZrPpjTfe0BtvvKGXXnpJS5Ys0erVq11e99prr2nkyJGSpN/97nfas2eP3nzzTe3du1eLFy9WXFycR30A8JABAB/Yu3evkWTeeecdx9iAAQPMbbfdZowxJisry9xzzz0urykoKDAtWrQwp0+fNsYYk5aWZp555hljjDHr1q0zVqvVHDx40FG/e/duI8l88MEHxhhj+vXrZ8aNG1dvT87vZ4wxkszatWtdalauXGnat29vvvvuO2OMMdu3bzcWi8UcOHDA7fc1xpilS5caSeazzz5zjN17772mdevWpry83DE2dOhQc++99zqef/fddyYqKsrs2LHDGGPMDTfcYO666656f3bNz4qJiTlnDQD3secIgE9ccskluvrqq/XXv/5VkrR//34VFBToF7/4hSRp69atWrZsmdq2bet4DB06VFVVVTpw4ECt99u7d69SU1OVmprqGOvWrZvatWunvXv3SpK2b9+uQYMGnVffN954o8LCwrR27VpJ1edIXXPNNY7DcJ5o3bq1unTp4ngeHx+v9PR0tW3b1mXs6NGjjufvvPOOYmNjddlll0mSfvWrX2nFihXq2bOnZsyYoU2bNjXykwFwF+EIgM+MHz9ea9asUVlZmZYuXaq0tDRHeKmqqtK9996r7du3Ox7/7//9P3366acugaKGMabOw1rO45GRkefdc3h4uLKysrR06VJVVlbq5ZdfdgQ6T7Vs2dLlucViqXOsqqrK8dz5kJok/exnP9OXX36p3NxcHT58WIMGDdL06dMb1Q8A9xCOAPjM6NGjZbVa9fLLL+vFF1/UXXfd5QgyV1xxhXbv3q2LLrqo1iM8PLzWe3Xr1k0HDx5UYWGhY2zPnj0qLS3VpZdeKknq0aOH3n77bbf7a9myZa2ToSXpl7/8pd566y0tWrRIZ86ccTmp25eMMfrnP/+pESNGuIx37NhR2dnZ+tvf/qb58+dryZIlfukHaK4IRwB8pm3bthozZox+85vf6PDhw8rOznZse+CBB7R582ZNmjRJ27dv16effqrXXntNkydPrvO9Bg8erB49emjcuHH66KOP9MEHH+iOO+7QwIEDHSddP/zww1q+fLkefvhh7d27Vzt37tTcuXPr7S89PV1vv/22SkpKdPz4ccf4pZdeqquuukoPPPCAbrvtNq/skXLH1q1bderUKQ0YMMAx9vvf/16vvvqqPvvsM+3evVv/+te/HGEQgG8QjgD41Pjx43X8+HENHjxYF1xwgWO8R48e2rBhgz799FNlZGSoV69e+t3vfqfExMQ636dmwcb27dtrwIABGjx4sC688EKtXLnSUZOZmalVq1bptddeU8+ePXXttdfq/fffr7e3p59+Wvn5+UpNTVWvXr1q9V1ZWdnoQ2qN8eqrr2rYsGEKCwtzjIWHh2vmzJnq0aOHBgwYIKvVqhUrVvitJ6A5shjjwcIdANBMPPbYY1qxYoV27tzZYG16erpyc3OVm5t7Xj+zR48e+u1vf6vRo0d79Lply5YpNzfX77cuAZoq9hwBgJOTJ09qy5YtWrhwoaZMmeL26x544AG1bdtWpaWljfq5lZWVuvnmm/Wzn/3Mo9e1bdtWEyZMaNTPBFA39hwBgJPs7GwtX75cN954o15++WVZrdYGX/Pll1/qzJkzkqQLL7xQLVr479+dn332mSTJarWqc+fOfvu5QFNGOAIAAHDCYTUAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAn/x8EG9toe1Fr/QAAAABJRU5ErkJggg==ter(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],color = 'lime')
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
Cell In[33], line 2 plt.scatdata:image/png;base64,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RUWFHnroIaWlpSkiIkJdunTRX//6V+82ZeB3119/venevbvZtGmT2bRpk+nevbsZPnz4OV/z2WefmQ4dOpj777/ffPTRR2b//v3mX//6lzly5Iifug6cxsxXjbVr15rLL7/cJCUlmWeeeca3jQYJT+frxIkTZvDgwWblypXm448/Nps3bzZ9+/Y1vXv39mPX/rFixQrTsmVL8/zzz5s9e/aYnJwc06ZNG/Pll1/WWf/555+b1q1bm5ycHLNnzx7z/PPPm5YtW5rVq1f7ufPA8XTOcnJyzBNPPGE++OADs2/fPjNz5kzTsmVL89FHH/m588DwdL5qnDhxwlx44YVmyJAh5vLLL/dPs0GgMfM1YsQI07dvX5Ofn28OHDhg3n//ffPee+95tS/CkZ/t2bPHSDL/+c9/HGObN282kszHH39c7+vGjBljbr/9dn+0GFQaO1/GGFNUVGSSk5PNrl27TFpaWrMIR+czX84++OADI6nB/6CHmp/85CdmwoQJLmOXXHKJefDBB+usnzFjhrnkkktcxu69915z1VVX+azHYOPpnNWlW7du5pFHHvF2a0GpsfM1ZswY89vf/tY8/PDDzSoceTpfb775pomJiTHHjh3zaV8cVvOzzZs3KyYmRn379nWMXXXVVYqJidGmTZvqfE1VVZVef/11XXzxxRo6dKg6deqkvn376pVXXvFT14HTmPmSqucsKytL999/v3784x/7o9Wg0Nj5OltpaaksFovatWvngy4Do7KyUlu3btWQIUNcxocMGVLv3GzevLlW/dChQ/Xhhx/qzJkzPus1WDRmzs5WVVWl8vJydejQwRctBpXGztfSpUu1f/9+Pfzww75uMag0Zr5ee+019enTR3PnzlVycrIuvvhiTZ8+XadPn/Zqb4QjPyspKVGnTp1qjXfq1EklJSV1vubo0aM6efKkHn/8cV1//fVat26dbrrpJtlsNm3YsMHXLQdUY+ZLkp544gmFhYVpypQpvmwv6DR2vpx99913evDBBzV27NgmdWPMr7/+Wna7XfHx8S7j8fHx9c5NSUlJnfXff/+9vv76a5/1GiwaM2dne/rpp3Xq1CmNHj3aFy0GlcbM16effqoHH3xQf//73xUW1rzuBd+Y+fr888+1ceNG7dq1S2vXrtX8+fO1evVqTZo0yau9EY68ZNasWbJYLOd8fPjhh5Iki8VS6/XGmDrHpep/eUnSyJEj9etf/1o9e/bUgw8+qOHDh4fsyaG+nK+tW7dqwYIFWrZsWb01ocaX8+XszJkzuvXWW1VVVaVFixZ5/XMEg7PnoaG5qau+rvGmzNM5q7F8+XLNmjVLK1eurDO0N1XuzpfdbtfYsWP1yCOP6OKLL/ZXe0HHkz9fVVVVslgs+vvf/66f/OQn+vnPf6558+Zp2bJlXt171Lxiqg/dd999uvXWW89Zk56erh07dujIkSO1tn311Ve10nONuLg4hYWFqVu3bi7jl156qTZu3Nj4pgPIl/NVUFCgo0eP6oILLnCM2e12TZs2TfPnz9cXX3xxXr0Hgi/nq8aZM2c0evRoHThwQO+8806T2mskVf89slqttf5FevTo0XrnJiEhoc76sLAwxcbG+qzXYNGYOauxcuVKjR8/XqtWrdLgwYN92WbQ8HS+ysvL9eGHH2rbtm267777JFV/+RtjFBYWpnXr1unaa6/1S++B0Jg/X4mJiUpOTlZMTIxj7NJLL5UxRkVFReratatXeiMceUlcXJzi4uIarOvXr59KS0v1wQcf6Cc/+Ykk6f3331dpaamuvvrqOl8THh6uK6+8Up988onL+L59+5SWlnb+zQeAL+crKyur1n+Mhw4dqqysLN11113n33wA+HK+pB+C0aeffqp33323SX7xh4eHq3fv3srPz9dNN93kGM/Pz9fIkSPrfE2/fv30z3/+02Vs3bp16tOnj1q2bOnTfoNBY+ZMqt5j9Itf/ELLly/XsGHD/NFqUPB0vqKjo7Vz506XsUWLFumdd97R6tWr1blzZ5/3HEiN+fPVv39/rVq1SidPnlTbtm0lVX8XtmjRQikpKd5rzqene6NO119/venRo4fZvHmz2bx5s7nssstqXWr9ox/9yOTl5Tme5+XlmZYtW5olS5aYTz/91CxcuNBYrVZTUFDg7/b9rjHzdbbmcrWaMZ7P15kzZ8yIESNMSkqK2b59uykuLnY8KioqAvERfKbmsuEXXnjB7Nmzx+Tm5po2bdqYL774whhjzIMPPmiysrIc9TWX8v/61782e/bsMS+88EKzvZTf3Tl7+eWXTVhYmPnjH//o8mfpxIkTgfoIfuXpfJ2tuV2t5ul8lZeXm5SUFDNq1Cize/dus2HDBtO1a1fzy1/+0qt9EY4C4NixY2bcuHEmKirKREVFmXHjxpnjx4+71EgyS5cudRl74YUXzEUXXWRatWplLr/8cvPKK6/4r+kAaux8OWtO4cjT+Tpw4ICRVOfj3Xff9Xv/vvbHP/7RpKWlmfDwcHPFFVeYDRs2OLbdeeedZuDAgS7169evN7169TLh4eEmPT3dLF682M8dB54nczZw4MA6/yzdeeed/m88QDz9M+asuYUjYzyfr71795rBgwebyMhIk5KSYqZOnWq+/fZbr/ZkMea/ZxcCAACAq9UAAACcEY4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4AAACcEI4ABK309HTNnz8/aN/P+X0tFossFotOnDjh9fc/l5qf265dO7/+XKApIxwB8Lobbrih3juxb968WRaLRR999JGfu5K2bNmie+65x/HcYrHolVde8cp7P/rooyouLna5W/j5yMzM1J/+9KcG64qLi30S+IDmjHAEwOvGjx+vd955R19++WWtbX/961/Vs2dPXXHFFX7vq2PHjmrdurVP3jsqKkoJCQmyWCzn/V7ffPONNm3apBtuuKHB2oSEBK8FMgDVCEcAvG748OHq1KmTli1b5jL+7bffauXKlRo/frwkadOmTRowYIAiIyOVmpqqKVOm6NSpU/W+78GDBzVy5Ei1bdtW0dHRGj16tI4cOeJS89prr6lPnz5q1aqV4uLiZLPZHNucD6ulp6dLkm666SZZLBalp6friy++UIsWLfThhx+6vOfChQuVlpYmT25FuWzZMrVr107/+te/9KMf/UitW7fWqFGjdOrUKb344otKT09X+/btNXnyZNntdpfXvv7667r88suVnJys48ePa9y4cerYsaMiIyPVtWtXLV261O0+AHiOcATA68LCwnTHHXdo2bJlLoFi1apVqqys1Lhx47Rz504NHTpUNptNO3bs0MqVK7Vx40bdd999db6nMUY33nijvvnmG23YsEH5+fnav3+/xowZ46h5/fXXZbPZNGzYMG3btk1vv/22+vTpU+f7bdmyRZK0dOlSFRcXa8uWLUpPT9fgwYNrhY+lS5cqOzvb471C3377rZ599lmtWLFC//d//6f169fLZrPpjTfe0BtvvKGXXnpJS5Ys0erVq11e99prr2nkyJGSpN/97nfas2eP3nzzTe3du1eLFy9WXFycR30A8JABAB/Yu3evkWTeeecdx9iAAQPMbbfdZowxJisry9xzzz0urykoKDAtWrQwp0+fNsYYk5aWZp555hljjDHr1q0zVqvVHDx40FG/e/duI8l88MEHxhhj+vXrZ8aNG1dvT87vZ4wxkszatWtdalauXGnat29vvvvuO2OMMdu3bzcWi8UcOHDA7fc1xpilS5caSeazzz5zjN17772mdevWpry83DE2dOhQc++99zqef/fddyYqKsrs2LHDGGPMDTfcYO666656f3bNz4qJiTlnDQD3secIgE9ccskluvrqq/XXv/5VkrR//34VFBToF7/4hSRp69atWrZsmdq2bet4DB06VFVVVTpw4ECt99u7d69SU1OVmprqGOvWrZvatWunvXv3SpK2b9+uQYMGnVffN954o8LCwrR27VpJ1edIXXPNNY7DcJ5o3bq1unTp4ngeHx+v9PR0tW3b1mXs6NGjjufvvPOOYmNjddlll0mSfvWrX2nFihXq2bOnZsyYoU2bNjXykwFwF+EIgM+MHz9ea9asUVlZmZYuXaq0tDRHeKmqqtK9996r7du3Ox7/7//9P3366acugaKGMabOw1rO45GRkefdc3h4uLKysrR06VJVVlbq5ZdfdgQ6T7Vs2dLlucViqXOsqqrK8dz5kJok/exnP9OXX36p3NxcHT58WIMGDdL06dMb1Q8A9xCOAPjM6NGjZbVa9fLLL+vFF1/UXXfd5QgyV1xxhXbv3q2LLrqo1iM8PLzWe3Xr1k0HDx5UYWGhY2zPnj0qLS3VpZdeKknq0aOH3n77bbf7a9myZa2ToSXpl7/8pd566y0tWrRIZ86ccTmp25eMMfrnP/+pESNGuIx37NhR2dnZ+tvf/qb58+dryZIlfukHaK4IRwB8pm3bthozZox+85vf6PDhw8rOznZse+CBB7R582ZNmjRJ27dv16effqrXXntNkydPrvO9Bg8erB49emjcuHH66KOP9MEHH+iOO+7QwIEDHSddP/zww1q+fLkefvhh7d27Vzt37tTcuXPr7S89PV1vv/22SkpKdPz4ccf4pZdeqquuukoPPPCAbrvtNq/skXLH1q1bderUKQ0YMMAx9vvf/16vvvqqPvvsM+3evVv/+te/HGEQgG8QjgD41Pjx43X8+HENHjxYF1xwgWO8R48e2rBhgz799FNlZGSoV69e+t3vfqfExMQ636dmwcb27dtrwIABGjx4sC688EKtXLnSUZOZmalVq1bptddeU8+ePXXttdfq/fffr7e3p59+Wvn5+UpNTVWvXr1q9V1ZWdnoQ2qN8eqrr2rYsGEKCwtzjIWHh2vmzJnq0aOHBgwYIKvVqhUrVvitJ6A5shjjwcIdANBMPPbYY1qxYoV27tzZYG16erpyc3OVm5t7Xj+zR48e+u1vf6vRo0d79Lply5YpNzfX77cuAZoq9hwBgJOTJ09qy5YtWrhwoaZMmeL26x544AG1bdtWpaWljfq5lZWVuvnmm/Wzn/3Mo9e1bdtWEyZMaNTPBFA39hwBgJPs7GwtX75cN954o15++WVZrdYGX/Pll1/qzJkzkqQLL7xQLVr479+dn332mSTJarWqc+fOfvu5QFNGOAIAAHDCYTUAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAnhCMAAAAn/x8EG9toe1Fr/QAAAABJRU5ErkJggg==ter(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],color = 'lime') ^ SyntaxError: invalid decimal literal
Linear fitΒΆ
Well behaved dampers like this one tend to have two damping constants - one in compression and the other in rebound. Of course, these don't need to be straight lines, but in this case the shims in the damper's piston have been tuned for a linear response. Let's get a straight line fit on both these lines and see what the damping constants are:
import numpy as np
ullman_pvp_coefficients_negative1 = np.polyfit(ullman_velocity[ullman_velocity_peaks_negative[0]], ullman_force[ullman_velocity_peaks_negative[0]],1)
ullman_pvp_negative1 = np.poly1d(ullman_pvp_coefficients_negative1)
ullman_pvp_coefficients_positive1 = np.polyfit(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],1)
ullman_pvp_positive1 = np.poly1d(ullman_pvp_coefficients_positive1)
plt.plot(ullman_velocity, ullman_pvp_negative1(ullman_velocity),color = 'red')
plt.plot(ullman_velocity, ullman_pvp_positive1(ullman_velocity),color = 'lime')
plt.text(0.2,800,'c1 = ' + str(-round(ullman_pvp_coefficients_negative1[0])) + ' N*s/m', color = 'red')
plt.text(0.2,700,'c2 = ' + str(-round(ullman_pvp_coefficients_positive1[0])) + ' N*s/m', color = 'lime')
plt.scatter(ullman_velocity[ullman_velocity_peaks_negative[0]], ullman_force[ullman_velocity_peaks_negative[0]],color = 'red')
plt.scatter(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],color = 'lime')
plt.title("Two linear fits (two damping constants)")
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
Higher order polynomialΒΆ
Can a single higher order polynomial fit the data?
ullman_velocity_peaks = ullman_velocity_peaks_negative + ullman_velocity_peaks_positive
ullman_pvp_coefficients = np.polyfit(ullman_velocity[ullman_velocity_peaks[0]], ullman_force[ullman_velocity_peaks[0]],4)
ullman_pvp2 = np.poly1d(ullman_pvp_coefficients)
plt.plot(ullman_velocity, ullman_pvp2(ullman_velocity))
plt.title("4th order polynomial fit for the damping curve")
plt.scatter(ullman_velocity[ullman_velocity_peaks_negative[0]], ullman_force[ullman_velocity_peaks_negative[0]],color = 'red')
plt.scatter(ullman_velocity[ullman_velocity_peaks_positive[0]], ullman_force[ullman_velocity_peaks_positive[0]],color = 'lime')
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
plt.show()
from tensorflow import keras
import tensorflow as tf
import math
# Create the model
model = keras.Sequential()
model.add(keras.layers.Dense(units = 1, activation = 'linear', input_shape=[1]))
model.add(keras.layers.Dense(units = 64, activation = 'relu'))
model.add(keras.layers.Dense(units = 64, activation = 'relu'))
model.add(keras.layers.Dense(units = 1, activation = 'linear'))
model.compile(loss='mse', optimizer="adam")
# Display the model
model.summary()
/opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/attr_value.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/tensor.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/resource_handle.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/tensor_shape.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/types.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/full_type.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/function.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/node_def.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/op_def.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/graph.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/graph_debug_info.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/versions.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/protobuf/config.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at xla/tsl/protobuf/coordination_config.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/cost_graph.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/step_stats.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/allocation_description.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/framework/tensor_description.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/protobuf/cluster.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/google/protobuf/runtime_version.py:98: UserWarning: Protobuf gencode version 5.28.3 is exactly one major version older than the runtime version 6.31.1 at tensorflow/core/protobuf/debug.proto. Please update the gencode to avoid compatibility violations in the next runtime release. warnings.warn( /opt/conda/lib/python3.13/site-packages/keras/src/export/tf2onnx_lib.py:8: FutureWarning: In the future `np.object` will be defined as the corresponding NumPy scalar. if not hasattr(np, "object"): /opt/conda/lib/python3.13/site-packages/keras/src/layers/core/dense.py:106: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
βββββββββββββββββββββββββββββββββββ³βββββββββββββββββββββββββ³ββββββββββββββββ β Layer (type) β Output Shape β Param # β β‘βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ© β dense (Dense) β (None, 1) β 2 β βββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββββββββ€ β dense_1 (Dense) β (None, 64) β 128 β βββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββββββββ€ β dense_2 (Dense) β (None, 64) β 4,160 β βββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββββββββ€ β dense_3 (Dense) β (None, 1) β 65 β βββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄ββββββββββββββββ
Total params: 4,355 (17.01 KB)
Trainable params: 4,355 (17.01 KB)
Non-trainable params: 0 (0.00 B)
# Training
model.fit( ullman_velocity, ullman_force, epochs=100, verbose=1)
Epoch 1/100 1064/1064 ββββββββββββββββββββ 3s 1ms/step - loss: 13814.1543 Epoch 2/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 2722.0652 Epoch 3/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 2207.5793 Epoch 4/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1749.1078 Epoch 5/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1529.4952 Epoch 6/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1440.0519 Epoch 7/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1392.2977 Epoch 8/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1363.6760 Epoch 9/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1349.8647 Epoch 10/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1341.4752 Epoch 11/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1327.3407 Epoch 12/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1325.1079 Epoch 13/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1314.2338 Epoch 14/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1308.0569 Epoch 15/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1308.1688 Epoch 16/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1304.6078 Epoch 17/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1303.7666 Epoch 18/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1305.5067 Epoch 19/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1303.3816 Epoch 20/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1303.4846 Epoch 21/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1297.2653 Epoch 22/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.5061 Epoch 23/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1296.4343 Epoch 24/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.7406 Epoch 25/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1298.7593 Epoch 26/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1297.2434 Epoch 27/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1296.7106 Epoch 28/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1296.0599 Epoch 29/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1295.3154 Epoch 30/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1295.5212 Epoch 31/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1296.8688 Epoch 32/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.0133 Epoch 33/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.4882 Epoch 34/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1293.6497 Epoch 35/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.7628 Epoch 36/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1293.1870 Epoch 37/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.5201 Epoch 38/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.2454 Epoch 39/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.5138 Epoch 40/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.5327 Epoch 41/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1293.0852 Epoch 42/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1295.9518 Epoch 43/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.1375 Epoch 44/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.6090 Epoch 45/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.8464 Epoch 46/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.0609 Epoch 47/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.8826 Epoch 48/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.3689 Epoch 49/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.6859 Epoch 50/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.2965 Epoch 51/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1288.2144 Epoch 52/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.1262 Epoch 53/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.8053 Epoch 54/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.2422 Epoch 55/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.0076 Epoch 56/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.0084 Epoch 57/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.6095 Epoch 58/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1288.3645 Epoch 59/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.5881 Epoch 60/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1294.8358 Epoch 61/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.7021 Epoch 62/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.0344 Epoch 63/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.0354 Epoch 64/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.5771 Epoch 65/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.5732 Epoch 66/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.8263 Epoch 67/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1285.4114 Epoch 68/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.3972 Epoch 69/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.7135 Epoch 70/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.1635 Epoch 71/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.6438 Epoch 72/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.3409 Epoch 73/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.9170 Epoch 74/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.0470 Epoch 75/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1288.8875 Epoch 76/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.4871 Epoch 77/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1285.6396 Epoch 78/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.5902 Epoch 79/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1288.8912 Epoch 80/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1288.1246 Epoch 81/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.0289 Epoch 82/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.7023 Epoch 83/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.7206 Epoch 84/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1286.4290 Epoch 85/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1285.0483 Epoch 86/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1291.2622 Epoch 87/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.9436 Epoch 88/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1290.9926 Epoch 89/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.3160 Epoch 90/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1283.1725 Epoch 91/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1292.7914 Epoch 92/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1287.0483 Epoch 93/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1284.6010 Epoch 94/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.8257 Epoch 95/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.7552 Epoch 96/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.2177 Epoch 97/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1289.0544 Epoch 98/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1286.4901 Epoch 99/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1286.8035 Epoch 100/100 1064/1064 ββββββββββββββββββββ 1s 1ms/step - loss: 1284.6512
<keras.src.callbacks.history.History at 0xe8020c285be0>
# Compute the output
ullman_force_predicted = model.predict(ullman_velocity)
# Display the result
plt.scatter(ullman_velocity,ullman_force)
plt.plot(ullman_velocity, ullman_force_predicted, 'r', linewidth=4)
plt.title("100 epoch neural network fit with TensorFlow")
plt.xlabel(ullman_velocity_name + ' [' + ullman_velocity_unit + ']')
plt.ylabel(ullman_force_name + ' [' + ullman_force_unit + ']')
# plt.grid()
plt.show()
1064/1064 ββββββββββββββββββββ 1s 750us/step