delucidazione su arrayfunction



  • delucidazione su array/function
    di Aregaf (utente non iscritto) data: 08/01/2015 22:43:25

    Salve a tutti, presupponendo che sono alle prime armi, sto svolgendo un esercizio sulla macro di excel e mi sono imbattuto in una delle mie profonde lacune.
    Nel codice che ho riportato ho compreso di aver sbagliato nella moltiplicazione tra matrici ( y = AR(1) * ARR(1) ) ed ho lasciato dei punti al ciclo che non sapevo come impostare; l'obiettivo del ciclo Do while-Loop era quello di trovare il valore di x che rendesse l'equazione "y" uguale a 0.

    Desidererei quindi che qualcuno mi desse una dritta riguardo la moltiplicazione tra matrici e il ciclo per ottenere il valore di x che rende y=0.

    Grazie in anticipo per l'aiuto !!

    p.s. = ovviamente prendo in considerazione solo il primo passaggio, perché poi capito il procedimento, lo applicherò alle altre componenti delle due matrici.
     
    Sub Macro()
    Dim x As Double, y As Double, i As Integer
    Dim AR(1 To 5) As Double, ARR(1 To 5) As Double
    Dim n As Integer
    
    a1 = 1
    b1 = 4
    c1 = 4
    d1 = 1
    e1 = 4
    f1 = 4
    
    
    AR(1) = x ^ 5 + x ^ 4 + x ^ 3 + x ^ 2 + x + 1
    AR(2) = x2 ^ 5 + x2 ^ 4 + x2 ^ 3 + x2 ^ 2 + x2 + 1
    AR(3) = x3 ^ 5 + x3 ^ 4 + x3 ^ 3 + x3 ^ 2 + x3 + 1
    AR(4) = x4 ^ 5 + x4 ^ 4 + x4 ^ 3 + x4 ^ 2 + x4 + 1
    AR(5) = x5 ^ 5 + x5 ^ 4 + x5 ^ 3 + x5 ^ 2 + x5 + 1
    
    ARR(1) = a1 + b1 + c1 + d1 + e1 + f1
    ARR(2) = a2 + b2 + c2 + d2 + e2 + f2
    ARR(3) = a3 + b3 + c3 + d3 + e3 + f3
    ARR(4) = a4 + b4 + c4 + d4 + e4 + f4
    ARR(5) = a5 + b5 + c5 + d5 + e5 + f5
    
        
        
        For i = 1 To n 'non parto da zero perchè il termine noto è diverso da zero
    
                y = AR(1) * ARR(1)
            
               Do while y<>0
               .....................
               Loop
       Next i             
              End If



  • di Vecchio Frac data: 09/01/2015 07:07:04

    Qualche riferimento anche non causale a questa discussione?
    h t t p://www.excelvba.it/Forum/thread.php?f=1&t=7840





  • di lepat (utente non iscritto) data: 09/01/2015 09:53:34

    E' inutile che tu cambi titolo, insisti a voler applicare al vba e ad excel equazioni che non hanno alcun senso per excel, ti è stato già detto, rivolgiti ad un forum di matematica o fai una ricerca su google con le parole "regola di ruffini con excel" oppure "risolvere equazioni con excel"



  • di lepat (utente non iscritto) data: 09/01/2015 09:57:30

    per chiarire meglio, il vba non lavora con le incognite, una riga del tipo
    AR(1) = x ^ 5 + x ^ 4 + x ^ 3 + x ^ 2 + x + 1
    non ha alcun significato se alla variabile x non viene assegnato un valore



  • di lepat (utente non iscritto) data: 09/01/2015 10:01:59

    Inoltre a che serve cambiare nome utente ? porta solo confusione, ci prendi per ritardati ?



  • di aregaf (utente non iscritto) data: 09/01/2015 11:11:55

    ho cambiato post per focalizzare il problema.. anyway è un esercizio che devo fare sulla macro di excel quindi se potete essermi di aiuto mi fareste un gran favore..



  • di lepat (utente non iscritto) data: 09/01/2015 15:28:26

    Per poter esserti di aiuto (te l'ho già detto) occorre sapere cosa si deve fare, se tu conosci metodi numerici per risolvere noi possiamo aiutarti ad applicarli, se tu non li conosci sei al pari di noi (conosciamo excel, ma non la matematica che ti serve).
    Sei nel posto sbagliato e stai perdendo tempo.



  • di aregaf (utente non iscritto) data: 09/01/2015 18:05:13

    ok lepat, scusa ma forse non sono stato molto chiaro..
    Riassumo brevemente ciò le mie intenzioni:
    Ho creato le due matrici, AR(5) e ARR(5), per poter avere un'equazione del tipo y=a*x^5+b*x^4+c*x^3+d*x^2+e*x+f, poi da questa equazione il mio obiettivo è stato quello di trovare (con un ciclo immagino) il valore di x che, sostituito nell'equazione sopracitata, mi dia y=0.

    Riassumendo il tutto, i problemi sono due, uno che, come mi avete detto, vba non legge l'equazione scritta in questo modo(e quindi mi servirebbe sapere come posso dargli un input del genere), e il secondo su come impostare il ciclo per aver il valore di x che renda y=0 ( ovvero a*x^5+b*x^4+c*x^3+d*x^2+e*x+f=0 ).

    Penso di essere stato chiaro, fammi sapere se ho tralasciato qualcosa, grazie!
    p.s. il cambio di nick non era voluto ma il problema è che li uso entrambi in altri forum sorry



  • di Albatros54 (utente non iscritto) data: 09/01/2015 18:34:55

    essendo un polinomio di quinto grado, non potendo applicare le formule di soluzione immediata, secondo le mie rimembranze, si dovrebbe prima verificare se il polinomio ammette delle soluzioni.Dopo questa verifica si dovrebbe applicare la formula di RUFFINI ovvero: trovare i divisori del termine noto e innescare un loop per verificare le radici, non so se la soluzione in VBA sia cosi semplice.
    Gioacchino



  • di aregaf (utente non iscritto) data: 09/01/2015 18:58:20

    ciao Gioacchino..guarda, se riesco a capire come scrivere equazioni su vba e impostare il loop (per scomporre l'equazione avendone una al quarto grado), il resto del lavoro(portare l'equazione dal quarto al terzo, secondo e primo grado) lo svolgerei io... quindi se puoi darmi qualche dritta su queste due cose mi saresti veramente utile. ciao!



  • di Vecchio Frac data: 09/01/2015 19:13:44

    Io però nell'altra discussione "Scomposizione con Ruffini": h t t p://www.excelvba.it/Forum/thread.php?f=1&t=7840
    (e che sto meditando di chiudere perchè un duplicato infruttuoso di questa) avevo già dato un'indicazione di come procedere, per creare una Function con passaggio di parametri noti, che la Function mastica e che restituisce sotto forma di risultato.
    In pratica devi creare una Function che accetti in ingresso i parametri noti e li elabori con la formula che conosci.
    Cosa non era chiaro nella spiegazione?





  • di frank (utente non iscritto) data: 09/01/2015 19:57:43

    Intendi così?? o come?

    Comunque sul ciclo non ho ancora idea di come fare..

    p.s. avrei voluto mantenere le matrici in questo progetto SE POSSIBILE
     
    Function f_x1(x As Single, a As Single, b As Single, c As Single, d As Single, e As Single, f As Single) As Single
    f_x1 = a * x ^ 5 + b * x ^ 4 + c * x ^ 3 + d * x ^ 2 + e * x + f
    End Function
    
    Sub macro()
    Dim y As Single
    a = 1
    b = 4
    c = 4
    d = 1
    e = 4
    f = 4
    For i = 1 To n
    
    Do
    ....... (trovare il valore di x che renda y=0)
    Loop Until y <> 0
    
    Next
    
    Cells(1, 1) = x
    End Sub



  • di Vecchio Frac data: 09/01/2015 21:13:29

    Sì il ragionamento è giusto, poi chiaramente bisogna adattare il codice per rispettare la sintassi.
    Solo che non avendo la minima idea di quello che devi fare, bisogna restare sul puro piano concettuale.
    Cioè, non so se sia quello che cerchi davvero anche perchè non ho idea di come il ciclo possa produrre una soluzione all'equazione... sembra quasi che hai introdotto coefficienti a caso.
     
    Function f_x1(x As Single, a As Single, b As Single, c As Single, d As Single, e As Single, f As Single) As Single
        f_x1 = a * x ^ 5 + b * x ^ 4 + c * x ^ 3 + d * x ^ 2 + e * x + f
    End Function
    
    Sub macro()
    Dim i as long, y As Single
        
        For i = 1 To 1000000     'mi fermo a un milione di cicli per evitare un loop infinito
             ' assegna a y il valore della function definita sopra
             y = f_x1(i, 1, 4, 4, 1, 4, 4)
             ' se y è zero esce dal ciclo
             if y = 0 then exit for
        Next
    
        if y = 0 then
             Cells(1, 1) = y
             msgbox "Ho trovato uno zero"
        else
             cells(1, 1) = ""
             msgbox "Non ho trovato uno zero nemmeno dopo un milione di cicli."
        end if
    End Sub






  • di frank (utente non iscritto) data: 09/01/2015 21:44:48

    Giusto, solo che mi serve in Cells(1,1)=x perché a me interessa il valore di x che blocca il ciclo quando y=0.
    I coefficienti li ho inventati io per far venire x (il primo valore di x, x1) uguale a -1, poi riproporrei questo ragionamento per abbassare l'equazione di un altro grado e quindi trovare x2, e così via finché l'equazione è scomposta e ho i 5 valori di x(x1, x2, x3, x4, x5), chiaro ora il mio obiettivo??

    Comunque mi dà questo errore di compilazione: Tipo non corrispondente per l'argomento ByRef (e mi evidenzia "i")

    p.s. grazie per aver chiuso l'altra discussione!



  • di Vecchio Frac data: 09/01/2015 21:54:44

    Eh può essere, non avevo provato.
    Scusami, correggi così nella firma della Function:
    ByVal x As Single
    Comunque se trova uno zero te lo mette in A1 che è Cells(1,1) appunto.
    E a me non ha trovato zeri nemmeno dopo un milione di cicli^_^






  • di Vecchio Frac data: 09/01/2015 21:56:20

    Spiegazione dell'errore: avevo dichiarato i come intero lungo ma poi l'ho passato alla funzione che si aspettava un tipo in precisione singola (con decimali) e quindi si è arrabbiato... allora noi gli diciamo di prendere il valore per quello che è, fregandosene del tipo.
    In soldoni :)





  • di frank (utente non iscritto) data: 09/01/2015 22:24:44

    10+ nella tua spiegazione Vecchio Frac..thanks
    per quanto riguarda il valore di x è -1 ecco perché non ce lo trovava ahah comunque il ciclo dovrebbe essere impostato considerando in ordine i valori di x come x=0, poi x=+/-1, x=+/-2, x=+/-3 e così via. quindi penso che il ciclo vada cambiato giusto? (e anche For i= -10 To 10)



  • di Vecchio Frac data: 09/01/2015 22:34:32

    Penso di sì... non ti resta che provare :)





  • di frank (utente non iscritto) data: 09/01/2015 22:57:22

    emhh... un ultimo aiutino su come impostarlo?



  • di Vecchio Frac data: 09/01/2015 23:05:46

    Non è chiaro ormai?
    Per x che va da -1000 e + 1000:
    For i = -1000# To 1000#

    e fai anche questa modifica:
    If y = 0 Then
    Cells(1, 1) = "y vale zero per x = " & i
    MsgBox "Ho trovato uno zero"

    così l'output in cella è più chiaro.





  • di frank (utente non iscritto) data: 09/01/2015 23:19:01

    no, ma così facendo esce un risultato sbagliato perché dovrebbe iniziare dallo 0 e non da -1000, perché in questo caso mi dà -2 invece di -1....
    In pratica il ciclo dovrebbe essere che considera prima i=0, poi i=+1 Or -1, i=+2 Or -2, e così via dicendo..



  • di frank (utente non iscritto) data: 09/01/2015 23:21:17

    ok...non avevo messo #, ed ora il problema si è risolto....scusa se ti ho fatto esaurire



  • di frank (utente non iscritto) data: 10/01/2015 00:51:23

    nonostante tutto il codice mi risulta ancora sbagliato vedete qualche errore ??? penso sia nel ciclo...

    Date giusto un occhiata ai cicli e alle funzioni, il resto tralasciatelo, almeno per quello posso garantire io...
     
    Function f_x(ByVal x As Single, a As Single, b As Single, c As Single, d As Single, e As Single) As Single
        f_x = a * x ^ 4 + b * x ^ 3 + c * x ^ 2 + d * x + e
    End Function
    
    Function f_v(ByVal v As Single, ByVal b1 As Single, ByVal c1 As Single, ByVal d1 As Single, ByVal e1 As Single) As Single
        f_v = b1 * v ^ 3 + c1 * v ^ 2 + d1 * v + e1
    End Function
    
    Function f_w(ByVal w As Single, ByVal c2 As Single, ByVal d2 As Single, ByVal e2 As Single) As Single
        f_w = c2 * w ^ 2 + d2 * w + e2
    End Function
    
    Sub Progetto_scomposizione()
    Dim y As Single, d3 As Single, e3 As Single
    
        b1 = a
        c1 = b + x
        d1 = c + (c1 * x)
        e1 = d + (d1 * x)
        
        c2 = b1
        d2 = c1 + v
        e2 = d1 + (d2 * v)
        
        d3 = c2
        e3 = d2 + w
        
        
        For x = -10# To 10#
             y = f_x(x, 1, 5, 5, -5, -6) ' assegna a y il valore della function definita sopra
             If y = 0 Then Exit For ' se y è zero esce dal ciclo
        Next
        
        For v = -10# To 10#
            y = f_v(v, b1, c1, d1, e1)
            If y = 0 Then Exit For
        Next
        
            For w = -10# To 10#
             y = f_w(w, c2, d2, e2)
             If y = 0 Then Exit For
        Next
       
        Cells(1, 1) = "x°1"
        Cells(2, 1) = x
        Cells(3, 1) = "x°2"
        Cells(4, 1) = v
        Cells(5, 1) = "x°3"
        Cells(6, 1) = w
        Cells(7, 1) = "x°4"
        Cells(8, 1) = (e3 / d3)
        
    End Sub
    



  • di Vecchio Frac data: 10/01/2015 08:56:09

    Il problema non è certo nel cancelletto (#) che è solo un suffisso che indica il tipo di dato Long.
    E per una volta che non metto io Option Explicit in testa al modulo, era il caso di metterlo.
    Così avresti avuto informazione che ci sono variabili non dichiarate... cosa che in VBA va fatta prima di usarle esplicitamente per evitare valori strani.
    Nella sub per esempio, tu assegni a c1 il valore di b + x ma questa assegnazione va fatta quando serve: non è che basta dirlo una volta sola e il compilatore indovina che deve farlo ogni volta che trova la x :)
    E poi devi comunque mostrare i valori trovati appena li scovi... ma sarà giusto testare il valore di y = 0? io questo non lo so.

    Comunque torniamo al quesito iniziale... sostituire tutte le variabili con un array.
    Certo si dovrebbe fare ma solo per ottimizzare il codice, non per la logica del problema.
     
    Option Explicit
    
    Function f_x(ByVal x As Single, a As Single, b As Single, c As Single, d As Single, e As Single) As Single
        f_x = a * x ^ 4 + b * x ^ 3 + c * x ^ 2 + d * x + e
    End Function
    
    Function f_v(ByVal v As Single, ByVal b1 As Single, ByVal c1 As Single, ByVal d1 As Single, ByVal e1 As Single) As Single
        f_v = b1 * v ^ 3 + c1 * v ^ 2 + d1 * v + e1
    End Function
    
    Function f_w(ByVal w As Single, ByVal c2 As Single, ByVal d2 As Single, ByVal e2 As Single) As Single
        f_w = c2 * w ^ 2 + d2 * w + e2
    End Function
    
    Sub Progetto_scomposizione()
    Dim a As Single, b As Single, c As Single, d As Single, e As Single
    Dim y As Single, x As Single, w As Single, v As Single, z As Single
    Dim b1 As Single, c1 As Single, d1 As Single, e1 As Single
    Dim c2 As Single, d2 As Single, e2 As Single
    Dim d3 As Single, e3 As Single
    
        a = 1
        b = 5
        c = 5
        d = -5
        e = -6
        
        For x = -10 To 10
             y = f_x(x, a, b, c, d, e) ' assegna a y il valore della function definita sopra
             If y = 0 Then Call mostra_soluzioni(x, v, w, e3, d3): Exit Sub
        
             b1 = a
             c1 = b + x
             d1 = c + (c1 * x)
             e1 = d + (d1 * x)
          
            For v = -10 To 10
                 y = f_v(z, b1, c1, d1, e1)
                 If y = 0 Then Call mostra_soluzioni(x, v, w, e3, d3): Exit Sub
    
                 c2 = b1
                 d2 = c1 + v
                 e2 = d1 + (d2 * v)
    
                 For w = -10 To 10
                     y = f_w(w, c2, d2, e2)
                     d3 = c2
                     e3 = d2 + w
                     If y = 0 Then Call mostra_soluzioni(x, v, w, e3, d3): Exit Sub
                 Next w
            Next v
        Next x
    
    End Sub
       
    Private Sub mostra_soluzioni(x, v, w, e3, d3)
        Cells(1, 1) = "x°1"
        Cells(2, 1) = x
        Cells(3, 1) = "x°2"
        Cells(4, 1) = v
        Cells(5, 1) = "x°3"
        Cells(6, 1) = w
        Cells(7, 1) = "x°4"
        Cells(8, 1) = (e3 / d3)
    End Sub
    






  • di frank (utente non iscritto) data: 10/01/2015 10:50:08

    ok, tutto chiaro fino ad ora... per quanto riguarda il test di quando il valore di y è 0 è inevitabile, perché trovare il valore di x significa trovare quel numero che sostituito alla x, annulla tutti i coefficienti(e quindi y=..... risulta uguale a 0), e dato che ho un termine noto(valore non moltiplicato per x) che è "e", il valore di x non potrà essere 0. Cosa sicura è che non ci sta facendo ciò che vogliamo fargli fare : ....si può impostare un tipo di ciclo con Do while loop che consideri prima x=0 e +-1 +-2 +-3 ecc?

    Per l'array se la metto nel progettino sarebbe ancora meglio!



  • di lepat (utente non iscritto) data: 10/01/2015 12:42:48

    le soluzioni devono essere sicuramente numeri interi ?



  • di frank (utente non iscritto) data: 10/01/2015 12:56:17

    sisi, ci si può arrivare facilmente, se all'equazione x^4+5x^3+5x^2-5x-6 metti il valore di x=-1, y è uguale a 0, poi in base alla scomposizione, viene fuori l'equazione x^3+4x^2+x-6, il secondo valore è x=1(che nel codice chiamo "v"), quindi viene fuori l'equazione x^2+5x+6 con valore di x=-2 e infine rimane x+3=0, quindi il quarto ed ultimo valore di x=3...



  • di Vecchio Frac data: 10/01/2015 14:03:13

    Allora guarda, mi sono preso un po' di tempo e ho messo in piedi un piccolo modello.
    Perfezionabile, ma è per capire se siamo sulla strada giusta.
    Inserisci i valori nella zona arancione, poi Alt-F8 per eseguire la macro.
    Istruzioni nel foglio :)

    Allego file: "ruffini by vfrac 1.xlsm"





  • di Vecchio Frac data: 10/01/2015 14:04:20

    By the way, per il tuo problema di risolvere l'esercizio con l'array si fa abbastanza presto.





  • di Vecchio Frac data: 10/01/2015 14:27:37

    Ho fatto girare il modello con valori diversi: ecco subito un errata corrige nella sub mostra_soluzioni perchè ci sono casi di divisione per zero.
    Sostituisci quella sub con questa qui sotto (non farai fatica a trovare il punto della modifica):
     
    Private Sub mostra_soluzioni(x, v, w, e3, d3)
        Cells(riga, "E") = "x°1 = "
        Cells(riga, "F") = x
        Cells(riga + 1, "E") = "x°2 ="
        Cells(riga + 1, "F") = v
        Cells(riga + 2, "E") = "x°3 ="
        Cells(riga + 2, "F") = w
        Cells(riga + 3, "E") = "x°4 ="
        If d3 > 0 Then
            Cells(riga + 3, "F") = (e3 / d3)
        Else
            Cells(riga + 3, "F") = "Divisione per zero"
        End If
        
        riga = riga + 5
        Cells(1, "E").Select
    End Sub






  • di Vecchio Frac data: 10/01/2015 14:34:41

    Ho riallegato il file corretto perchè ho sistemato altre sbavature estetiche :)





  • di frank (utente non iscritto) data: 10/01/2015 14:56:39

    Perfect, l'arcano è stato risolto, grazie mille!!