1 % Scaling counterexample
5 % This basic simulation is designed to show, by counterexample,
6 % why use of nondimensional numbers is necessary for NTRT.
7 % Equivalently, this would show why the commutative property of
8 % multiplication does not apply to scaling of units.
10 clear all; clc; close all;
12 % This disproves the following posulate:
13 % 10 * (length / time ^2) == (10 * length) / time^2
15 % A spring-mass-damper oriented vertically.
18 %y_rest = 0.50; % meters;
22 c = 10; % N*s/m, or kg/sec
24 % Newton
's third law for this 1-DOF system is
25 % m * y_ddot + c * y_dot + k * (y - y_rest) = -mg
27 % So, in state space, we're looking at a linear system (technically an
28 % affine system) which is the following, where x = [y; y_dot]
34 C = [ 0; -g + k * y_rest/m];
36 % Forward-integrate (Euler style) for a handful of seconds
40 num_timesteps = size(t,2);
41 y = zeros(2, num_timesteps); % because we have 2 state variables plus the affine offset. Want column vectors
for each timestep.
43 % initialize. Particle starts at y0, with zero velocity.
47 %
simulate. note that only the Ax terms
get euler integrated, we need
48 % the affine term to stay == 1.
49 y(:, i) = ( A * y(:, i-1) + C) * dt + y(:,i-1);
55 title(
'Original, unscaled simulation');
57 ylabel(
'Vertical height of particle, meters');
59 % Now,
for comparison, scale gravity. This should be different!
61 % A does not change, but C does:
62 C = [ 0; -g_scaled + k * y_rest/m];
63 % We can use the same timestepping, but need to collect
new data points:
64 y_new = zeros(2, num_timesteps);
65 y_new(:,1) = [ y0; 0];
68 %
simulate. note that only the Ax terms
get euler integrated, we need
69 % the affine term to stay == 1.
70 y_new(:, i) = ( A * y_new(:, i-1) + C) * dt + y_new(:,i-1);
76 plot(t, y_new(2,:),
'r');
77 title(
'With only gravity scaled');
79 ylabel(
'Vertical height of particle, meters');
81 % Here
's the fun part: do a third simulation, and scale length,
82 % as we'd normally
do in NTRT. Our length constants are y0 and y_rest.
83 length_scaling_factor = g_scaled/g;
84 y0_new = length_scaling_factor * y0;
85 y_rest_new = length_scaling_factor * y_rest;
87 % Recalculate C, again, and initialize.
88 C = [ 0; -g_scaled + k * y_rest_new/m];
89 y_new_length_scaled = zeros(2, num_timesteps);
90 y_new_length_scaled(:,1) = [y0_new; 0];
93 %
simulate. note that only the Ax terms
get euler integrated, we need
94 % the affine term to stay == 1.
95 y_new_length_scaled(:, i) = ( A * y_new_length_scaled(:, i-1) + C) * dt + y_new_length_scaled(:,i-1);
98 % Now, re-adjust the length scale as we'd do in NTRT.
99 y_new_length_scaled = y_new_length_scaled ./ length_scaling_factor;
103 plot(t, y_new_length_scaled(1,:));
104 plot(t, y_new_length_scaled(2,:),
'r');
105 title(
'With both gravity and initial length constants scaled');
107 ylabel(
'Vertical height of particle, meters');
109 % These plots are the same, and that makes sense by laws of superposition.
110 % Since scaling g is equivalent to scaling a step input in the system,
this
111 % can be thought of as an increase in the magnitude of the input, and we
112 % expect a proportional increase in the magnitude of the output via linear
115 % Now, let
's do something explicitly nonlinear.
void simulate(tgSimulation *simulation)