Ceci est un forum public. Les Cowboys Fringants dalporto se dissocient des opinions émises sur ce forum.

 L'Encyclopédie du Peuple

Auteur Sujet: Mathématiques!!  (Lu 566 fois)

dalporto

  • Expert en tout et en rien, mais surtout en rien.
  • Membre
  • ******
  • Messages: 14885
  • Admin capo di tutti i capi ultra-woke
  • Respect: +1958
Mathématiques!!
« le: juin 05, 2024, 01:06:14 pm »
0
Yo les Ing.

Soit la formule suivante:

FCV_A[0] :=  1.712846;
FCV_A[1] := -4.6682500e-001;
FCV_A[2] :=  9.4512100e-002;
FCV_A[3] := -2.2403100e-003;
FCV_A[4] :=  3.6533000e-005;
FCV_A[5] := -3.3381500e-007;
FCV_A[6] :=  1.1859600e-009;
FCV_B[0] := FCV_A[0];
FCV_B[1] := FCV_A[1] * (FCV_POSITION);
FCV_B[2] := FCV_A[2] * (FCV_POSITION ** 2);
FCV_B[3] := FCV_A[3] * (FCV_POSITION ** 3);
FCV_B[4] := FCV_A[4] * (FCV_POSITION ** 4);
FCV_B[5] := FCV_A[5] * (FCV_POSITION ** 5);
FCV_B[6] := FCV_A[6] * (FCV_POSITION ** 6);
FCV_C := 1 / (FCV_B[0] + FCV_B[1] + FCV_B[2] + FCV_B[3] + FCV_B[4] + FCV_B[5] + FCV_B[6]);
FCV_ELEVATION := 1051.0;

FCV_WATERHEAD := FCV_RESERVOIR_LEVEL - FCV_ELEVATION;
FCV_CALCULATION := FCV_C  + 7.4708000e-005;
FCV_Q := (SQRT(FCV_WATERHEAD) / SQRT(FCV_CALCULATION));
RET(FCV_Q);


Ça calcule en gros un débit (FCV_Q) selon la valeur FCV_RESERVOIR_LEVEL et la valeur FCV_POSITION. Le reste c'est des constantes.

Je voudrais modifier la formule pour qu'avec un débit connu FCV_Q et un FCV_RESERVOIR_LEVEL connu je puisse connaitre FCV_POSITION.

** = exposant et SQRT = racine carrée.

C'est des maths du secondaire, mais quand y'a trop d'opérations mélangées ensemble et un polynome ça me mêle.

Valeurs pour exemple: à 1112.4 de Reservoir et 18.3 de position ça donne un débit de 29.87.

MadChuck

  • Mad Chuck Norris
  • Membre
  • *********
  • Messages: 33108
  • Ing. BBQ
  • Respect: +2343
Mathématiques!!
« Réponse #1 le: juin 05, 2024, 01:14:36 pm »
0
si les performances ne sont pas importantes, peut-etre tu as pas besoin de penser ou faire de math et juste utilisé le processeur pour le trouvé, chatGPT par example suggère:

# Calcul de FCV_WATERHEAD
FCV_WATERHEAD = FCV_RESERVOIR_LEVEL - FCV_ELEVATION

# Initialisation des variables
FCV_POSITION = 1.0  # initial guess for FCV_POSITION
epsilon = 1e-6  # error tolerance
delta = 1.0  # initial value for delta

# Boucle de résolution
while delta > epsilon:
{
    # Calcul de FCV_B
    FCV_B = [
        FCV_A[0],
        FCV_A[1] * FCV_POSITION,
        FCV_A[2] * (FCV_POSITION ** 2),
        FCV_A[3] * (FCV_POSITION ** 3),
        FCV_A[4] * (FCV_POSITION ** 4),
        FCV_A[5] * (FCV_POSITION ** 5),
        FCV_A[6] * (FCV_POSITION ** 6)
    ]

    # Calcul de FCV_C
    FCV_C = 1 / sum(FCV_B)
   
    # Calcul de FCV_CALCULATION
    FCV_CALCULATION = FCV_C + 7.4708000e-005
   
    # Nouvelle estimation de FCV_POSITION
    new_position = (FCV_WATERHEAD / (FCV_Q ** 2 * FCV_CALCULATION)) ** 0.25
   
    # Calcul de la différence
    delta = abs(new_position - FCV_POSITION)
   
    # Mise à jour de FCV_POSITION
    FCV_POSITION = new_position
}


dalporto

  • Expert en tout et en rien, mais surtout en rien.
  • Membre
  • ******
  • Messages: 14885
  • Admin capo di tutti i capi ultra-woke
  • Respect: +1958
Mathématiques!!
« Réponse #2 le: juin 05, 2024, 01:47:11 pm »
0
J<y ai fait calculer avec ce que j'ai, et c'est off en partant:



FCV_A[0] :=  1.712846;
FCV_A[1] := -4.6682500e-001;
FCV_A[2] :=  9.4512100e-002;
FCV_A[3] := -2.2403100e-003;
FCV_A[4] :=  3.6533000e-005;
FCV_A[5] := -3.3381500e-007;
FCV_A[6] :=  1.1859600e-009;
FCV_B[0] := FCV_A[0];
FCV_B[1] := FCV_A[1] * (FCV_POSITION);
FCV_B[2] := FCV_A[2] * (FCV_POSITION ** 2);
FCV_B[3] := FCV_A[3] * (FCV_POSITION ** 3);
FCV_B[4] := FCV_A[4] * (FCV_POSITION ** 4);
FCV_B[5] := FCV_A[5] * (FCV_POSITION ** 5);
FCV_B[6] := FCV_A[6] * (FCV_POSITION ** 6);
FCV_C := 1 / (FCV_B[0] + FCV_B[1] + FCV_B[2] + FCV_B[3] + FCV_B[4] + FCV_B[5] + FCV_B[6]);
FCV_ELEVATION := 1051.0;

FCV_WATERHEAD := FCV_RESERVOIR_LEVEL - FCV_ELEVATION;
FCV_CALCULATION := FCV_C  + 7.4708000e-005;
FCV_Q := (SQRT(FCV_WATERHEAD) / SQRT(FCV_CALCULATION));
RET(FCV_Q);

If FCV_RESERVOIR_LEVEL = 1112.4 and FCV_POSITION = 18.3, what is FCV_Q?
ChatGPT

To calculate FCVQFCVQ? given FCVRESERVOIRLEVEL=1112.4FCVR?ESERVOIRL?EVEL=1112.4 and FCVPOSITION=18.3FCVP?OSITION=18.3, we need to follow the provided formulas step by step.

Here are the steps:

    Calculate FCVWATERHEADFCVW?ATERHEAD:
    FCVWATERHEAD=FCVRESERVOIRLEVEL?FCVELEVATIONFCVW?ATERHEAD=FCVR?ESERVOIRL?EVEL?FCVE?LEVATION
    FCVWATERHEAD=1112.4?1051.0FCVW?ATERHEAD=1112.4?1051.0
    FCVWATERHEAD=61.4FCVW?ATERHEAD=61.4

    Calculate the FCVBFCVB? values using the given FCVPOSITION=18.3FCVP?OSITION=18.3:
    FCVB[0]=FCVA[0]=1.712846FCVB?[0]=FCVA?[0]=1.712846
    FCVB[1]=FCVA[1]×FCVPOSITION=?0.46682500×18.3FCVB?[1]=FCVA?[1]×FCVP?OSITION=?0.46682500×18.3
    FCVB[2]=FCVA[2]×FCVPOSITION2=0.094512100×(18.3)2FCVB?[2]=FCVA?[2]×FCVP?OSITION2=0.094512100×(18.3)2
    FCVB[3]=FCVA[3]×FCVPOSITION3=?0.0022403100×(18.3)3FCVB?[3]=FCVA?[3]×FCVP?OSITION3=?0.0022403100×(18.3)3
    FCVB[4]=FCVA[4]×FCVPOSITION4=3.6533000e?005×(18.3)4FCVB?[4]=FCVA?[4]×FCVP?OSITION4=3.6533000e?005×(18.3)4
    FCVB[5]=FCVA[5]×FCVPOSITION5=?3.3381500e?007×(18.3)5FCVB?[5]=FCVA?[5]×FCVP?OSITION5=?3.3381500e?007×(18.3)5
    FCVB[6]=FCVA[6]×FCVPOSITION6=1.1859600e?009×(18.3)6FCVB?[6]=FCVA?[6]×FCVP?OSITION6=1.1859600e?009×(18.3)6

    Calculate FCVCFCVC?:
    FCVC=1FCVB[0]+FCVB[1]+FCVB[2]+FCVB[3]+FCVB[4]+FCVB[5]+FCVB[6]FCVC?=FCVB?[0]+FCVB?[1]+FCVB?[2]+FCVB?[3]+FCVB?[4]+FCVB?[5]+FCVB?[6]1?

    Calculate FCVCALCULATIONFCVC?ALCULATION:
    FCVCALCULATION=FCVC+7.4708000×10?5FCVC?ALCULATION=FCVC?+7.4708000×10?5

    Finally, calculate FCVQFCVQ?:
    FCVQ=FCVWATERHEADFCVCALCULATIONFCVQ?=FCVC?ALCULATION

?FCVW?ATERHEAD

    ??

Now let's compute these step by step.
Step-by-Step Calculation

    FCVWATERHEAD=61.4FCVW?ATERHEAD=61.4

    Calculate FCVBFCVB? values:

    FCVB[0]=1.712846FCVB?[0]=1.712846
    FCVB[1]=?0.46682500×18.3=?8.5458975FCVB?[1]=?0.46682500×18.3=?8.5458975
    FCVB[2]=0.094512100×(18.3)2=31.696665259FCVB?[2]=0.094512100×(18.3)2=31.696665259
    FCVB[3]=?0.0022403100×(18.3)3=?13.7642073007FCVB?[3]=?0.0022403100×(18.3)3=?13.7642073007
    FCVB[4]=3.6533000e?005×(18.3)4=4.69777325806861FCVB?[4]=3.6533000e?005×(18.3)4=4.69777325806861
    FCVB[5]=?3.3381500e?007×(18.3)5=?0.26160355800467407FCVB?[5]=?3.3381500e?007×(18.3)5=?0.26160355800467407
    FCVB[6]=1.1859600e?009×(18.3)6=0.05515135141241042FCVB?[6]=1.1859600e?009×(18.3)6=0.05515135141241042

    Sum the FCVBFCVB? values:
    FCV_B_{\text{sum}} = 1.712846 + (-8.5458975) + 31.696665259 + (-13.7642073007) + 4.69777325806861 + (-0.26160355800467407) + 0.05515135141241042
    FCV_B_{\text{sum}} = 15.590727510776346

    Calculate FCVCFCVC?:
    FCV_C = \frac{1}{FCV_B_{\text{sum}}} = \frac{1}{15.590727510776346} = 0.0641463804667497

    Calculate FCVCALCULATIONFCVC?ALCULATION:
    FCVCALCULATION=FCVC+7.4708000×10?5=0.0641463804667497+7.4708000×10?5=0.0642210884667497FCVC?ALCULATION=FCVC?+7.4708000×10?5=0.0641463804667497+7.4708000×10?5=0.0642210884667497

    Calculate FCVQFCVQ?:
    FCVQ=61.40.0642210884667497FCVQ?=0.0642210884667497

?61.4

    ??
    FCVQ=7.8376611877924390.253417264919943FCVQ?=0.2534172649199437.837661187792439?
    FCVQ?30.924FCVQ??30.924

Therefore, given FCVRESERVOIRLEVEL=1112.4FCVR?ESERVOIRL?EVEL=1112.4 and FCVPOSITION=18.3FCVP?OSITION=18.3, the calculated FCVQFCVQ? is approximately 30.924.

MadChuck

  • Mad Chuck Norris
  • Membre
  • *********
  • Messages: 33108
  • Ing. BBQ
  • Respect: +2343
Mathématiques!!
« Réponse #3 le: juin 05, 2024, 02:48:43 pm »
0
J<y ai fait calculer avec ce que j'ai, et c'est off en partant:

Je ny ferais pas trop confiance pour faire des actuels calcul mathématique, tu peux tu rouler le code à la place ?

dalporto

  • Expert en tout et en rien, mais surtout en rien.
  • Membre
  • ******
  • Messages: 14885
  • Admin capo di tutti i capi ultra-woke
  • Respect: +1958
Mathématiques!!
« Réponse #4 le: juin 05, 2024, 05:30:46 pm »
0
Ouain, j'ai rien d'installé pour rouler du Python, faudrait que je m'y mette un jour.

Mias là je veux quelque chose de plus précis qu'une approximation.

Il faut que réussisse à reverse-engineerer FV_C, ce qui me semble compliqué pour mes maths 203 d'il y a presque 30 ans.

dalporto

  • Expert en tout et en rien, mais surtout en rien.
  • Membre
  • ******
  • Messages: 14885
  • Admin capo di tutti i capi ultra-woke
  • Respect: +1958
Mathématiques!!
« Réponse #5 le: juin 05, 2024, 05:38:48 pm »
0
J'arrive avec des dérivés pour calculer ça, je crois que ça va être fuck it et je vais trouver une façon détournée de le faire, genre avec 2 look-out tables à deux dimensions selon les valeurs possibles.

MadChuck

  • Mad Chuck Norris
  • Membre
  • *********
  • Messages: 33108
  • Ing. BBQ
  • Respect: +2343
Mathématiques!!
« Réponse #6 le: juin 05, 2024, 08:03:22 pm »
0
Mias là je veux quelque chose de plus précis qu'une approximation.

Sur un ordinateur, il n'existe pas mal juste que des approximations si tu fais des calculs avec des virgules (C'est assez compliqué de faire du précis) et toutes des variables d'entrés en seront.

Ce code la (qui peut-etre collé ici : https://www.online-python.com/ pour le rouler):


known_FCV_Q = 29.87
known_FCV_RESERVOIR_LEVEL = 1112.4
FCV_ELEVATION = 1051.0;
FCV_A = [ 0 ] * 7
FCV_A[0] =  1.712846
FCV_A[1] = -4.6682500e-001
FCV_A[2] =  9.4512100e-002
FCV_A[3] = -2.2403100e-003
FCV_A[4] =  3.6533000e-005
FCV_A[5] = -3.3381500e-007
FCV_A[6] =  1.1859600e-009


def calculate_FCV_Q(FCV_POSITION):
    FCV_B = [ 0 ] * 7
    FCV_B[0] = FCV_A[0]
    FCV_B[1] = FCV_A[1] * FCV_POSITION
    FCV_B[2] = FCV_A[2] * (FCV_POSITION ** 2)
    FCV_B[3] = FCV_A[3] * (FCV_POSITION ** 3)
    FCV_B[4] = FCV_A[4] * (FCV_POSITION ** 4)
    FCV_B[5] = FCV_A[5] * (FCV_POSITION ** 5)
    FCV_B[6] = FCV_A[6] * (FCV_POSITION ** 6)

    FCV_C = 1 / sum(FCV_B)
    FCV_WATERHEAD = known_FCV_RESERVOIR_LEVEL - FCV_ELEVATION
    FCV_CALCULATION = FCV_C  + 7.4708000e-005
    FCV_Q = (FCV_WATERHEAD ** 0.5) / (FCV_CALCULATION ** 0.5)
    return FCV_Q

def derivative(FCV_POSITION):
    FCV_B_derivative = [ 0 ] * 7
    FCV_B_derivative[0] = 0
    FCV_B_derivative[1] = FCV_A[1]
    FCV_B_derivative[2] = 2 * FCV_A[2] * FCV_POSITION
    FCV_B_derivative[3] = 3 * FCV_A[3] * (FCV_POSITION ** 2)
    FCV_B_derivative[4] = 4 * FCV_A[4] * (FCV_POSITION ** 3)
    FCV_B_derivative[5] = 5 * FCV_A[5] * (FCV_POSITION ** 4)
    FCV_B_derivative[6] = 6 * FCV_A[6] * (FCV_POSITION ** 5)
   
    return sum(FCV_B_derivative)

# Define your initial guess and tolerance
FCV_POSITION = 100
epsilon = 1e-6

while True:
    FCV_POSITION_next = FCV_POSITION - (calculate_FCV_Q(FCV_POSITION) - known_FCV_Q) / derivative(FCV_POSITION)
    if abs(FCV_POSITION_next - FCV_POSITION) < epsilon:
        break
    FCV_POSITION = FCV_POSITION_next

print("Estimated FCV_POSITION:", FCV_POSITION)



Me donne:
Estimated FCV_POSITION: 18.299291247161747, avec un guess de départ de 100 pour FCV_POSITION 5-10 marche aussi, mais si il débute a 1-2, il ne se rend pas
« Modifié: juin 05, 2024, 08:05:39 pm par MadChuck »

MadChuck

  • Mad Chuck Norris
  • Membre
  • *********
  • Messages: 33108
  • Ing. BBQ
  • Respect: +2343
Mathématiques!!
« Réponse #7 le: juin 05, 2024, 08:08:11 pm »
0
J'arrive avec des dérivés pour calculer ça, je crois que ça va être fuck it et je vais trouver une façon détournée de le faire, genre avec 2 look-out tables à deux dimensions selon les valeurs possibles.

Si tu veux une précision assez rough et que ca bouge pas tant les 2 variables, tu peux trouvé quelque valeur proche et intrapolé entre elle (ou juste la plus proche) d'une table précalculé effectivement, pour le IK d'un bras de robot c'est ce qu'on avait fini par faire dans l'ancien temps ou les calculés sur le fly était trop lent pour son petit cpu, mais il avait en masse de mémoire.

Une table mysql a des performances vraiment dure à comprendre pour ce genre de chose.

dalporto

  • Expert en tout et en rien, mais surtout en rien.
  • Membre
  • ******
  • Messages: 14885
  • Admin capo di tutti i capi ultra-woke
  • Respect: +1958
Mathématiques!!
« Réponse #8 le: juin 05, 2024, 08:46:38 pm »
0
C'est du PLC, je ne vais pas piger ça dans des tables SQL.

Je monte un fichier Excel pour extraire les données de position 0-100% dans le range du réservoir (semi à déterminer, le plus faible range sera le mieux et le moins long à populer), et je garroche ça dans deux lookout tables en cascade dans ce style-là. Ça vire habituellement au final en bas de 50ms, donc c'est pas trop stressant.


IF ARRAY_DIM_X > 0 AND ARRAY_DIM_Y > 0 THEN
   IF INVAL >= ARRAY_Y[ARRAY_DIM_Y] AND ARRAY_Y[ARRAY_DIM_Y] > 0.0 THEN
      Y_2 := ARRAY_DIM_Y;
      Y_1 := Y_2 -1;
   ELSE
      FOR I_Y := 1 TO ARRAY_DIM_Y DO
         IF ARRAY_Y[I_Y] >= INVAL THEN
            IF I_Y = 1 THEN
               Y_2 := I_Y + 1;
               Y_1 := I_Y;
            ELSE
               Y_2 := I_Y;
               Y_1 := I_Y - 1;
            END_IF;
            EXIT;
         END_IF;
      END_FOR;
   END_IF;

   IF(INVAL > ARRAY_Y[Y_2]) THEN
      TEMP_VAL := ARRAY_Y[Y_2];
   ELSIF INVAL < ARRAY_Y[Y_1] THEN
      TEMP_VAL := ARRAY_Y[Y_1];
   ELSE
      TEMP_VAL := INVAL;
   END_IF;

   RATIO := (ARRAY_Y[Y_2] - TEMP_VAL)/(ARRAY_Y[Y_2] - ARRAY_Y[Y_1]);

   FOR I:= 1 TO ARRAY_DIM_Y DO
      ARRAY_OUT := ARRAY_DATA[I,Y_2] - (ARRAY_DATA[I,Y_2] - ARRAY_DATA[I,Y_1]) * RATIO;      
   END_FOR;

END_IF;



J'avais un collègue qui avait monté un script Python pour monter les arrays, il n'est plus là, faudrait que j'essaie un jour. Anyway c'est pas la même sorte de PLC, et là je me dis fuck pas certain que je vais pouvoir monter des array à 2 dimensions avec ça.

MadChuck

  • Mad Chuck Norris
  • Membre
  • *********
  • Messages: 33108
  • Ing. BBQ
  • Respect: +2343
Mathématiques!!
« Réponse #9 le: juin 05, 2024, 08:58:44 pm »
0
as-tu assez de mémoire sur ton PLC/PIC, pour la mettre ?

Tu peux tricher et "dérouler" une array 2D en 1D, juste a savoir la longueur du nombres de colonnes, pour te promener dedans


A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4

Peut devenir
A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4

Et pour aller chercher une valeur
retourner valeur (Ligne L, Colone C)
    return array(L*4+C)

Si la premiere ligne et colonne sont considéré être 0 (J'imagine que c'est pas mal ça qui se passe à l'interne quand on fait un tableau 2d dans du code de toute façon)
« Modifié: juin 05, 2024, 09:08:44 pm par MadChuck »